aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--MAINTAINERS9
-rw-r--r--arch/tile/Kconfig31
-rw-r--r--arch/tile/Kconfig.debug14
-rw-r--r--arch/tile/Makefile4
-rw-r--r--arch/tile/configs/tilegx_defconfig241
-rw-r--r--arch/tile/configs/tilepro_defconfig87
-rw-r--r--arch/tile/gxio/Kconfig5
-rw-r--r--arch/tile/gxio/Makefile1
-rw-r--r--arch/tile/gxio/iorpc_trio.c23
-rw-r--r--arch/tile/gxio/iorpc_uart.c77
-rw-r--r--arch/tile/gxio/uart.c87
-rw-r--r--arch/tile/include/arch/trio.h39
-rw-r--r--arch/tile/include/arch/uart.h300
-rw-r--r--arch/tile/include/arch/uart_def.h120
-rw-r--r--arch/tile/include/asm/Kbuild3
-rw-r--r--arch/tile/include/asm/atomic.h52
-rw-r--r--arch/tile/include/asm/atomic_32.h102
-rw-r--r--arch/tile/include/asm/atomic_64.h42
-rw-r--r--arch/tile/include/asm/barrier.h4
-rw-r--r--arch/tile/include/asm/bitops.h41
-rw-r--r--arch/tile/include/asm/bitops_32.h2
-rw-r--r--arch/tile/include/asm/bitops_64.h8
-rw-r--r--arch/tile/include/asm/cache.h13
-rw-r--r--arch/tile/include/asm/cacheflush.h44
-rw-r--r--arch/tile/include/asm/cmpxchg.h93
-rw-r--r--arch/tile/include/asm/device.h5
-rw-r--r--arch/tile/include/asm/dma-mapping.h27
-rw-r--r--arch/tile/include/asm/elf.h10
-rw-r--r--arch/tile/include/asm/fixmap.h8
-rw-r--r--arch/tile/include/asm/ftrace.h22
-rw-r--r--arch/tile/include/asm/futex.h1
-rw-r--r--arch/tile/include/asm/homecache.h11
-rw-r--r--arch/tile/include/asm/io.h132
-rw-r--r--arch/tile/include/asm/irqflags.h21
-rw-r--r--arch/tile/include/asm/kdebug.h (renamed from arch/tile/include/asm/hw_irq.h)18
-rw-r--r--arch/tile/include/asm/kgdb.h71
-rw-r--r--arch/tile/include/asm/kprobes.h79
-rw-r--r--arch/tile/include/asm/mmu.h1
-rw-r--r--arch/tile/include/asm/mmu_context.h2
-rw-r--r--arch/tile/include/asm/mmzone.h2
-rw-r--r--arch/tile/include/asm/page.h61
-rw-r--r--arch/tile/include/asm/pci.h22
-rw-r--r--arch/tile/include/asm/pgtable_32.h4
-rw-r--r--arch/tile/include/asm/pgtable_64.h27
-rw-r--r--arch/tile/include/asm/processor.h84
-rw-r--r--arch/tile/include/asm/ptrace.h6
-rw-r--r--arch/tile/include/asm/sections.h8
-rw-r--r--arch/tile/include/asm/setup.h3
-rw-r--r--arch/tile/include/asm/smp.h2
-rw-r--r--arch/tile/include/asm/spinlock_64.h4
-rw-r--r--arch/tile/include/asm/string.h2
-rw-r--r--arch/tile/include/asm/thread_info.h6
-rw-r--r--arch/tile/include/asm/traps.h13
-rw-r--r--arch/tile/include/asm/uaccess.h37
-rw-r--r--arch/tile/include/asm/unaligned.h14
-rw-r--r--arch/tile/include/asm/vdso.h49
-rw-r--r--arch/tile/include/gxio/iorpc_trio.h5
-rw-r--r--arch/tile/include/gxio/iorpc_uart.h40
-rw-r--r--arch/tile/include/gxio/uart.h105
-rw-r--r--arch/tile/include/hv/drv_trio_intf.h8
-rw-r--r--arch/tile/include/hv/drv_uart_intf.h33
-rw-r--r--arch/tile/include/hv/hypervisor.h61
-rw-r--r--arch/tile/include/uapi/arch/Kbuild1
-rw-r--r--arch/tile/include/uapi/arch/chip.h4
-rw-r--r--arch/tile/include/uapi/arch/chip_tile64.h258
-rw-r--r--arch/tile/include/uapi/arch/opcode_tilegx.h1
-rw-r--r--arch/tile/include/uapi/arch/opcode_tilepro.h1
-rw-r--r--arch/tile/include/uapi/arch/spr_def_32.h2
-rw-r--r--arch/tile/include/uapi/asm/auxvec.h3
-rw-r--r--arch/tile/include/uapi/asm/cachectl.h4
-rw-r--r--arch/tile/kernel/Makefile16
-rw-r--r--arch/tile/kernel/asm-offsets.c52
-rw-r--r--arch/tile/kernel/compat_signal.c3
-rw-r--r--arch/tile/kernel/early_printk.c47
-rw-r--r--arch/tile/kernel/entry.S16
-rw-r--r--arch/tile/kernel/ftrace.c246
-rw-r--r--arch/tile/kernel/hardwall.c28
-rw-r--r--arch/tile/kernel/head_32.S17
-rw-r--r--arch/tile/kernel/head_64.S46
-rw-r--r--arch/tile/kernel/hvglue.S74
-rw-r--r--arch/tile/kernel/hvglue.lds59
-rw-r--r--arch/tile/kernel/hvglue_trace.c266
-rw-r--r--arch/tile/kernel/intvec_32.S114
-rw-r--r--arch/tile/kernel/intvec_64.S305
-rw-r--r--arch/tile/kernel/irq.c8
-rw-r--r--arch/tile/kernel/kgdb.c499
-rw-r--r--arch/tile/kernel/kprobes.c528
-rw-r--r--arch/tile/kernel/mcount_64.S224
-rw-r--r--arch/tile/kernel/pci-dma.c74
-rw-r--r--arch/tile/kernel/pci.c33
-rw-r--r--arch/tile/kernel/pci_gx.c727
-rw-r--r--arch/tile/kernel/proc.c2
-rw-r--r--arch/tile/kernel/process.c116
-rw-r--r--arch/tile/kernel/ptrace.c19
-rw-r--r--arch/tile/kernel/reboot.c2
-rw-r--r--arch/tile/kernel/regs_32.S4
-rw-r--r--arch/tile/kernel/regs_64.S4
-rw-r--r--arch/tile/kernel/relocate_kernel_32.S27
-rw-r--r--arch/tile/kernel/relocate_kernel_64.S11
-rw-r--r--arch/tile/kernel/setup.c162
-rw-r--r--arch/tile/kernel/signal.c3
-rw-r--r--arch/tile/kernel/single_step.c118
-rw-r--r--arch/tile/kernel/smp.c22
-rw-r--r--arch/tile/kernel/smpboot.c8
-rw-r--r--arch/tile/kernel/stack.c51
-rw-r--r--arch/tile/kernel/sys.c4
-rw-r--r--arch/tile/kernel/sysfs.c76
-rw-r--r--arch/tile/kernel/time.c37
-rw-r--r--arch/tile/kernel/tlb.c8
-rw-r--r--arch/tile/kernel/traps.c89
-rw-r--r--arch/tile/kernel/unaligned.c1609
-rw-r--r--arch/tile/kernel/vdso.c212
-rw-r--r--arch/tile/kernel/vdso/Makefile118
-rw-r--r--arch/tile/kernel/vdso/vdso.S28
-rw-r--r--arch/tile/kernel/vdso/vdso.lds.S87
-rw-r--r--arch/tile/kernel/vdso/vdso32.S28
-rw-r--r--arch/tile/kernel/vdso/vgettimeofday.c107
-rw-r--r--arch/tile/kernel/vdso/vrt_sigreturn.S30
-rw-r--r--arch/tile/kernel/vmlinux.lds.S31
-rw-r--r--arch/tile/lib/Makefile16
-rw-r--r--arch/tile/lib/atomic_32.c133
-rw-r--r--arch/tile/lib/atomic_asm_32.S1
-rw-r--r--arch/tile/lib/cacheflush.c16
-rw-r--r--arch/tile/lib/exports.c7
-rw-r--r--arch/tile/lib/memchr_64.c2
-rw-r--r--arch/tile/lib/memcpy_32.S63
-rw-r--r--arch/tile/lib/memcpy_64.c264
-rw-r--r--arch/tile/lib/memcpy_tile64.c276
-rw-r--r--arch/tile/lib/memcpy_user_64.c2
-rw-r--r--arch/tile/lib/memset_32.c110
-rw-r--r--arch/tile/lib/memset_64.c9
-rw-r--r--arch/tile/lib/strchr_32.c2
-rw-r--r--arch/tile/lib/strchr_64.c2
-rw-r--r--arch/tile/lib/string-endian.h13
-rw-r--r--arch/tile/lib/strlen_32.c2
-rw-r--r--arch/tile/lib/strnlen_32.c47
-rw-r--r--arch/tile/lib/strnlen_64.c48
-rw-r--r--arch/tile/lib/usercopy_32.S36
-rw-r--r--arch/tile/lib/usercopy_64.S36
-rw-r--r--arch/tile/mm/elf.c99
-rw-r--r--arch/tile/mm/fault.c135
-rw-r--r--arch/tile/mm/highmem.c2
-rw-r--r--arch/tile/mm/homecache.c39
-rw-r--r--arch/tile/mm/hugetlbpage.c38
-rw-r--r--arch/tile/mm/init.c96
-rw-r--r--arch/tile/mm/migrate_32.S4
-rw-r--r--arch/tile/mm/migrate_64.S4
-rw-r--r--arch/tile/mm/mmap.c24
-rw-r--r--arch/tile/mm/pgtable.c76
-rw-r--r--drivers/edac/tile_edac.c1
-rw-r--r--drivers/tty/hvc/hvc_tile.c149
-rw-r--r--drivers/tty/serial/Kconfig9
-rw-r--r--drivers/tty/serial/Makefile1
-rw-r--r--drivers/tty/serial/tilegx.c708
-rw-r--r--include/uapi/linux/serial_core.h3
-rw-r--r--samples/kprobes/kprobe_example.c9
-rwxr-xr-xscripts/recordmcount.pl4
157 files changed, 8708 insertions, 2893 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index caa7c3a1fef9..6bc2d87b042f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8373,9 +8373,14 @@ M: Chris Metcalf <cmetcalf@tilera.com>
8373W: http://www.tilera.com/scm/ 8373W: http://www.tilera.com/scm/
8374S: Supported 8374S: Supported
8375F: arch/tile/ 8375F: arch/tile/
8376F: drivers/tty/hvc/hvc_tile.c 8376F: drivers/char/tile-srom.c
8377F: drivers/net/ethernet/tile/
8378F: drivers/edac/tile_edac.c 8377F: drivers/edac/tile_edac.c
8378F: drivers/net/ethernet/tile/
8379F: drivers/rtc/rtc-tile.c
8380F: drivers/tty/hvc/hvc_tile.c
8381F: drivers/tty/serial/tilegx.c
8382F: drivers/usb/host/*-tilegx.c
8383F: include/linux/usb/tilegx.h
8379 8384
8380TLAN NETWORK DRIVER 8385TLAN NETWORK DRIVER
8381M: Samuel Chessman <chessman@tux.org> 8386M: Samuel Chessman <chessman@tux.org>
diff --git a/arch/tile/Kconfig b/arch/tile/Kconfig
index 24565a7ffe6d..6e1ed55f6cfc 100644
--- a/arch/tile/Kconfig
+++ b/arch/tile/Kconfig
@@ -26,6 +26,7 @@ config TILE
26 select HAVE_SYSCALL_TRACEPOINTS 26 select HAVE_SYSCALL_TRACEPOINTS
27 select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE 27 select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
28 select HAVE_DEBUG_STACKOVERFLOW 28 select HAVE_DEBUG_STACKOVERFLOW
29 select ARCH_WANT_FRAME_POINTERS
29 30
30# FIXME: investigate whether we need/want these options. 31# FIXME: investigate whether we need/want these options.
31# select HAVE_IOREMAP_PROT 32# select HAVE_IOREMAP_PROT
@@ -64,6 +65,9 @@ config HUGETLB_SUPER_PAGES
64 depends on HUGETLB_PAGE && TILEGX 65 depends on HUGETLB_PAGE && TILEGX
65 def_bool y 66 def_bool y
66 67
68config GENERIC_TIME_VSYSCALL
69 def_bool y
70
67# FIXME: tilegx can implement a more efficient rwsem. 71# FIXME: tilegx can implement a more efficient rwsem.
68config RWSEM_GENERIC_SPINLOCK 72config RWSEM_GENERIC_SPINLOCK
69 def_bool y 73 def_bool y
@@ -112,10 +116,19 @@ config SMP
112config HVC_TILE 116config HVC_TILE
113 depends on TTY 117 depends on TTY
114 select HVC_DRIVER 118 select HVC_DRIVER
119 select HVC_IRQ if TILEGX
115 def_bool y 120 def_bool y
116 121
117config TILEGX 122config TILEGX
118 bool "Building with TILE-Gx (64-bit) compiler and toolchain" 123 bool "Building for TILE-Gx (64-bit) processor"
124 select HAVE_FUNCTION_TRACER
125 select HAVE_FUNCTION_TRACE_MCOUNT_TEST
126 select HAVE_FUNCTION_GRAPH_TRACER
127 select HAVE_DYNAMIC_FTRACE
128 select HAVE_FTRACE_MCOUNT_RECORD
129 select HAVE_KPROBES
130 select HAVE_KRETPROBES
131 select HAVE_ARCH_KGDB
119 132
120config TILEPRO 133config TILEPRO
121 def_bool !TILEGX 134 def_bool !TILEGX
@@ -194,7 +207,7 @@ config SYSVIPC_COMPAT
194 def_bool y 207 def_bool y
195 depends on COMPAT && SYSVIPC 208 depends on COMPAT && SYSVIPC
196 209
197# We do not currently support disabling HIGHMEM on tile64 and tilepro. 210# We do not currently support disabling HIGHMEM on tilepro.
198config HIGHMEM 211config HIGHMEM
199 bool # "Support for more than 512 MB of RAM" 212 bool # "Support for more than 512 MB of RAM"
200 default !TILEGX 213 default !TILEGX
@@ -300,6 +313,8 @@ config PAGE_OFFSET
300 313
301source "mm/Kconfig" 314source "mm/Kconfig"
302 315
316source "kernel/Kconfig.preempt"
317
303config CMDLINE_BOOL 318config CMDLINE_BOOL
304 bool "Built-in kernel command line" 319 bool "Built-in kernel command line"
305 default n 320 default n
@@ -396,8 +411,20 @@ config NO_IOMEM
396config NO_IOPORT 411config NO_IOPORT
397 def_bool !PCI 412 def_bool !PCI
398 413
414config TILE_PCI_IO
415 bool "PCI I/O space support"
416 default n
417 depends on PCI
418 depends on TILEGX
419 ---help---
420 Enable PCI I/O space support on TILEGx. Since the PCI I/O space
421 is used by few modern PCIe endpoint devices, its support is disabled
422 by default to save the TRIO PIO Region resource for other purposes.
423
399source "drivers/pci/Kconfig" 424source "drivers/pci/Kconfig"
400 425
426source "drivers/pci/pcie/Kconfig"
427
401config TILE_USB 428config TILE_USB
402 tristate "Tilera USB host adapter support" 429 tristate "Tilera USB host adapter support"
403 default y 430 default y
diff --git a/arch/tile/Kconfig.debug b/arch/tile/Kconfig.debug
index 9165ea979e85..19734d3ab1e8 100644
--- a/arch/tile/Kconfig.debug
+++ b/arch/tile/Kconfig.debug
@@ -14,14 +14,12 @@ config EARLY_PRINTK
14 with klogd/syslogd. You should normally N here, 14 with klogd/syslogd. You should normally N here,
15 unless you want to debug such a crash. 15 unless you want to debug such a crash.
16 16
17config DEBUG_EXTRA_FLAGS 17config TILE_HVGLUE_TRACE
18 string "Additional compiler arguments when building with '-g'" 18 bool "Provide wrapper functions for hypervisor ABI calls"
19 depends on DEBUG_INFO 19 default n
20 default ""
21 help 20 help
22 Debug info can be large, and flags like 21 Provide wrapper functions for the hypervisor ABI calls
23 `-femit-struct-debug-baseonly' can reduce the kernel file 22 defined in arch/tile/kernel/hvglue.S. This allows tracing
24 size and build time noticeably. Such flags are often 23 mechanisms, etc., to have visibility into those calls.
25 helpful if the main use of debug info is line number info.
26 24
27endmenu 25endmenu
diff --git a/arch/tile/Makefile b/arch/tile/Makefile
index 3d15364c6071..4dc380a519d4 100644
--- a/arch/tile/Makefile
+++ b/arch/tile/Makefile
@@ -30,10 +30,6 @@ endif
30# In kernel modules, this causes load failures due to unsupported relocations. 30# In kernel modules, this causes load failures due to unsupported relocations.
31KBUILD_CFLAGS += -fno-asynchronous-unwind-tables 31KBUILD_CFLAGS += -fno-asynchronous-unwind-tables
32 32
33ifneq ($(CONFIG_DEBUG_EXTRA_FLAGS),"")
34KBUILD_CFLAGS += $(CONFIG_DEBUG_EXTRA_FLAGS)
35endif
36
37LIBGCC_PATH := \ 33LIBGCC_PATH := \
38 $(shell $(CC) $(KBUILD_CFLAGS) $(KCFLAGS) -print-libgcc-file-name) 34 $(shell $(CC) $(KBUILD_CFLAGS) $(KCFLAGS) -print-libgcc-file-name)
39 35
diff --git a/arch/tile/configs/tilegx_defconfig b/arch/tile/configs/tilegx_defconfig
index 47684815e5c8..730e40d9cf62 100644
--- a/arch/tile/configs/tilegx_defconfig
+++ b/arch/tile/configs/tilegx_defconfig
@@ -1,16 +1,15 @@
1CONFIG_TILEGX=y 1CONFIG_TILEGX=y
2CONFIG_EXPERIMENTAL=y
3# CONFIG_LOCALVERSION_AUTO is not set
4CONFIG_SYSVIPC=y 2CONFIG_SYSVIPC=y
5CONFIG_POSIX_MQUEUE=y 3CONFIG_POSIX_MQUEUE=y
4CONFIG_FHANDLE=y
5CONFIG_AUDIT=y
6CONFIG_NO_HZ=y
6CONFIG_BSD_PROCESS_ACCT=y 7CONFIG_BSD_PROCESS_ACCT=y
7CONFIG_BSD_PROCESS_ACCT_V3=y 8CONFIG_BSD_PROCESS_ACCT_V3=y
8CONFIG_FHANDLE=y
9CONFIG_TASKSTATS=y 9CONFIG_TASKSTATS=y
10CONFIG_TASK_DELAY_ACCT=y 10CONFIG_TASK_DELAY_ACCT=y
11CONFIG_TASK_XACCT=y 11CONFIG_TASK_XACCT=y
12CONFIG_TASK_IO_ACCOUNTING=y 12CONFIG_TASK_IO_ACCOUNTING=y
13CONFIG_AUDIT=y
14CONFIG_LOG_BUF_SHIFT=19 13CONFIG_LOG_BUF_SHIFT=19
15CONFIG_CGROUPS=y 14CONFIG_CGROUPS=y
16CONFIG_CGROUP_DEBUG=y 15CONFIG_CGROUP_DEBUG=y
@@ -18,18 +17,18 @@ CONFIG_CGROUP_DEVICE=y
18CONFIG_CPUSETS=y 17CONFIG_CPUSETS=y
19CONFIG_CGROUP_CPUACCT=y 18CONFIG_CGROUP_CPUACCT=y
20CONFIG_RESOURCE_COUNTERS=y 19CONFIG_RESOURCE_COUNTERS=y
21CONFIG_CGROUP_MEMCG=y
22CONFIG_CGROUP_MEMCG_SWAP=y
23CONFIG_CGROUP_SCHED=y 20CONFIG_CGROUP_SCHED=y
24CONFIG_RT_GROUP_SCHED=y 21CONFIG_RT_GROUP_SCHED=y
25CONFIG_BLK_CGROUP=y 22CONFIG_BLK_CGROUP=y
26CONFIG_NAMESPACES=y 23CONFIG_NAMESPACES=y
27CONFIG_RELAY=y 24CONFIG_RELAY=y
28CONFIG_BLK_DEV_INITRD=y 25CONFIG_BLK_DEV_INITRD=y
26CONFIG_RD_XZ=y
29CONFIG_SYSCTL_SYSCALL=y 27CONFIG_SYSCTL_SYSCALL=y
30CONFIG_EMBEDDED=y 28CONFIG_EMBEDDED=y
31# CONFIG_COMPAT_BRK is not set 29# CONFIG_COMPAT_BRK is not set
32CONFIG_PROFILING=y 30CONFIG_PROFILING=y
31CONFIG_KPROBES=y
33CONFIG_MODULES=y 32CONFIG_MODULES=y
34CONFIG_MODULE_FORCE_LOAD=y 33CONFIG_MODULE_FORCE_LOAD=y
35CONFIG_MODULE_UNLOAD=y 34CONFIG_MODULE_UNLOAD=y
@@ -45,12 +44,12 @@ CONFIG_UNIXWARE_DISKLABEL=y
45CONFIG_SGI_PARTITION=y 44CONFIG_SGI_PARTITION=y
46CONFIG_SUN_PARTITION=y 45CONFIG_SUN_PARTITION=y
47CONFIG_KARMA_PARTITION=y 46CONFIG_KARMA_PARTITION=y
48CONFIG_EFI_PARTITION=y
49CONFIG_CFQ_GROUP_IOSCHED=y 47CONFIG_CFQ_GROUP_IOSCHED=y
50CONFIG_NR_CPUS=100 48CONFIG_NR_CPUS=100
51CONFIG_NO_HZ=y
52CONFIG_HIGH_RES_TIMERS=y
53CONFIG_HZ_100=y 49CONFIG_HZ_100=y
50# CONFIG_COMPACTION is not set
51CONFIG_PREEMPT_VOLUNTARY=y
52CONFIG_TILE_PCI_IO=y
54CONFIG_PCI_DEBUG=y 53CONFIG_PCI_DEBUG=y
55# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set 54# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
56CONFIG_BINFMT_MISC=y 55CONFIG_BINFMT_MISC=y
@@ -108,150 +107,9 @@ CONFIG_IPV6_MULTIPLE_TABLES=y
108CONFIG_IPV6_MROUTE=y 107CONFIG_IPV6_MROUTE=y
109CONFIG_IPV6_PIMSM_V2=y 108CONFIG_IPV6_PIMSM_V2=y
110CONFIG_NETLABEL=y 109CONFIG_NETLABEL=y
111CONFIG_NETFILTER=y
112CONFIG_NF_CONNTRACK=m
113CONFIG_NF_CONNTRACK_SECMARK=y
114CONFIG_NF_CONNTRACK_ZONES=y
115CONFIG_NF_CONNTRACK_EVENTS=y
116CONFIG_NF_CT_PROTO_DCCP=m
117CONFIG_NF_CT_PROTO_UDPLITE=m
118CONFIG_NF_CONNTRACK_AMANDA=m
119CONFIG_NF_CONNTRACK_FTP=m
120CONFIG_NF_CONNTRACK_H323=m
121CONFIG_NF_CONNTRACK_IRC=m
122CONFIG_NF_CONNTRACK_NETBIOS_NS=m
123CONFIG_NF_CONNTRACK_PPTP=m
124CONFIG_NF_CONNTRACK_SANE=m
125CONFIG_NF_CONNTRACK_SIP=m
126CONFIG_NF_CONNTRACK_TFTP=m
127CONFIG_NETFILTER_TPROXY=m
128CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
129CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
130CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
131CONFIG_NETFILTER_XT_TARGET_CT=m
132CONFIG_NETFILTER_XT_TARGET_DSCP=m
133CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m
134CONFIG_NETFILTER_XT_TARGET_MARK=m
135CONFIG_NETFILTER_XT_TARGET_NFLOG=m
136CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
137CONFIG_NETFILTER_XT_TARGET_TEE=m
138CONFIG_NETFILTER_XT_TARGET_TPROXY=m
139CONFIG_NETFILTER_XT_TARGET_TRACE=m
140CONFIG_NETFILTER_XT_TARGET_SECMARK=m
141CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
142CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
143CONFIG_NETFILTER_XT_MATCH_CLUSTER=m
144CONFIG_NETFILTER_XT_MATCH_COMMENT=m
145CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
146CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
147CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
148CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
149CONFIG_NETFILTER_XT_MATCH_DCCP=m
150CONFIG_NETFILTER_XT_MATCH_DSCP=m
151CONFIG_NETFILTER_XT_MATCH_ESP=m
152CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
153CONFIG_NETFILTER_XT_MATCH_HELPER=m
154CONFIG_NETFILTER_XT_MATCH_IPRANGE=m
155CONFIG_NETFILTER_XT_MATCH_IPVS=m
156CONFIG_NETFILTER_XT_MATCH_LENGTH=m
157CONFIG_NETFILTER_XT_MATCH_LIMIT=m
158CONFIG_NETFILTER_XT_MATCH_MAC=m
159CONFIG_NETFILTER_XT_MATCH_MARK=m
160CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
161CONFIG_NETFILTER_XT_MATCH_OSF=m
162CONFIG_NETFILTER_XT_MATCH_OWNER=m
163CONFIG_NETFILTER_XT_MATCH_POLICY=m
164CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m
165CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
166CONFIG_NETFILTER_XT_MATCH_QUOTA=m
167CONFIG_NETFILTER_XT_MATCH_RATEEST=m
168CONFIG_NETFILTER_XT_MATCH_REALM=m
169CONFIG_NETFILTER_XT_MATCH_RECENT=m
170CONFIG_NETFILTER_XT_MATCH_SOCKET=m
171CONFIG_NETFILTER_XT_MATCH_STATE=m
172CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
173CONFIG_NETFILTER_XT_MATCH_STRING=m
174CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
175CONFIG_NETFILTER_XT_MATCH_TIME=m
176CONFIG_NETFILTER_XT_MATCH_U32=m
177CONFIG_IP_VS=m
178CONFIG_IP_VS_IPV6=y
179CONFIG_IP_VS_PROTO_TCP=y
180CONFIG_IP_VS_PROTO_UDP=y
181CONFIG_IP_VS_PROTO_ESP=y
182CONFIG_IP_VS_PROTO_AH=y
183CONFIG_IP_VS_PROTO_SCTP=y
184CONFIG_IP_VS_RR=m
185CONFIG_IP_VS_WRR=m
186CONFIG_IP_VS_LC=m
187CONFIG_IP_VS_WLC=m
188CONFIG_IP_VS_LBLC=m
189CONFIG_IP_VS_LBLCR=m
190CONFIG_IP_VS_SED=m
191CONFIG_IP_VS_NQ=m
192CONFIG_NF_CONNTRACK_IPV4=m
193# CONFIG_NF_CONNTRACK_PROC_COMPAT is not set
194CONFIG_IP_NF_QUEUE=m
195CONFIG_IP_NF_IPTABLES=y
196CONFIG_IP_NF_MATCH_AH=m
197CONFIG_IP_NF_MATCH_ECN=m
198CONFIG_IP_NF_MATCH_TTL=m
199CONFIG_IP_NF_FILTER=y
200CONFIG_IP_NF_TARGET_REJECT=y
201CONFIG_IP_NF_TARGET_LOG=m
202CONFIG_IP_NF_TARGET_ULOG=m
203CONFIG_IP_NF_MANGLE=m
204CONFIG_IP_NF_TARGET_ECN=m
205CONFIG_IP_NF_TARGET_TTL=m
206CONFIG_IP_NF_RAW=m
207CONFIG_IP_NF_SECURITY=m
208CONFIG_IP_NF_ARPTABLES=m
209CONFIG_IP_NF_ARPFILTER=m
210CONFIG_IP_NF_ARP_MANGLE=m
211CONFIG_NF_CONNTRACK_IPV6=m
212CONFIG_IP6_NF_QUEUE=m
213CONFIG_IP6_NF_IPTABLES=m
214CONFIG_IP6_NF_MATCH_AH=m
215CONFIG_IP6_NF_MATCH_EUI64=m
216CONFIG_IP6_NF_MATCH_FRAG=m
217CONFIG_IP6_NF_MATCH_OPTS=m
218CONFIG_IP6_NF_MATCH_HL=m
219CONFIG_IP6_NF_MATCH_IPV6HEADER=m
220CONFIG_IP6_NF_MATCH_MH=m
221CONFIG_IP6_NF_MATCH_RT=m
222CONFIG_IP6_NF_TARGET_HL=m
223CONFIG_IP6_NF_TARGET_LOG=m
224CONFIG_IP6_NF_FILTER=m
225CONFIG_IP6_NF_TARGET_REJECT=m
226CONFIG_IP6_NF_MANGLE=m
227CONFIG_IP6_NF_RAW=m
228CONFIG_IP6_NF_SECURITY=m
229CONFIG_BRIDGE_NF_EBTABLES=m
230CONFIG_BRIDGE_EBT_BROUTE=m
231CONFIG_BRIDGE_EBT_T_FILTER=m
232CONFIG_BRIDGE_EBT_T_NAT=m
233CONFIG_BRIDGE_EBT_802_3=m
234CONFIG_BRIDGE_EBT_AMONG=m
235CONFIG_BRIDGE_EBT_ARP=m
236CONFIG_BRIDGE_EBT_IP=m
237CONFIG_BRIDGE_EBT_IP6=m
238CONFIG_BRIDGE_EBT_LIMIT=m
239CONFIG_BRIDGE_EBT_MARK=m
240CONFIG_BRIDGE_EBT_PKTTYPE=m
241CONFIG_BRIDGE_EBT_STP=m
242CONFIG_BRIDGE_EBT_VLAN=m
243CONFIG_BRIDGE_EBT_ARPREPLY=m
244CONFIG_BRIDGE_EBT_DNAT=m
245CONFIG_BRIDGE_EBT_MARK_T=m
246CONFIG_BRIDGE_EBT_REDIRECT=m
247CONFIG_BRIDGE_EBT_SNAT=m
248CONFIG_BRIDGE_EBT_LOG=m
249CONFIG_BRIDGE_EBT_ULOG=m
250CONFIG_BRIDGE_EBT_NFLOG=m
251CONFIG_RDS=m 110CONFIG_RDS=m
252CONFIG_RDS_TCP=m 111CONFIG_RDS_TCP=m
253CONFIG_BRIDGE=m 112CONFIG_BRIDGE=m
254CONFIG_NET_DSA=y
255CONFIG_VLAN_8021Q=m 113CONFIG_VLAN_8021Q=m
256CONFIG_VLAN_8021Q_GVRP=y 114CONFIG_VLAN_8021Q_GVRP=y
257CONFIG_PHONET=m 115CONFIG_PHONET=m
@@ -292,13 +150,13 @@ CONFIG_NET_ACT_POLICE=m
292CONFIG_NET_ACT_GACT=m 150CONFIG_NET_ACT_GACT=m
293CONFIG_GACT_PROB=y 151CONFIG_GACT_PROB=y
294CONFIG_NET_ACT_MIRRED=m 152CONFIG_NET_ACT_MIRRED=m
295CONFIG_NET_ACT_IPT=m
296CONFIG_NET_ACT_NAT=m 153CONFIG_NET_ACT_NAT=m
297CONFIG_NET_ACT_PEDIT=m 154CONFIG_NET_ACT_PEDIT=m
298CONFIG_NET_ACT_SIMP=m 155CONFIG_NET_ACT_SIMP=m
299CONFIG_NET_ACT_SKBEDIT=m 156CONFIG_NET_ACT_SKBEDIT=m
300CONFIG_NET_CLS_IND=y 157CONFIG_NET_CLS_IND=y
301CONFIG_DCB=y 158CONFIG_DCB=y
159CONFIG_DNS_RESOLVER=y
302# CONFIG_WIRELESS is not set 160# CONFIG_WIRELESS is not set
303CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" 161CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
304CONFIG_DEVTMPFS=y 162CONFIG_DEVTMPFS=y
@@ -317,10 +175,12 @@ CONFIG_BLK_DEV_SD=y
317CONFIG_SCSI_CONSTANTS=y 175CONFIG_SCSI_CONSTANTS=y
318CONFIG_SCSI_LOGGING=y 176CONFIG_SCSI_LOGGING=y
319CONFIG_SCSI_SAS_ATA=y 177CONFIG_SCSI_SAS_ATA=y
178CONFIG_ISCSI_TCP=m
320CONFIG_SCSI_MVSAS=y 179CONFIG_SCSI_MVSAS=y
321# CONFIG_SCSI_MVSAS_DEBUG is not set 180# CONFIG_SCSI_MVSAS_DEBUG is not set
322CONFIG_SCSI_MVSAS_TASKLET=y 181CONFIG_SCSI_MVSAS_TASKLET=y
323CONFIG_ATA=y 182CONFIG_ATA=y
183CONFIG_SATA_AHCI=y
324CONFIG_SATA_SIL24=y 184CONFIG_SATA_SIL24=y
325# CONFIG_ATA_SFF is not set 185# CONFIG_ATA_SFF is not set
326CONFIG_MD=y 186CONFIG_MD=y
@@ -343,6 +203,12 @@ CONFIG_DM_MULTIPATH_QL=m
343CONFIG_DM_MULTIPATH_ST=m 203CONFIG_DM_MULTIPATH_ST=m
344CONFIG_DM_DELAY=m 204CONFIG_DM_DELAY=m
345CONFIG_DM_UEVENT=y 205CONFIG_DM_UEVENT=y
206CONFIG_TARGET_CORE=m
207CONFIG_TCM_IBLOCK=m
208CONFIG_TCM_FILEIO=m
209CONFIG_TCM_PSCSI=m
210CONFIG_LOOPBACK_TARGET=m
211CONFIG_ISCSI_TARGET=m
346CONFIG_FUSION=y 212CONFIG_FUSION=y
347CONFIG_FUSION_SAS=y 213CONFIG_FUSION_SAS=y
348CONFIG_NETDEVICES=y 214CONFIG_NETDEVICES=y
@@ -359,42 +225,8 @@ CONFIG_VETH=m
359CONFIG_NET_DSA_MV88E6060=y 225CONFIG_NET_DSA_MV88E6060=y
360CONFIG_NET_DSA_MV88E6131=y 226CONFIG_NET_DSA_MV88E6131=y
361CONFIG_NET_DSA_MV88E6123_61_65=y 227CONFIG_NET_DSA_MV88E6123_61_65=y
362# CONFIG_NET_VENDOR_3COM is not set 228CONFIG_SKY2=y
363# CONFIG_NET_VENDOR_ADAPTEC is not set 229CONFIG_PTP_1588_CLOCK_TILEGX=y
364# CONFIG_NET_VENDOR_ALTEON is not set
365# CONFIG_NET_VENDOR_AMD is not set
366# CONFIG_NET_VENDOR_ATHEROS is not set
367# CONFIG_NET_VENDOR_BROADCOM is not set
368# CONFIG_NET_VENDOR_BROCADE is not set
369# CONFIG_NET_VENDOR_CHELSIO is not set
370# CONFIG_NET_VENDOR_CISCO is not set
371# CONFIG_NET_VENDOR_DEC is not set
372# CONFIG_NET_VENDOR_DLINK is not set
373# CONFIG_NET_VENDOR_EMULEX is not set
374# CONFIG_NET_VENDOR_EXAR is not set
375# CONFIG_NET_VENDOR_HP is not set
376# CONFIG_NET_VENDOR_INTEL is not set
377# CONFIG_NET_VENDOR_MARVELL is not set
378# CONFIG_NET_VENDOR_MELLANOX is not set
379# CONFIG_NET_VENDOR_MICREL is not set
380# CONFIG_NET_VENDOR_MYRI is not set
381# CONFIG_NET_VENDOR_NATSEMI is not set
382# CONFIG_NET_VENDOR_NVIDIA is not set
383# CONFIG_NET_VENDOR_OKI is not set
384# CONFIG_NET_PACKET_ENGINE is not set
385# CONFIG_NET_VENDOR_QLOGIC is not set
386# CONFIG_NET_VENDOR_REALTEK is not set
387# CONFIG_NET_VENDOR_RDC is not set
388# CONFIG_NET_VENDOR_SEEQ is not set
389# CONFIG_NET_VENDOR_SILAN is not set
390# CONFIG_NET_VENDOR_SIS is not set
391# CONFIG_NET_VENDOR_SMSC is not set
392# CONFIG_NET_VENDOR_STMICRO is not set
393# CONFIG_NET_VENDOR_SUN is not set
394# CONFIG_NET_VENDOR_TEHUTI is not set
395# CONFIG_NET_VENDOR_TI is not set
396# CONFIG_TILE_NET is not set
397# CONFIG_NET_VENDOR_VIA is not set
398# CONFIG_WLAN is not set 230# CONFIG_WLAN is not set
399# CONFIG_INPUT_MOUSEDEV is not set 231# CONFIG_INPUT_MOUSEDEV is not set
400# CONFIG_INPUT_KEYBOARD is not set 232# CONFIG_INPUT_KEYBOARD is not set
@@ -402,6 +234,7 @@ CONFIG_NET_DSA_MV88E6123_61_65=y
402# CONFIG_SERIO is not set 234# CONFIG_SERIO is not set
403# CONFIG_VT is not set 235# CONFIG_VT is not set
404# CONFIG_LEGACY_PTYS is not set 236# CONFIG_LEGACY_PTYS is not set
237CONFIG_SERIAL_TILEGX=y
405CONFIG_HW_RANDOM=y 238CONFIG_HW_RANDOM=y
406CONFIG_HW_RANDOM_TIMERIOMEM=m 239CONFIG_HW_RANDOM_TIMERIOMEM=m
407CONFIG_I2C=y 240CONFIG_I2C=y
@@ -410,13 +243,16 @@ CONFIG_I2C_CHARDEV=y
410CONFIG_WATCHDOG=y 243CONFIG_WATCHDOG=y
411CONFIG_WATCHDOG_NOWAYOUT=y 244CONFIG_WATCHDOG_NOWAYOUT=y
412# CONFIG_VGA_ARB is not set 245# CONFIG_VGA_ARB is not set
413# CONFIG_HID_SUPPORT is not set 246CONFIG_DRM=m
247CONFIG_DRM_TDFX=m
248CONFIG_DRM_R128=m
249CONFIG_DRM_MGA=m
250CONFIG_DRM_VIA=m
251CONFIG_DRM_SAVAGE=m
414CONFIG_USB=y 252CONFIG_USB=y
415# CONFIG_USB_DEVICE_CLASS is not set
416CONFIG_USB_EHCI_HCD=y 253CONFIG_USB_EHCI_HCD=y
417CONFIG_USB_OHCI_HCD=y 254CONFIG_USB_OHCI_HCD=y
418CONFIG_USB_STORAGE=y 255CONFIG_USB_STORAGE=y
419CONFIG_USB_LIBUSUAL=y
420CONFIG_EDAC=y 256CONFIG_EDAC=y
421CONFIG_EDAC_MM_EDAC=y 257CONFIG_EDAC_MM_EDAC=y
422CONFIG_RTC_CLASS=y 258CONFIG_RTC_CLASS=y
@@ -464,9 +300,8 @@ CONFIG_ECRYPT_FS=m
464CONFIG_CRAMFS=m 300CONFIG_CRAMFS=m
465CONFIG_SQUASHFS=m 301CONFIG_SQUASHFS=m
466CONFIG_NFS_FS=m 302CONFIG_NFS_FS=m
467CONFIG_NFS_V3=y
468CONFIG_NFS_V3_ACL=y 303CONFIG_NFS_V3_ACL=y
469CONFIG_NFS_V4=y 304CONFIG_NFS_V4=m
470CONFIG_NFS_V4_1=y 305CONFIG_NFS_V4_1=y
471CONFIG_NFS_FSCACHE=y 306CONFIG_NFS_FSCACHE=y
472CONFIG_NFSD=m 307CONFIG_NFSD=m
@@ -519,25 +354,28 @@ CONFIG_NLS_ISO8859_15=m
519CONFIG_NLS_KOI8_R=m 354CONFIG_NLS_KOI8_R=m
520CONFIG_NLS_KOI8_U=m 355CONFIG_NLS_KOI8_U=m
521CONFIG_NLS_UTF8=m 356CONFIG_NLS_UTF8=m
357CONFIG_DLM=m
522CONFIG_DLM_DEBUG=y 358CONFIG_DLM_DEBUG=y
359CONFIG_DYNAMIC_DEBUG=y
360CONFIG_DEBUG_INFO=y
361CONFIG_DEBUG_INFO_REDUCED=y
523# CONFIG_ENABLE_WARN_DEPRECATED is not set 362# CONFIG_ENABLE_WARN_DEPRECATED is not set
524CONFIG_MAGIC_SYSRQ=y
525CONFIG_STRIP_ASM_SYMS=y 363CONFIG_STRIP_ASM_SYMS=y
526CONFIG_DEBUG_FS=y 364CONFIG_DEBUG_FS=y
527CONFIG_HEADERS_CHECK=y 365CONFIG_HEADERS_CHECK=y
366# CONFIG_FRAME_POINTER is not set
367CONFIG_DEBUG_FORCE_WEAK_PER_CPU=y
368CONFIG_DEBUG_VM=y
369CONFIG_DEBUG_MEMORY_INIT=y
370CONFIG_DEBUG_STACKOVERFLOW=y
528CONFIG_LOCKUP_DETECTOR=y 371CONFIG_LOCKUP_DETECTOR=y
529CONFIG_SCHEDSTATS=y 372CONFIG_SCHEDSTATS=y
530CONFIG_TIMER_STATS=y 373CONFIG_TIMER_STATS=y
531CONFIG_DEBUG_INFO=y
532CONFIG_DEBUG_INFO_REDUCED=y
533CONFIG_DEBUG_VM=y
534CONFIG_DEBUG_MEMORY_INIT=y
535CONFIG_DEBUG_LIST=y 374CONFIG_DEBUG_LIST=y
536CONFIG_DEBUG_CREDENTIALS=y 375CONFIG_DEBUG_CREDENTIALS=y
537CONFIG_DEBUG_FORCE_WEAK_PER_CPU=y 376CONFIG_RCU_CPU_STALL_TIMEOUT=60
538CONFIG_DYNAMIC_DEBUG=y
539CONFIG_ASYNC_RAID6_TEST=m 377CONFIG_ASYNC_RAID6_TEST=m
540CONFIG_DEBUG_STACKOVERFLOW=y 378CONFIG_KGDB=y
541CONFIG_KEYS_DEBUG_PROC_KEYS=y 379CONFIG_KEYS_DEBUG_PROC_KEYS=y
542CONFIG_SECURITY=y 380CONFIG_SECURITY=y
543CONFIG_SECURITYFS=y 381CONFIG_SECURITYFS=y
@@ -546,7 +384,6 @@ CONFIG_SECURITY_NETWORK_XFRM=y
546CONFIG_SECURITY_SELINUX=y 384CONFIG_SECURITY_SELINUX=y
547CONFIG_SECURITY_SELINUX_BOOTPARAM=y 385CONFIG_SECURITY_SELINUX_BOOTPARAM=y
548CONFIG_SECURITY_SELINUX_DISABLE=y 386CONFIG_SECURITY_SELINUX_DISABLE=y
549CONFIG_CRYPTO_NULL=m
550CONFIG_CRYPTO_PCRYPT=m 387CONFIG_CRYPTO_PCRYPT=m
551CONFIG_CRYPTO_CRYPTD=m 388CONFIG_CRYPTO_CRYPTD=m
552CONFIG_CRYPTO_TEST=m 389CONFIG_CRYPTO_TEST=m
@@ -559,14 +396,12 @@ CONFIG_CRYPTO_XTS=m
559CONFIG_CRYPTO_HMAC=y 396CONFIG_CRYPTO_HMAC=y
560CONFIG_CRYPTO_XCBC=m 397CONFIG_CRYPTO_XCBC=m
561CONFIG_CRYPTO_VMAC=m 398CONFIG_CRYPTO_VMAC=m
562CONFIG_CRYPTO_CRC32C=y
563CONFIG_CRYPTO_MICHAEL_MIC=m 399CONFIG_CRYPTO_MICHAEL_MIC=m
564CONFIG_CRYPTO_RMD128=m 400CONFIG_CRYPTO_RMD128=m
565CONFIG_CRYPTO_RMD160=m 401CONFIG_CRYPTO_RMD160=m
566CONFIG_CRYPTO_RMD256=m 402CONFIG_CRYPTO_RMD256=m
567CONFIG_CRYPTO_RMD320=m 403CONFIG_CRYPTO_RMD320=m
568CONFIG_CRYPTO_SHA1=y 404CONFIG_CRYPTO_SHA1=y
569CONFIG_CRYPTO_SHA256=m
570CONFIG_CRYPTO_SHA512=m 405CONFIG_CRYPTO_SHA512=m
571CONFIG_CRYPTO_TGR192=m 406CONFIG_CRYPTO_TGR192=m
572CONFIG_CRYPTO_WP512=m 407CONFIG_CRYPTO_WP512=m
diff --git a/arch/tile/configs/tilepro_defconfig b/arch/tile/configs/tilepro_defconfig
index dd2b8f0c631f..80fc32ed0491 100644
--- a/arch/tile/configs/tilepro_defconfig
+++ b/arch/tile/configs/tilepro_defconfig
@@ -1,15 +1,14 @@
1CONFIG_EXPERIMENTAL=y
2# CONFIG_LOCALVERSION_AUTO is not set
3CONFIG_SYSVIPC=y 1CONFIG_SYSVIPC=y
4CONFIG_POSIX_MQUEUE=y 2CONFIG_POSIX_MQUEUE=y
3CONFIG_AUDIT=y
4CONFIG_NO_HZ=y
5CONFIG_HIGH_RES_TIMERS=y
5CONFIG_BSD_PROCESS_ACCT=y 6CONFIG_BSD_PROCESS_ACCT=y
6CONFIG_BSD_PROCESS_ACCT_V3=y 7CONFIG_BSD_PROCESS_ACCT_V3=y
7CONFIG_FHANDLE=y
8CONFIG_TASKSTATS=y 8CONFIG_TASKSTATS=y
9CONFIG_TASK_DELAY_ACCT=y 9CONFIG_TASK_DELAY_ACCT=y
10CONFIG_TASK_XACCT=y 10CONFIG_TASK_XACCT=y
11CONFIG_TASK_IO_ACCOUNTING=y 11CONFIG_TASK_IO_ACCOUNTING=y
12CONFIG_AUDIT=y
13CONFIG_LOG_BUF_SHIFT=19 12CONFIG_LOG_BUF_SHIFT=19
14CONFIG_CGROUPS=y 13CONFIG_CGROUPS=y
15CONFIG_CGROUP_DEBUG=y 14CONFIG_CGROUP_DEBUG=y
@@ -17,14 +16,13 @@ CONFIG_CGROUP_DEVICE=y
17CONFIG_CPUSETS=y 16CONFIG_CPUSETS=y
18CONFIG_CGROUP_CPUACCT=y 17CONFIG_CGROUP_CPUACCT=y
19CONFIG_RESOURCE_COUNTERS=y 18CONFIG_RESOURCE_COUNTERS=y
20CONFIG_CGROUP_MEMCG=y
21CONFIG_CGROUP_MEMCG_SWAP=y
22CONFIG_CGROUP_SCHED=y 19CONFIG_CGROUP_SCHED=y
23CONFIG_RT_GROUP_SCHED=y 20CONFIG_RT_GROUP_SCHED=y
24CONFIG_BLK_CGROUP=y 21CONFIG_BLK_CGROUP=y
25CONFIG_NAMESPACES=y 22CONFIG_NAMESPACES=y
26CONFIG_RELAY=y 23CONFIG_RELAY=y
27CONFIG_BLK_DEV_INITRD=y 24CONFIG_BLK_DEV_INITRD=y
25CONFIG_RD_XZ=y
28CONFIG_SYSCTL_SYSCALL=y 26CONFIG_SYSCTL_SYSCALL=y
29CONFIG_EMBEDDED=y 27CONFIG_EMBEDDED=y
30# CONFIG_COMPAT_BRK is not set 28# CONFIG_COMPAT_BRK is not set
@@ -44,11 +42,10 @@ CONFIG_UNIXWARE_DISKLABEL=y
44CONFIG_SGI_PARTITION=y 42CONFIG_SGI_PARTITION=y
45CONFIG_SUN_PARTITION=y 43CONFIG_SUN_PARTITION=y
46CONFIG_KARMA_PARTITION=y 44CONFIG_KARMA_PARTITION=y
47CONFIG_EFI_PARTITION=y
48CONFIG_CFQ_GROUP_IOSCHED=y 45CONFIG_CFQ_GROUP_IOSCHED=y
49CONFIG_NO_HZ=y
50CONFIG_HIGH_RES_TIMERS=y
51CONFIG_HZ_100=y 46CONFIG_HZ_100=y
47# CONFIG_COMPACTION is not set
48CONFIG_PREEMPT_VOLUNTARY=y
52CONFIG_PCI_DEBUG=y 49CONFIG_PCI_DEBUG=y
53# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set 50# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
54CONFIG_BINFMT_MISC=y 51CONFIG_BINFMT_MISC=y
@@ -122,16 +119,15 @@ CONFIG_NF_CONNTRACK_PPTP=m
122CONFIG_NF_CONNTRACK_SANE=m 119CONFIG_NF_CONNTRACK_SANE=m
123CONFIG_NF_CONNTRACK_SIP=m 120CONFIG_NF_CONNTRACK_SIP=m
124CONFIG_NF_CONNTRACK_TFTP=m 121CONFIG_NF_CONNTRACK_TFTP=m
125CONFIG_NETFILTER_TPROXY=m
126CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m 122CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
127CONFIG_NETFILTER_XT_TARGET_CONNMARK=m 123CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
128CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m 124CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
129CONFIG_NETFILTER_XT_TARGET_CT=m
130CONFIG_NETFILTER_XT_TARGET_DSCP=m 125CONFIG_NETFILTER_XT_TARGET_DSCP=m
131CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m 126CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m
132CONFIG_NETFILTER_XT_TARGET_MARK=m 127CONFIG_NETFILTER_XT_TARGET_MARK=m
133CONFIG_NETFILTER_XT_TARGET_NFLOG=m 128CONFIG_NETFILTER_XT_TARGET_NFLOG=m
134CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m 129CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
130CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
135CONFIG_NETFILTER_XT_TARGET_TEE=m 131CONFIG_NETFILTER_XT_TARGET_TEE=m
136CONFIG_NETFILTER_XT_TARGET_TPROXY=m 132CONFIG_NETFILTER_XT_TARGET_TPROXY=m
137CONFIG_NETFILTER_XT_TARGET_TRACE=m 133CONFIG_NETFILTER_XT_TARGET_TRACE=m
@@ -189,14 +185,12 @@ CONFIG_IP_VS_SED=m
189CONFIG_IP_VS_NQ=m 185CONFIG_IP_VS_NQ=m
190CONFIG_NF_CONNTRACK_IPV4=m 186CONFIG_NF_CONNTRACK_IPV4=m
191# CONFIG_NF_CONNTRACK_PROC_COMPAT is not set 187# CONFIG_NF_CONNTRACK_PROC_COMPAT is not set
192CONFIG_IP_NF_QUEUE=m
193CONFIG_IP_NF_IPTABLES=y 188CONFIG_IP_NF_IPTABLES=y
194CONFIG_IP_NF_MATCH_AH=m 189CONFIG_IP_NF_MATCH_AH=m
195CONFIG_IP_NF_MATCH_ECN=m 190CONFIG_IP_NF_MATCH_ECN=m
196CONFIG_IP_NF_MATCH_TTL=m 191CONFIG_IP_NF_MATCH_TTL=m
197CONFIG_IP_NF_FILTER=y 192CONFIG_IP_NF_FILTER=y
198CONFIG_IP_NF_TARGET_REJECT=y 193CONFIG_IP_NF_TARGET_REJECT=y
199CONFIG_IP_NF_TARGET_LOG=m
200CONFIG_IP_NF_TARGET_ULOG=m 194CONFIG_IP_NF_TARGET_ULOG=m
201CONFIG_IP_NF_MANGLE=m 195CONFIG_IP_NF_MANGLE=m
202CONFIG_IP_NF_TARGET_ECN=m 196CONFIG_IP_NF_TARGET_ECN=m
@@ -207,8 +201,6 @@ CONFIG_IP_NF_ARPTABLES=m
207CONFIG_IP_NF_ARPFILTER=m 201CONFIG_IP_NF_ARPFILTER=m
208CONFIG_IP_NF_ARP_MANGLE=m 202CONFIG_IP_NF_ARP_MANGLE=m
209CONFIG_NF_CONNTRACK_IPV6=m 203CONFIG_NF_CONNTRACK_IPV6=m
210CONFIG_IP6_NF_QUEUE=m
211CONFIG_IP6_NF_IPTABLES=m
212CONFIG_IP6_NF_MATCH_AH=m 204CONFIG_IP6_NF_MATCH_AH=m
213CONFIG_IP6_NF_MATCH_EUI64=m 205CONFIG_IP6_NF_MATCH_EUI64=m
214CONFIG_IP6_NF_MATCH_FRAG=m 206CONFIG_IP6_NF_MATCH_FRAG=m
@@ -218,7 +210,6 @@ CONFIG_IP6_NF_MATCH_IPV6HEADER=m
218CONFIG_IP6_NF_MATCH_MH=m 210CONFIG_IP6_NF_MATCH_MH=m
219CONFIG_IP6_NF_MATCH_RT=m 211CONFIG_IP6_NF_MATCH_RT=m
220CONFIG_IP6_NF_TARGET_HL=m 212CONFIG_IP6_NF_TARGET_HL=m
221CONFIG_IP6_NF_TARGET_LOG=m
222CONFIG_IP6_NF_FILTER=m 213CONFIG_IP6_NF_FILTER=m
223CONFIG_IP6_NF_TARGET_REJECT=m 214CONFIG_IP6_NF_TARGET_REJECT=m
224CONFIG_IP6_NF_MANGLE=m 215CONFIG_IP6_NF_MANGLE=m
@@ -249,7 +240,6 @@ CONFIG_BRIDGE_EBT_NFLOG=m
249CONFIG_RDS=m 240CONFIG_RDS=m
250CONFIG_RDS_TCP=m 241CONFIG_RDS_TCP=m
251CONFIG_BRIDGE=m 242CONFIG_BRIDGE=m
252CONFIG_NET_DSA=y
253CONFIG_VLAN_8021Q=m 243CONFIG_VLAN_8021Q=m
254CONFIG_VLAN_8021Q_GVRP=y 244CONFIG_VLAN_8021Q_GVRP=y
255CONFIG_PHONET=m 245CONFIG_PHONET=m
@@ -297,6 +287,7 @@ CONFIG_NET_ACT_SIMP=m
297CONFIG_NET_ACT_SKBEDIT=m 287CONFIG_NET_ACT_SKBEDIT=m
298CONFIG_NET_CLS_IND=y 288CONFIG_NET_CLS_IND=y
299CONFIG_DCB=y 289CONFIG_DCB=y
290CONFIG_DNS_RESOLVER=y
300# CONFIG_WIRELESS is not set 291# CONFIG_WIRELESS is not set
301CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" 292CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
302CONFIG_DEVTMPFS=y 293CONFIG_DEVTMPFS=y
@@ -354,40 +345,7 @@ CONFIG_NET_DSA_MV88E6060=y
354CONFIG_NET_DSA_MV88E6131=y 345CONFIG_NET_DSA_MV88E6131=y
355CONFIG_NET_DSA_MV88E6123_61_65=y 346CONFIG_NET_DSA_MV88E6123_61_65=y
356# CONFIG_NET_VENDOR_3COM is not set 347# CONFIG_NET_VENDOR_3COM is not set
357# CONFIG_NET_VENDOR_ADAPTEC is not set 348CONFIG_E1000E=y
358# CONFIG_NET_VENDOR_ALTEON is not set
359# CONFIG_NET_VENDOR_AMD is not set
360# CONFIG_NET_VENDOR_ATHEROS is not set
361# CONFIG_NET_VENDOR_BROADCOM is not set
362# CONFIG_NET_VENDOR_BROCADE is not set
363# CONFIG_NET_VENDOR_CHELSIO is not set
364# CONFIG_NET_VENDOR_CISCO is not set
365# CONFIG_NET_VENDOR_DEC is not set
366# CONFIG_NET_VENDOR_DLINK is not set
367# CONFIG_NET_VENDOR_EMULEX is not set
368# CONFIG_NET_VENDOR_EXAR is not set
369# CONFIG_NET_VENDOR_HP is not set
370# CONFIG_NET_VENDOR_INTEL is not set
371# CONFIG_NET_VENDOR_MARVELL is not set
372# CONFIG_NET_VENDOR_MELLANOX is not set
373# CONFIG_NET_VENDOR_MICREL is not set
374# CONFIG_NET_VENDOR_MYRI is not set
375# CONFIG_NET_VENDOR_NATSEMI is not set
376# CONFIG_NET_VENDOR_NVIDIA is not set
377# CONFIG_NET_VENDOR_OKI is not set
378# CONFIG_NET_PACKET_ENGINE is not set
379# CONFIG_NET_VENDOR_QLOGIC is not set
380# CONFIG_NET_VENDOR_REALTEK is not set
381# CONFIG_NET_VENDOR_RDC is not set
382# CONFIG_NET_VENDOR_SEEQ is not set
383# CONFIG_NET_VENDOR_SILAN is not set
384# CONFIG_NET_VENDOR_SIS is not set
385# CONFIG_NET_VENDOR_SMSC is not set
386# CONFIG_NET_VENDOR_STMICRO is not set
387# CONFIG_NET_VENDOR_SUN is not set
388# CONFIG_NET_VENDOR_TEHUTI is not set
389# CONFIG_NET_VENDOR_TI is not set
390# CONFIG_NET_VENDOR_VIA is not set
391# CONFIG_WLAN is not set 349# CONFIG_WLAN is not set
392# CONFIG_INPUT_MOUSEDEV is not set 350# CONFIG_INPUT_MOUSEDEV is not set
393# CONFIG_INPUT_KEYBOARD is not set 351# CONFIG_INPUT_KEYBOARD is not set
@@ -403,7 +361,6 @@ CONFIG_I2C_CHARDEV=y
403CONFIG_WATCHDOG=y 361CONFIG_WATCHDOG=y
404CONFIG_WATCHDOG_NOWAYOUT=y 362CONFIG_WATCHDOG_NOWAYOUT=y
405# CONFIG_VGA_ARB is not set 363# CONFIG_VGA_ARB is not set
406# CONFIG_HID_SUPPORT is not set
407# CONFIG_USB_SUPPORT is not set 364# CONFIG_USB_SUPPORT is not set
408CONFIG_EDAC=y 365CONFIG_EDAC=y
409CONFIG_EDAC_MM_EDAC=y 366CONFIG_EDAC_MM_EDAC=y
@@ -448,13 +405,13 @@ CONFIG_PROC_KCORE=y
448CONFIG_TMPFS=y 405CONFIG_TMPFS=y
449CONFIG_TMPFS_POSIX_ACL=y 406CONFIG_TMPFS_POSIX_ACL=y
450CONFIG_HUGETLBFS=y 407CONFIG_HUGETLBFS=y
408CONFIG_CONFIGFS_FS=m
451CONFIG_ECRYPT_FS=m 409CONFIG_ECRYPT_FS=m
452CONFIG_CRAMFS=m 410CONFIG_CRAMFS=m
453CONFIG_SQUASHFS=m 411CONFIG_SQUASHFS=m
454CONFIG_NFS_FS=m 412CONFIG_NFS_FS=m
455CONFIG_NFS_V3=y
456CONFIG_NFS_V3_ACL=y 413CONFIG_NFS_V3_ACL=y
457CONFIG_NFS_V4=y 414CONFIG_NFS_V4=m
458CONFIG_NFS_V4_1=y 415CONFIG_NFS_V4_1=y
459CONFIG_NFS_FSCACHE=y 416CONFIG_NFS_FSCACHE=y
460CONFIG_NFSD=m 417CONFIG_NFSD=m
@@ -508,26 +465,29 @@ CONFIG_NLS_ISO8859_15=m
508CONFIG_NLS_KOI8_R=m 465CONFIG_NLS_KOI8_R=m
509CONFIG_NLS_KOI8_U=m 466CONFIG_NLS_KOI8_U=m
510CONFIG_NLS_UTF8=m 467CONFIG_NLS_UTF8=m
468CONFIG_DLM=m
511CONFIG_DLM_DEBUG=y 469CONFIG_DLM_DEBUG=y
470CONFIG_DYNAMIC_DEBUG=y
471CONFIG_DEBUG_INFO=y
472CONFIG_DEBUG_INFO_REDUCED=y
512# CONFIG_ENABLE_WARN_DEPRECATED is not set 473# CONFIG_ENABLE_WARN_DEPRECATED is not set
513CONFIG_FRAME_WARN=2048 474CONFIG_FRAME_WARN=2048
514CONFIG_MAGIC_SYSRQ=y
515CONFIG_STRIP_ASM_SYMS=y 475CONFIG_STRIP_ASM_SYMS=y
516CONFIG_DEBUG_FS=y 476CONFIG_DEBUG_FS=y
517CONFIG_HEADERS_CHECK=y 477CONFIG_HEADERS_CHECK=y
478# CONFIG_FRAME_POINTER is not set
479CONFIG_DEBUG_FORCE_WEAK_PER_CPU=y
480CONFIG_MAGIC_SYSRQ=y
481CONFIG_DEBUG_VM=y
482CONFIG_DEBUG_MEMORY_INIT=y
483CONFIG_DEBUG_STACKOVERFLOW=y
518CONFIG_LOCKUP_DETECTOR=y 484CONFIG_LOCKUP_DETECTOR=y
519CONFIG_SCHEDSTATS=y 485CONFIG_SCHEDSTATS=y
520CONFIG_TIMER_STATS=y 486CONFIG_TIMER_STATS=y
521CONFIG_DEBUG_INFO=y
522CONFIG_DEBUG_INFO_REDUCED=y
523CONFIG_DEBUG_VM=y
524CONFIG_DEBUG_MEMORY_INIT=y
525CONFIG_DEBUG_LIST=y 487CONFIG_DEBUG_LIST=y
526CONFIG_DEBUG_CREDENTIALS=y 488CONFIG_DEBUG_CREDENTIALS=y
527CONFIG_DEBUG_FORCE_WEAK_PER_CPU=y 489CONFIG_RCU_CPU_STALL_TIMEOUT=60
528CONFIG_DYNAMIC_DEBUG=y
529CONFIG_ASYNC_RAID6_TEST=m 490CONFIG_ASYNC_RAID6_TEST=m
530CONFIG_DEBUG_STACKOVERFLOW=y
531CONFIG_KEYS_DEBUG_PROC_KEYS=y 491CONFIG_KEYS_DEBUG_PROC_KEYS=y
532CONFIG_SECURITY=y 492CONFIG_SECURITY=y
533CONFIG_SECURITYFS=y 493CONFIG_SECURITYFS=y
@@ -536,7 +496,6 @@ CONFIG_SECURITY_NETWORK_XFRM=y
536CONFIG_SECURITY_SELINUX=y 496CONFIG_SECURITY_SELINUX=y
537CONFIG_SECURITY_SELINUX_BOOTPARAM=y 497CONFIG_SECURITY_SELINUX_BOOTPARAM=y
538CONFIG_SECURITY_SELINUX_DISABLE=y 498CONFIG_SECURITY_SELINUX_DISABLE=y
539CONFIG_CRYPTO_NULL=m
540CONFIG_CRYPTO_PCRYPT=m 499CONFIG_CRYPTO_PCRYPT=m
541CONFIG_CRYPTO_CRYPTD=m 500CONFIG_CRYPTO_CRYPTD=m
542CONFIG_CRYPTO_TEST=m 501CONFIG_CRYPTO_TEST=m
@@ -549,14 +508,12 @@ CONFIG_CRYPTO_XTS=m
549CONFIG_CRYPTO_HMAC=y 508CONFIG_CRYPTO_HMAC=y
550CONFIG_CRYPTO_XCBC=m 509CONFIG_CRYPTO_XCBC=m
551CONFIG_CRYPTO_VMAC=m 510CONFIG_CRYPTO_VMAC=m
552CONFIG_CRYPTO_CRC32C=y
553CONFIG_CRYPTO_MICHAEL_MIC=m 511CONFIG_CRYPTO_MICHAEL_MIC=m
554CONFIG_CRYPTO_RMD128=m 512CONFIG_CRYPTO_RMD128=m
555CONFIG_CRYPTO_RMD160=m 513CONFIG_CRYPTO_RMD160=m
556CONFIG_CRYPTO_RMD256=m 514CONFIG_CRYPTO_RMD256=m
557CONFIG_CRYPTO_RMD320=m 515CONFIG_CRYPTO_RMD320=m
558CONFIG_CRYPTO_SHA1=y 516CONFIG_CRYPTO_SHA1=y
559CONFIG_CRYPTO_SHA256=m
560CONFIG_CRYPTO_SHA512=m 517CONFIG_CRYPTO_SHA512=m
561CONFIG_CRYPTO_TGR192=m 518CONFIG_CRYPTO_TGR192=m
562CONFIG_CRYPTO_WP512=m 519CONFIG_CRYPTO_WP512=m
diff --git a/arch/tile/gxio/Kconfig b/arch/tile/gxio/Kconfig
index d221f8d6de8b..d4e10d58071b 100644
--- a/arch/tile/gxio/Kconfig
+++ b/arch/tile/gxio/Kconfig
@@ -26,3 +26,8 @@ config TILE_GXIO_TRIO
26config TILE_GXIO_USB_HOST 26config TILE_GXIO_USB_HOST
27 bool 27 bool
28 select TILE_GXIO 28 select TILE_GXIO
29
30# Support direct access to the TILE-Gx UART hardware from kernel space.
31config TILE_GXIO_UART
32 bool
33 select TILE_GXIO
diff --git a/arch/tile/gxio/Makefile b/arch/tile/gxio/Makefile
index 8684bcaa74ea..26ae2c727467 100644
--- a/arch/tile/gxio/Makefile
+++ b/arch/tile/gxio/Makefile
@@ -6,4 +6,5 @@ obj-$(CONFIG_TILE_GXIO) += iorpc_globals.o kiorpc.o
6obj-$(CONFIG_TILE_GXIO_DMA) += dma_queue.o 6obj-$(CONFIG_TILE_GXIO_DMA) += dma_queue.o
7obj-$(CONFIG_TILE_GXIO_MPIPE) += mpipe.o iorpc_mpipe.o iorpc_mpipe_info.o 7obj-$(CONFIG_TILE_GXIO_MPIPE) += mpipe.o iorpc_mpipe.o iorpc_mpipe_info.o
8obj-$(CONFIG_TILE_GXIO_TRIO) += trio.o iorpc_trio.o 8obj-$(CONFIG_TILE_GXIO_TRIO) += trio.o iorpc_trio.o
9obj-$(CONFIG_TILE_GXIO_UART) += uart.o iorpc_uart.o
9obj-$(CONFIG_TILE_GXIO_USB_HOST) += usb_host.o iorpc_usb_host.o 10obj-$(CONFIG_TILE_GXIO_USB_HOST) += usb_host.o iorpc_usb_host.o
diff --git a/arch/tile/gxio/iorpc_trio.c b/arch/tile/gxio/iorpc_trio.c
index cef4b2209cda..da6e18e049c3 100644
--- a/arch/tile/gxio/iorpc_trio.c
+++ b/arch/tile/gxio/iorpc_trio.c
@@ -61,6 +61,29 @@ int gxio_trio_alloc_memory_maps(gxio_trio_context_t * context,
61 61
62EXPORT_SYMBOL(gxio_trio_alloc_memory_maps); 62EXPORT_SYMBOL(gxio_trio_alloc_memory_maps);
63 63
64struct alloc_scatter_queues_param {
65 unsigned int count;
66 unsigned int first;
67 unsigned int flags;
68};
69
70int gxio_trio_alloc_scatter_queues(gxio_trio_context_t * context,
71 unsigned int count, unsigned int first,
72 unsigned int flags)
73{
74 struct alloc_scatter_queues_param temp;
75 struct alloc_scatter_queues_param *params = &temp;
76
77 params->count = count;
78 params->first = first;
79 params->flags = flags;
80
81 return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
82 sizeof(*params),
83 GXIO_TRIO_OP_ALLOC_SCATTER_QUEUES);
84}
85
86EXPORT_SYMBOL(gxio_trio_alloc_scatter_queues);
64 87
65struct alloc_pio_regions_param { 88struct alloc_pio_regions_param {
66 unsigned int count; 89 unsigned int count;
diff --git a/arch/tile/gxio/iorpc_uart.c b/arch/tile/gxio/iorpc_uart.c
new file mode 100644
index 000000000000..b9a6d6193d73
--- /dev/null
+++ b/arch/tile/gxio/iorpc_uart.c
@@ -0,0 +1,77 @@
1/*
2 * Copyright 2013 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#include "gxio/iorpc_uart.h"
17
18struct cfg_interrupt_param {
19 union iorpc_interrupt interrupt;
20};
21
22int gxio_uart_cfg_interrupt(gxio_uart_context_t *context, int inter_x,
23 int inter_y, int inter_ipi, int inter_event)
24{
25 struct cfg_interrupt_param temp;
26 struct cfg_interrupt_param *params = &temp;
27
28 params->interrupt.kernel.x = inter_x;
29 params->interrupt.kernel.y = inter_y;
30 params->interrupt.kernel.ipi = inter_ipi;
31 params->interrupt.kernel.event = inter_event;
32
33 return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
34 sizeof(*params), GXIO_UART_OP_CFG_INTERRUPT);
35}
36
37EXPORT_SYMBOL(gxio_uart_cfg_interrupt);
38
39struct get_mmio_base_param {
40 HV_PTE base;
41};
42
43int gxio_uart_get_mmio_base(gxio_uart_context_t *context, HV_PTE *base)
44{
45 int __result;
46 struct get_mmio_base_param temp;
47 struct get_mmio_base_param *params = &temp;
48
49 __result =
50 hv_dev_pread(context->fd, 0, (HV_VirtAddr) params, sizeof(*params),
51 GXIO_UART_OP_GET_MMIO_BASE);
52 *base = params->base;
53
54 return __result;
55}
56
57EXPORT_SYMBOL(gxio_uart_get_mmio_base);
58
59struct check_mmio_offset_param {
60 unsigned long offset;
61 unsigned long size;
62};
63
64int gxio_uart_check_mmio_offset(gxio_uart_context_t *context,
65 unsigned long offset, unsigned long size)
66{
67 struct check_mmio_offset_param temp;
68 struct check_mmio_offset_param *params = &temp;
69
70 params->offset = offset;
71 params->size = size;
72
73 return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
74 sizeof(*params), GXIO_UART_OP_CHECK_MMIO_OFFSET);
75}
76
77EXPORT_SYMBOL(gxio_uart_check_mmio_offset);
diff --git a/arch/tile/gxio/uart.c b/arch/tile/gxio/uart.c
new file mode 100644
index 000000000000..ba585175ef88
--- /dev/null
+++ b/arch/tile/gxio/uart.c
@@ -0,0 +1,87 @@
1/*
2 * Copyright 2013 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 * Implementation of UART gxio calls.
17 */
18
19#include <linux/io.h>
20#include <linux/errno.h>
21#include <linux/module.h>
22
23#include <gxio/uart.h>
24#include <gxio/iorpc_globals.h>
25#include <gxio/iorpc_uart.h>
26#include <gxio/kiorpc.h>
27
28int gxio_uart_init(gxio_uart_context_t *context, int uart_index)
29{
30 char file[32];
31 int fd;
32
33 snprintf(file, sizeof(file), "uart/%d/iorpc", uart_index);
34 fd = hv_dev_open((HV_VirtAddr) file, 0);
35 if (fd < 0) {
36 if (fd >= GXIO_ERR_MIN && fd <= GXIO_ERR_MAX)
37 return fd;
38 else
39 return -ENODEV;
40 }
41
42 context->fd = fd;
43
44 /* Map in the MMIO space. */
45 context->mmio_base = (void __force *)
46 iorpc_ioremap(fd, HV_UART_MMIO_OFFSET, HV_UART_MMIO_SIZE);
47
48 if (context->mmio_base == NULL) {
49 hv_dev_close(context->fd);
50 context->fd = -1;
51 return -ENODEV;
52 }
53
54 return 0;
55}
56
57EXPORT_SYMBOL_GPL(gxio_uart_init);
58
59int gxio_uart_destroy(gxio_uart_context_t *context)
60{
61 iounmap((void __force __iomem *)(context->mmio_base));
62 hv_dev_close(context->fd);
63
64 context->mmio_base = NULL;
65 context->fd = -1;
66
67 return 0;
68}
69
70EXPORT_SYMBOL_GPL(gxio_uart_destroy);
71
72/* UART register write wrapper. */
73void gxio_uart_write(gxio_uart_context_t *context, uint64_t offset,
74 uint64_t word)
75{
76 __gxio_mmio_write(context->mmio_base + offset, word);
77}
78
79EXPORT_SYMBOL_GPL(gxio_uart_write);
80
81/* UART register read wrapper. */
82uint64_t gxio_uart_read(gxio_uart_context_t *context, uint64_t offset)
83{
84 return __gxio_mmio_read(context->mmio_base + offset);
85}
86
87EXPORT_SYMBOL_GPL(gxio_uart_read);
diff --git a/arch/tile/include/arch/trio.h b/arch/tile/include/arch/trio.h
index d3000a871a21..c0ddedcae085 100644
--- a/arch/tile/include/arch/trio.h
+++ b/arch/tile/include/arch/trio.h
@@ -23,6 +23,45 @@
23#ifndef __ASSEMBLER__ 23#ifndef __ASSEMBLER__
24 24
25/* 25/*
26 * Map SQ Doorbell Format.
27 * This describes the format of the write-only doorbell register that exists
28 * in the last 8-bytes of the MAP_SQ_BASE/LIM range. This register is only
29 * writable from PCIe space. Writes to this register will not be written to
30 * Tile memory space and thus no IO VA translation is required if the last
31 * page of the BASE/LIM range is not otherwise written.
32 */
33
34__extension__
35typedef union
36{
37 struct
38 {
39#ifndef __BIG_ENDIAN__
40 /*
41 * When written with a 1, the associated MAP_SQ region's doorbell
42 * interrupt will be triggered once all previous writes are visible to
43 * Tile software.
44 */
45 uint_reg_t doorbell : 1;
46 /*
47 * When written with a 1, the descriptor at the head of the associated
48 * MAP_SQ's FIFO will be dequeued.
49 */
50 uint_reg_t pop : 1;
51 /* Reserved. */
52 uint_reg_t __reserved : 62;
53#else /* __BIG_ENDIAN__ */
54 uint_reg_t __reserved : 62;
55 uint_reg_t pop : 1;
56 uint_reg_t doorbell : 1;
57#endif
58 };
59
60 uint_reg_t word;
61} TRIO_MAP_SQ_DOORBELL_FMT_t;
62
63
64/*
26 * Tile PIO Region Configuration - CFG Address Format. 65 * Tile PIO Region Configuration - CFG Address Format.
27 * This register describes the address format for PIO accesses when the 66 * This register describes the address format for PIO accesses when the
28 * associated region is setup with TYPE=CFG. 67 * associated region is setup with TYPE=CFG.
diff --git a/arch/tile/include/arch/uart.h b/arch/tile/include/arch/uart.h
new file mode 100644
index 000000000000..07966970adad
--- /dev/null
+++ b/arch/tile/include/arch/uart.h
@@ -0,0 +1,300 @@
1/*
2 * Copyright 2013 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/* Machine-generated file; do not edit. */
16
17#ifndef __ARCH_UART_H__
18#define __ARCH_UART_H__
19
20#include <arch/abi.h>
21#include <arch/uart_def.h>
22
23#ifndef __ASSEMBLER__
24
25/* Divisor. */
26
27__extension__
28typedef union
29{
30 struct
31 {
32#ifndef __BIG_ENDIAN__
33 /*
34 * Baud Rate Divisor. Desired_baud_rate = REF_CLK frequency / (baud *
35 * 16).
36 * Note: REF_CLK is always 125 MHz, the default
37 * divisor = 68, baud rate = 125M/(68*16) = 115200 baud.
38 */
39 uint_reg_t divisor : 12;
40 /* Reserved. */
41 uint_reg_t __reserved : 52;
42#else /* __BIG_ENDIAN__ */
43 uint_reg_t __reserved : 52;
44 uint_reg_t divisor : 12;
45#endif
46 };
47
48 uint_reg_t word;
49} UART_DIVISOR_t;
50
51/* FIFO Count. */
52
53__extension__
54typedef union
55{
56 struct
57 {
58#ifndef __BIG_ENDIAN__
59 /*
60 * n: n active entries in the receive FIFO (max is 2**8). Each entry has
61 * 8 bits.
62 * 0: no active entry in the receive FIFO (that is empty).
63 */
64 uint_reg_t rfifo_count : 9;
65 /* Reserved. */
66 uint_reg_t __reserved_0 : 7;
67 /*
68 * n: n active entries in the transmit FIFO (max is 2**8). Each entry has
69 * 8 bits.
70 * 0: no active entry in the transmit FIFO (that is empty).
71 */
72 uint_reg_t tfifo_count : 9;
73 /* Reserved. */
74 uint_reg_t __reserved_1 : 7;
75 /*
76 * n: n active entries in the write FIFO (max is 2**2). Each entry has 8
77 * bits.
78 * 0: no active entry in the write FIFO (that is empty).
79 */
80 uint_reg_t wfifo_count : 3;
81 /* Reserved. */
82 uint_reg_t __reserved_2 : 29;
83#else /* __BIG_ENDIAN__ */
84 uint_reg_t __reserved_2 : 29;
85 uint_reg_t wfifo_count : 3;
86 uint_reg_t __reserved_1 : 7;
87 uint_reg_t tfifo_count : 9;
88 uint_reg_t __reserved_0 : 7;
89 uint_reg_t rfifo_count : 9;
90#endif
91 };
92
93 uint_reg_t word;
94} UART_FIFO_COUNT_t;
95
96/* FLAG. */
97
98__extension__
99typedef union
100{
101 struct
102 {
103#ifndef __BIG_ENDIAN__
104 /* Reserved. */
105 uint_reg_t __reserved_0 : 1;
106 /* 1: receive FIFO is empty */
107 uint_reg_t rfifo_empty : 1;
108 /* 1: write FIFO is empty. */
109 uint_reg_t wfifo_empty : 1;
110 /* 1: transmit FIFO is empty. */
111 uint_reg_t tfifo_empty : 1;
112 /* 1: receive FIFO is full. */
113 uint_reg_t rfifo_full : 1;
114 /* 1: write FIFO is full. */
115 uint_reg_t wfifo_full : 1;
116 /* 1: transmit FIFO is full. */
117 uint_reg_t tfifo_full : 1;
118 /* Reserved. */
119 uint_reg_t __reserved_1 : 57;
120#else /* __BIG_ENDIAN__ */
121 uint_reg_t __reserved_1 : 57;
122 uint_reg_t tfifo_full : 1;
123 uint_reg_t wfifo_full : 1;
124 uint_reg_t rfifo_full : 1;
125 uint_reg_t tfifo_empty : 1;
126 uint_reg_t wfifo_empty : 1;
127 uint_reg_t rfifo_empty : 1;
128 uint_reg_t __reserved_0 : 1;
129#endif
130 };
131
132 uint_reg_t word;
133} UART_FLAG_t;
134
135/*
136 * Interrupt Vector Mask.
137 * Each bit in this register corresponds to a specific interrupt. When set,
138 * the associated interrupt will not be dispatched.
139 */
140
141__extension__
142typedef union
143{
144 struct
145 {
146#ifndef __BIG_ENDIAN__
147 /* Read data FIFO read and no data available */
148 uint_reg_t rdat_err : 1;
149 /* Write FIFO was written but it was full */
150 uint_reg_t wdat_err : 1;
151 /* Stop bit not found when current data was received */
152 uint_reg_t frame_err : 1;
153 /* Parity error was detected when current data was received */
154 uint_reg_t parity_err : 1;
155 /* Data was received but the receive FIFO was full */
156 uint_reg_t rfifo_overflow : 1;
157 /*
158 * An almost full event is reached when data is to be written to the
159 * receive FIFO, and the receive FIFO has more than or equal to
160 * BUFFER_THRESHOLD.RFIFO_AFULL bytes.
161 */
162 uint_reg_t rfifo_afull : 1;
163 /* Reserved. */
164 uint_reg_t __reserved_0 : 1;
165 /* An entry in the transmit FIFO was popped */
166 uint_reg_t tfifo_re : 1;
167 /* An entry has been pushed into the receive FIFO */
168 uint_reg_t rfifo_we : 1;
169 /* An entry of the write FIFO has been popped */
170 uint_reg_t wfifo_re : 1;
171 /* Rshim read receive FIFO in protocol mode */
172 uint_reg_t rfifo_err : 1;
173 /*
174 * An almost empty event is reached when data is to be read from the
175 * transmit FIFO, and the transmit FIFO has less than or equal to
176 * BUFFER_THRESHOLD.TFIFO_AEMPTY bytes.
177 */
178 uint_reg_t tfifo_aempty : 1;
179 /* Reserved. */
180 uint_reg_t __reserved_1 : 52;
181#else /* __BIG_ENDIAN__ */
182 uint_reg_t __reserved_1 : 52;
183 uint_reg_t tfifo_aempty : 1;
184 uint_reg_t rfifo_err : 1;
185 uint_reg_t wfifo_re : 1;
186 uint_reg_t rfifo_we : 1;
187 uint_reg_t tfifo_re : 1;
188 uint_reg_t __reserved_0 : 1;
189 uint_reg_t rfifo_afull : 1;
190 uint_reg_t rfifo_overflow : 1;
191 uint_reg_t parity_err : 1;
192 uint_reg_t frame_err : 1;
193 uint_reg_t wdat_err : 1;
194 uint_reg_t rdat_err : 1;
195#endif
196 };
197
198 uint_reg_t word;
199} UART_INTERRUPT_MASK_t;
200
201/*
202 * Interrupt vector, write-one-to-clear.
203 * Each bit in this register corresponds to a specific interrupt. Hardware
204 * sets the bit when the associated condition has occurred. Writing a 1
205 * clears the status bit.
206 */
207
208__extension__
209typedef union
210{
211 struct
212 {
213#ifndef __BIG_ENDIAN__
214 /* Read data FIFO read and no data available */
215 uint_reg_t rdat_err : 1;
216 /* Write FIFO was written but it was full */
217 uint_reg_t wdat_err : 1;
218 /* Stop bit not found when current data was received */
219 uint_reg_t frame_err : 1;
220 /* Parity error was detected when current data was received */
221 uint_reg_t parity_err : 1;
222 /* Data was received but the receive FIFO was full */
223 uint_reg_t rfifo_overflow : 1;
224 /*
225 * Data was received and the receive FIFO is now almost full (more than
226 * BUFFER_THRESHOLD.RFIFO_AFULL bytes in it)
227 */
228 uint_reg_t rfifo_afull : 1;
229 /* Reserved. */
230 uint_reg_t __reserved_0 : 1;
231 /* An entry in the transmit FIFO was popped */
232 uint_reg_t tfifo_re : 1;
233 /* An entry has been pushed into the receive FIFO */
234 uint_reg_t rfifo_we : 1;
235 /* An entry of the write FIFO has been popped */
236 uint_reg_t wfifo_re : 1;
237 /* Rshim read receive FIFO in protocol mode */
238 uint_reg_t rfifo_err : 1;
239 /*
240 * Data was read from the transmit FIFO and now it is almost empty (less
241 * than or equal to BUFFER_THRESHOLD.TFIFO_AEMPTY bytes in it).
242 */
243 uint_reg_t tfifo_aempty : 1;
244 /* Reserved. */
245 uint_reg_t __reserved_1 : 52;
246#else /* __BIG_ENDIAN__ */
247 uint_reg_t __reserved_1 : 52;
248 uint_reg_t tfifo_aempty : 1;
249 uint_reg_t rfifo_err : 1;
250 uint_reg_t wfifo_re : 1;
251 uint_reg_t rfifo_we : 1;
252 uint_reg_t tfifo_re : 1;
253 uint_reg_t __reserved_0 : 1;
254 uint_reg_t rfifo_afull : 1;
255 uint_reg_t rfifo_overflow : 1;
256 uint_reg_t parity_err : 1;
257 uint_reg_t frame_err : 1;
258 uint_reg_t wdat_err : 1;
259 uint_reg_t rdat_err : 1;
260#endif
261 };
262
263 uint_reg_t word;
264} UART_INTERRUPT_STATUS_t;
265
266/* Type. */
267
268__extension__
269typedef union
270{
271 struct
272 {
273#ifndef __BIG_ENDIAN__
274 /* Number of stop bits, rx and tx */
275 uint_reg_t sbits : 1;
276 /* Reserved. */
277 uint_reg_t __reserved_0 : 1;
278 /* Data word size, rx and tx */
279 uint_reg_t dbits : 1;
280 /* Reserved. */
281 uint_reg_t __reserved_1 : 1;
282 /* Parity selection, rx and tx */
283 uint_reg_t ptype : 3;
284 /* Reserved. */
285 uint_reg_t __reserved_2 : 57;
286#else /* __BIG_ENDIAN__ */
287 uint_reg_t __reserved_2 : 57;
288 uint_reg_t ptype : 3;
289 uint_reg_t __reserved_1 : 1;
290 uint_reg_t dbits : 1;
291 uint_reg_t __reserved_0 : 1;
292 uint_reg_t sbits : 1;
293#endif
294 };
295
296 uint_reg_t word;
297} UART_TYPE_t;
298#endif /* !defined(__ASSEMBLER__) */
299
300#endif /* !defined(__ARCH_UART_H__) */
diff --git a/arch/tile/include/arch/uart_def.h b/arch/tile/include/arch/uart_def.h
new file mode 100644
index 000000000000..42bcaf535379
--- /dev/null
+++ b/arch/tile/include/arch/uart_def.h
@@ -0,0 +1,120 @@
1/*
2 * Copyright 2013 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/* Machine-generated file; do not edit. */
16
17#ifndef __ARCH_UART_DEF_H__
18#define __ARCH_UART_DEF_H__
19#define UART_DIVISOR 0x0158
20#define UART_FIFO_COUNT 0x0110
21#define UART_FLAG 0x0108
22#define UART_INTERRUPT_MASK 0x0208
23#define UART_INTERRUPT_MASK__RDAT_ERR_SHIFT 0
24#define UART_INTERRUPT_MASK__RDAT_ERR_WIDTH 1
25#define UART_INTERRUPT_MASK__RDAT_ERR_RESET_VAL 1
26#define UART_INTERRUPT_MASK__RDAT_ERR_RMASK 0x1
27#define UART_INTERRUPT_MASK__RDAT_ERR_MASK 0x1
28#define UART_INTERRUPT_MASK__RDAT_ERR_FIELD 0,0
29#define UART_INTERRUPT_MASK__WDAT_ERR_SHIFT 1
30#define UART_INTERRUPT_MASK__WDAT_ERR_WIDTH 1
31#define UART_INTERRUPT_MASK__WDAT_ERR_RESET_VAL 1
32#define UART_INTERRUPT_MASK__WDAT_ERR_RMASK 0x1
33#define UART_INTERRUPT_MASK__WDAT_ERR_MASK 0x2
34#define UART_INTERRUPT_MASK__WDAT_ERR_FIELD 1,1
35#define UART_INTERRUPT_MASK__FRAME_ERR_SHIFT 2
36#define UART_INTERRUPT_MASK__FRAME_ERR_WIDTH 1
37#define UART_INTERRUPT_MASK__FRAME_ERR_RESET_VAL 1
38#define UART_INTERRUPT_MASK__FRAME_ERR_RMASK 0x1
39#define UART_INTERRUPT_MASK__FRAME_ERR_MASK 0x4
40#define UART_INTERRUPT_MASK__FRAME_ERR_FIELD 2,2
41#define UART_INTERRUPT_MASK__PARITY_ERR_SHIFT 3
42#define UART_INTERRUPT_MASK__PARITY_ERR_WIDTH 1
43#define UART_INTERRUPT_MASK__PARITY_ERR_RESET_VAL 1
44#define UART_INTERRUPT_MASK__PARITY_ERR_RMASK 0x1
45#define UART_INTERRUPT_MASK__PARITY_ERR_MASK 0x8
46#define UART_INTERRUPT_MASK__PARITY_ERR_FIELD 3,3
47#define UART_INTERRUPT_MASK__RFIFO_OVERFLOW_SHIFT 4
48#define UART_INTERRUPT_MASK__RFIFO_OVERFLOW_WIDTH 1
49#define UART_INTERRUPT_MASK__RFIFO_OVERFLOW_RESET_VAL 1
50#define UART_INTERRUPT_MASK__RFIFO_OVERFLOW_RMASK 0x1
51#define UART_INTERRUPT_MASK__RFIFO_OVERFLOW_MASK 0x10
52#define UART_INTERRUPT_MASK__RFIFO_OVERFLOW_FIELD 4,4
53#define UART_INTERRUPT_MASK__RFIFO_AFULL_SHIFT 5
54#define UART_INTERRUPT_MASK__RFIFO_AFULL_WIDTH 1
55#define UART_INTERRUPT_MASK__RFIFO_AFULL_RESET_VAL 1
56#define UART_INTERRUPT_MASK__RFIFO_AFULL_RMASK 0x1
57#define UART_INTERRUPT_MASK__RFIFO_AFULL_MASK 0x20
58#define UART_INTERRUPT_MASK__RFIFO_AFULL_FIELD 5,5
59#define UART_INTERRUPT_MASK__TFIFO_RE_SHIFT 7
60#define UART_INTERRUPT_MASK__TFIFO_RE_WIDTH 1
61#define UART_INTERRUPT_MASK__TFIFO_RE_RESET_VAL 1
62#define UART_INTERRUPT_MASK__TFIFO_RE_RMASK 0x1
63#define UART_INTERRUPT_MASK__TFIFO_RE_MASK 0x80
64#define UART_INTERRUPT_MASK__TFIFO_RE_FIELD 7,7
65#define UART_INTERRUPT_MASK__RFIFO_WE_SHIFT 8
66#define UART_INTERRUPT_MASK__RFIFO_WE_WIDTH 1
67#define UART_INTERRUPT_MASK__RFIFO_WE_RESET_VAL 1
68#define UART_INTERRUPT_MASK__RFIFO_WE_RMASK 0x1
69#define UART_INTERRUPT_MASK__RFIFO_WE_MASK 0x100
70#define UART_INTERRUPT_MASK__RFIFO_WE_FIELD 8,8
71#define UART_INTERRUPT_MASK__WFIFO_RE_SHIFT 9
72#define UART_INTERRUPT_MASK__WFIFO_RE_WIDTH 1
73#define UART_INTERRUPT_MASK__WFIFO_RE_RESET_VAL 1
74#define UART_INTERRUPT_MASK__WFIFO_RE_RMASK 0x1
75#define UART_INTERRUPT_MASK__WFIFO_RE_MASK 0x200
76#define UART_INTERRUPT_MASK__WFIFO_RE_FIELD 9,9
77#define UART_INTERRUPT_MASK__RFIFO_ERR_SHIFT 10
78#define UART_INTERRUPT_MASK__RFIFO_ERR_WIDTH 1
79#define UART_INTERRUPT_MASK__RFIFO_ERR_RESET_VAL 1
80#define UART_INTERRUPT_MASK__RFIFO_ERR_RMASK 0x1
81#define UART_INTERRUPT_MASK__RFIFO_ERR_MASK 0x400
82#define UART_INTERRUPT_MASK__RFIFO_ERR_FIELD 10,10
83#define UART_INTERRUPT_MASK__TFIFO_AEMPTY_SHIFT 11
84#define UART_INTERRUPT_MASK__TFIFO_AEMPTY_WIDTH 1
85#define UART_INTERRUPT_MASK__TFIFO_AEMPTY_RESET_VAL 1
86#define UART_INTERRUPT_MASK__TFIFO_AEMPTY_RMASK 0x1
87#define UART_INTERRUPT_MASK__TFIFO_AEMPTY_MASK 0x800
88#define UART_INTERRUPT_MASK__TFIFO_AEMPTY_FIELD 11,11
89#define UART_INTERRUPT_STATUS 0x0200
90#define UART_RECEIVE_DATA 0x0148
91#define UART_TRANSMIT_DATA 0x0140
92#define UART_TYPE 0x0160
93#define UART_TYPE__SBITS_SHIFT 0
94#define UART_TYPE__SBITS_WIDTH 1
95#define UART_TYPE__SBITS_RESET_VAL 1
96#define UART_TYPE__SBITS_RMASK 0x1
97#define UART_TYPE__SBITS_MASK 0x1
98#define UART_TYPE__SBITS_FIELD 0,0
99#define UART_TYPE__SBITS_VAL_ONE_SBITS 0x0
100#define UART_TYPE__SBITS_VAL_TWO_SBITS 0x1
101#define UART_TYPE__DBITS_SHIFT 2
102#define UART_TYPE__DBITS_WIDTH 1
103#define UART_TYPE__DBITS_RESET_VAL 0
104#define UART_TYPE__DBITS_RMASK 0x1
105#define UART_TYPE__DBITS_MASK 0x4
106#define UART_TYPE__DBITS_FIELD 2,2
107#define UART_TYPE__DBITS_VAL_EIGHT_DBITS 0x0
108#define UART_TYPE__DBITS_VAL_SEVEN_DBITS 0x1
109#define UART_TYPE__PTYPE_SHIFT 4
110#define UART_TYPE__PTYPE_WIDTH 3
111#define UART_TYPE__PTYPE_RESET_VAL 3
112#define UART_TYPE__PTYPE_RMASK 0x7
113#define UART_TYPE__PTYPE_MASK 0x70
114#define UART_TYPE__PTYPE_FIELD 4,6
115#define UART_TYPE__PTYPE_VAL_NONE 0x0
116#define UART_TYPE__PTYPE_VAL_MARK 0x1
117#define UART_TYPE__PTYPE_VAL_SPACE 0x2
118#define UART_TYPE__PTYPE_VAL_EVEN 0x3
119#define UART_TYPE__PTYPE_VAL_ODD 0x4
120#endif /* !defined(__ARCH_UART_DEF_H__) */
diff --git a/arch/tile/include/asm/Kbuild b/arch/tile/include/asm/Kbuild
index b17b9b8e53cd..664d6ad23f80 100644
--- a/arch/tile/include/asm/Kbuild
+++ b/arch/tile/include/asm/Kbuild
@@ -11,12 +11,13 @@ generic-y += errno.h
11generic-y += exec.h 11generic-y += exec.h
12generic-y += fb.h 12generic-y += fb.h
13generic-y += fcntl.h 13generic-y += fcntl.h
14generic-y += hw_irq.h
14generic-y += ioctl.h 15generic-y += ioctl.h
15generic-y += ioctls.h 16generic-y += ioctls.h
16generic-y += ipcbuf.h 17generic-y += ipcbuf.h
17generic-y += irq_regs.h 18generic-y += irq_regs.h
18generic-y += kdebug.h
19generic-y += local.h 19generic-y += local.h
20generic-y += local64.h
20generic-y += msgbuf.h 21generic-y += msgbuf.h
21generic-y += mutex.h 22generic-y += mutex.h
22generic-y += param.h 23generic-y += param.h
diff --git a/arch/tile/include/asm/atomic.h b/arch/tile/include/asm/atomic.h
index e71387ab20ca..d385eaadece7 100644
--- a/arch/tile/include/asm/atomic.h
+++ b/arch/tile/include/asm/atomic.h
@@ -114,6 +114,32 @@ static inline int atomic_read(const atomic_t *v)
114#define atomic_inc_and_test(v) (atomic_inc_return(v) == 0) 114#define atomic_inc_and_test(v) (atomic_inc_return(v) == 0)
115 115
116/** 116/**
117 * atomic_xchg - atomically exchange contents of memory with a new value
118 * @v: pointer of type atomic_t
119 * @i: integer value to store in memory
120 *
121 * Atomically sets @v to @i and returns old @v
122 */
123static inline int atomic_xchg(atomic_t *v, int n)
124{
125 return xchg(&v->counter, n);
126}
127
128/**
129 * atomic_cmpxchg - atomically exchange contents of memory if it matches
130 * @v: pointer of type atomic_t
131 * @o: old value that memory should have
132 * @n: new value to write to memory if it matches
133 *
134 * Atomically checks if @v holds @o and replaces it with @n if so.
135 * Returns the old value at @v.
136 */
137static inline int atomic_cmpxchg(atomic_t *v, int o, int n)
138{
139 return cmpxchg(&v->counter, o, n);
140}
141
142/**
117 * atomic_add_negative - add and test if negative 143 * atomic_add_negative - add and test if negative
118 * @v: pointer of type atomic_t 144 * @v: pointer of type atomic_t
119 * @i: integer value to add 145 * @i: integer value to add
@@ -133,6 +159,32 @@ static inline int atomic_read(const atomic_t *v)
133 159
134#ifndef __ASSEMBLY__ 160#ifndef __ASSEMBLY__
135 161
162/**
163 * atomic64_xchg - atomically exchange contents of memory with a new value
164 * @v: pointer of type atomic64_t
165 * @i: integer value to store in memory
166 *
167 * Atomically sets @v to @i and returns old @v
168 */
169static inline u64 atomic64_xchg(atomic64_t *v, u64 n)
170{
171 return xchg64(&v->counter, n);
172}
173
174/**
175 * atomic64_cmpxchg - atomically exchange contents of memory if it matches
176 * @v: pointer of type atomic64_t
177 * @o: old value that memory should have
178 * @n: new value to write to memory if it matches
179 *
180 * Atomically checks if @v holds @o and replaces it with @n if so.
181 * Returns the old value at @v.
182 */
183static inline u64 atomic64_cmpxchg(atomic64_t *v, u64 o, u64 n)
184{
185 return cmpxchg64(&v->counter, o, n);
186}
187
136static inline long long atomic64_dec_if_positive(atomic64_t *v) 188static inline long long atomic64_dec_if_positive(atomic64_t *v)
137{ 189{
138 long long c, old, dec; 190 long long c, old, dec;
diff --git a/arch/tile/include/asm/atomic_32.h b/arch/tile/include/asm/atomic_32.h
index e7fb5cfb9597..0d0395b1b152 100644
--- a/arch/tile/include/asm/atomic_32.h
+++ b/arch/tile/include/asm/atomic_32.h
@@ -22,40 +22,6 @@
22 22
23#ifndef __ASSEMBLY__ 23#ifndef __ASSEMBLY__
24 24
25/* Tile-specific routines to support <linux/atomic.h>. */
26int _atomic_xchg(atomic_t *v, int n);
27int _atomic_xchg_add(atomic_t *v, int i);
28int _atomic_xchg_add_unless(atomic_t *v, int a, int u);
29int _atomic_cmpxchg(atomic_t *v, int o, int n);
30
31/**
32 * atomic_xchg - atomically exchange contents of memory with a new value
33 * @v: pointer of type atomic_t
34 * @i: integer value to store in memory
35 *
36 * Atomically sets @v to @i and returns old @v
37 */
38static inline int atomic_xchg(atomic_t *v, int n)
39{
40 smp_mb(); /* barrier for proper semantics */
41 return _atomic_xchg(v, n);
42}
43
44/**
45 * atomic_cmpxchg - atomically exchange contents of memory if it matches
46 * @v: pointer of type atomic_t
47 * @o: old value that memory should have
48 * @n: new value to write to memory if it matches
49 *
50 * Atomically checks if @v holds @o and replaces it with @n if so.
51 * Returns the old value at @v.
52 */
53static inline int atomic_cmpxchg(atomic_t *v, int o, int n)
54{
55 smp_mb(); /* barrier for proper semantics */
56 return _atomic_cmpxchg(v, o, n);
57}
58
59/** 25/**
60 * atomic_add - add integer to atomic variable 26 * atomic_add - add integer to atomic variable
61 * @i: integer value to add 27 * @i: integer value to add
@@ -65,7 +31,7 @@ static inline int atomic_cmpxchg(atomic_t *v, int o, int n)
65 */ 31 */
66static inline void atomic_add(int i, atomic_t *v) 32static inline void atomic_add(int i, atomic_t *v)
67{ 33{
68 _atomic_xchg_add(v, i); 34 _atomic_xchg_add(&v->counter, i);
69} 35}
70 36
71/** 37/**
@@ -78,7 +44,7 @@ static inline void atomic_add(int i, atomic_t *v)
78static inline int atomic_add_return(int i, atomic_t *v) 44static inline int atomic_add_return(int i, atomic_t *v)
79{ 45{
80 smp_mb(); /* barrier for proper semantics */ 46 smp_mb(); /* barrier for proper semantics */
81 return _atomic_xchg_add(v, i) + i; 47 return _atomic_xchg_add(&v->counter, i) + i;
82} 48}
83 49
84/** 50/**
@@ -93,7 +59,7 @@ static inline int atomic_add_return(int i, atomic_t *v)
93static inline int __atomic_add_unless(atomic_t *v, int a, int u) 59static inline int __atomic_add_unless(atomic_t *v, int a, int u)
94{ 60{
95 smp_mb(); /* barrier for proper semantics */ 61 smp_mb(); /* barrier for proper semantics */
96 return _atomic_xchg_add_unless(v, a, u); 62 return _atomic_xchg_add_unless(&v->counter, a, u);
97} 63}
98 64
99/** 65/**
@@ -108,7 +74,7 @@ static inline int __atomic_add_unless(atomic_t *v, int a, int u)
108 */ 74 */
109static inline void atomic_set(atomic_t *v, int n) 75static inline void atomic_set(atomic_t *v, int n)
110{ 76{
111 _atomic_xchg(v, n); 77 _atomic_xchg(&v->counter, n);
112} 78}
113 79
114/* A 64bit atomic type */ 80/* A 64bit atomic type */
@@ -119,11 +85,6 @@ typedef struct {
119 85
120#define ATOMIC64_INIT(val) { (val) } 86#define ATOMIC64_INIT(val) { (val) }
121 87
122u64 _atomic64_xchg(atomic64_t *v, u64 n);
123u64 _atomic64_xchg_add(atomic64_t *v, u64 i);
124u64 _atomic64_xchg_add_unless(atomic64_t *v, u64 a, u64 u);
125u64 _atomic64_cmpxchg(atomic64_t *v, u64 o, u64 n);
126
127/** 88/**
128 * atomic64_read - read atomic variable 89 * atomic64_read - read atomic variable
129 * @v: pointer of type atomic64_t 90 * @v: pointer of type atomic64_t
@@ -137,35 +98,7 @@ static inline u64 atomic64_read(const atomic64_t *v)
137 * Casting away const is safe since the atomic support routines 98 * Casting away const is safe since the atomic support routines
138 * do not write to memory if the value has not been modified. 99 * do not write to memory if the value has not been modified.
139 */ 100 */
140 return _atomic64_xchg_add((atomic64_t *)v, 0); 101 return _atomic64_xchg_add((u64 *)&v->counter, 0);
141}
142
143/**
144 * atomic64_xchg - atomically exchange contents of memory with a new value
145 * @v: pointer of type atomic64_t
146 * @i: integer value to store in memory
147 *
148 * Atomically sets @v to @i and returns old @v
149 */
150static inline u64 atomic64_xchg(atomic64_t *v, u64 n)
151{
152 smp_mb(); /* barrier for proper semantics */
153 return _atomic64_xchg(v, n);
154}
155
156/**
157 * atomic64_cmpxchg - atomically exchange contents of memory if it matches
158 * @v: pointer of type atomic64_t
159 * @o: old value that memory should have
160 * @n: new value to write to memory if it matches
161 *
162 * Atomically checks if @v holds @o and replaces it with @n if so.
163 * Returns the old value at @v.
164 */
165static inline u64 atomic64_cmpxchg(atomic64_t *v, u64 o, u64 n)
166{
167 smp_mb(); /* barrier for proper semantics */
168 return _atomic64_cmpxchg(v, o, n);
169} 102}
170 103
171/** 104/**
@@ -177,7 +110,7 @@ static inline u64 atomic64_cmpxchg(atomic64_t *v, u64 o, u64 n)
177 */ 110 */
178static inline void atomic64_add(u64 i, atomic64_t *v) 111static inline void atomic64_add(u64 i, atomic64_t *v)
179{ 112{
180 _atomic64_xchg_add(v, i); 113 _atomic64_xchg_add(&v->counter, i);
181} 114}
182 115
183/** 116/**
@@ -190,7 +123,7 @@ static inline void atomic64_add(u64 i, atomic64_t *v)
190static inline u64 atomic64_add_return(u64 i, atomic64_t *v) 123static inline u64 atomic64_add_return(u64 i, atomic64_t *v)
191{ 124{
192 smp_mb(); /* barrier for proper semantics */ 125 smp_mb(); /* barrier for proper semantics */
193 return _atomic64_xchg_add(v, i) + i; 126 return _atomic64_xchg_add(&v->counter, i) + i;
194} 127}
195 128
196/** 129/**
@@ -205,7 +138,7 @@ static inline u64 atomic64_add_return(u64 i, atomic64_t *v)
205static inline u64 atomic64_add_unless(atomic64_t *v, u64 a, u64 u) 138static inline u64 atomic64_add_unless(atomic64_t *v, u64 a, u64 u)
206{ 139{
207 smp_mb(); /* barrier for proper semantics */ 140 smp_mb(); /* barrier for proper semantics */
208 return _atomic64_xchg_add_unless(v, a, u) != u; 141 return _atomic64_xchg_add_unless(&v->counter, a, u) != u;
209} 142}
210 143
211/** 144/**
@@ -220,7 +153,7 @@ static inline u64 atomic64_add_unless(atomic64_t *v, u64 a, u64 u)
220 */ 153 */
221static inline void atomic64_set(atomic64_t *v, u64 n) 154static inline void atomic64_set(atomic64_t *v, u64 n)
222{ 155{
223 _atomic64_xchg(v, n); 156 _atomic64_xchg(&v->counter, n);
224} 157}
225 158
226#define atomic64_add_negative(a, v) (atomic64_add_return((a), (v)) < 0) 159#define atomic64_add_negative(a, v) (atomic64_add_return((a), (v)) < 0)
@@ -252,21 +185,6 @@ static inline void atomic64_set(atomic64_t *v, u64 n)
252 * Internal definitions only beyond this point. 185 * Internal definitions only beyond this point.
253 */ 186 */
254 187
255#define ATOMIC_LOCKS_FOUND_VIA_TABLE() \
256 (!CHIP_HAS_CBOX_HOME_MAP() && defined(CONFIG_SMP))
257
258#if ATOMIC_LOCKS_FOUND_VIA_TABLE()
259
260/* Number of entries in atomic_lock_ptr[]. */
261#define ATOMIC_HASH_L1_SHIFT 6
262#define ATOMIC_HASH_L1_SIZE (1 << ATOMIC_HASH_L1_SHIFT)
263
264/* Number of locks in each struct pointed to by atomic_lock_ptr[]. */
265#define ATOMIC_HASH_L2_SHIFT (CHIP_L2_LOG_LINE_SIZE() - 2)
266#define ATOMIC_HASH_L2_SIZE (1 << ATOMIC_HASH_L2_SHIFT)
267
268#else /* ATOMIC_LOCKS_FOUND_VIA_TABLE() */
269
270/* 188/*
271 * Number of atomic locks in atomic_locks[]. Must be a power of two. 189 * Number of atomic locks in atomic_locks[]. Must be a power of two.
272 * There is no reason for more than PAGE_SIZE / 8 entries, since that 190 * There is no reason for more than PAGE_SIZE / 8 entries, since that
@@ -281,8 +199,6 @@ static inline void atomic64_set(atomic64_t *v, u64 n)
281extern int atomic_locks[]; 199extern int atomic_locks[];
282#endif 200#endif
283 201
284#endif /* ATOMIC_LOCKS_FOUND_VIA_TABLE() */
285
286/* 202/*
287 * All the code that may fault while holding an atomic lock must 203 * All the code that may fault while holding an atomic lock must
288 * place the pointer to the lock in ATOMIC_LOCK_REG so the fault code 204 * place the pointer to the lock in ATOMIC_LOCK_REG so the fault code
diff --git a/arch/tile/include/asm/atomic_64.h b/arch/tile/include/asm/atomic_64.h
index f4500c688ffa..ad220eed05fc 100644
--- a/arch/tile/include/asm/atomic_64.h
+++ b/arch/tile/include/asm/atomic_64.h
@@ -32,25 +32,6 @@
32 * on any routine which updates memory and returns a value. 32 * on any routine which updates memory and returns a value.
33 */ 33 */
34 34
35static inline int atomic_cmpxchg(atomic_t *v, int o, int n)
36{
37 int val;
38 __insn_mtspr(SPR_CMPEXCH_VALUE, o);
39 smp_mb(); /* barrier for proper semantics */
40 val = __insn_cmpexch4((void *)&v->counter, n);
41 smp_mb(); /* barrier for proper semantics */
42 return val;
43}
44
45static inline int atomic_xchg(atomic_t *v, int n)
46{
47 int val;
48 smp_mb(); /* barrier for proper semantics */
49 val = __insn_exch4((void *)&v->counter, n);
50 smp_mb(); /* barrier for proper semantics */
51 return val;
52}
53
54static inline void atomic_add(int i, atomic_t *v) 35static inline void atomic_add(int i, atomic_t *v)
55{ 36{
56 __insn_fetchadd4((void *)&v->counter, i); 37 __insn_fetchadd4((void *)&v->counter, i);
@@ -72,7 +53,7 @@ static inline int __atomic_add_unless(atomic_t *v, int a, int u)
72 if (oldval == u) 53 if (oldval == u)
73 break; 54 break;
74 guess = oldval; 55 guess = oldval;
75 oldval = atomic_cmpxchg(v, guess, guess + a); 56 oldval = cmpxchg(&v->counter, guess, guess + a);
76 } while (guess != oldval); 57 } while (guess != oldval);
77 return oldval; 58 return oldval;
78} 59}
@@ -84,25 +65,6 @@ static inline int __atomic_add_unless(atomic_t *v, int a, int u)
84#define atomic64_read(v) ((v)->counter) 65#define atomic64_read(v) ((v)->counter)
85#define atomic64_set(v, i) ((v)->counter = (i)) 66#define atomic64_set(v, i) ((v)->counter = (i))
86 67
87static inline long atomic64_cmpxchg(atomic64_t *v, long o, long n)
88{
89 long val;
90 smp_mb(); /* barrier for proper semantics */
91 __insn_mtspr(SPR_CMPEXCH_VALUE, o);
92 val = __insn_cmpexch((void *)&v->counter, n);
93 smp_mb(); /* barrier for proper semantics */
94 return val;
95}
96
97static inline long atomic64_xchg(atomic64_t *v, long n)
98{
99 long val;
100 smp_mb(); /* barrier for proper semantics */
101 val = __insn_exch((void *)&v->counter, n);
102 smp_mb(); /* barrier for proper semantics */
103 return val;
104}
105
106static inline void atomic64_add(long i, atomic64_t *v) 68static inline void atomic64_add(long i, atomic64_t *v)
107{ 69{
108 __insn_fetchadd((void *)&v->counter, i); 70 __insn_fetchadd((void *)&v->counter, i);
@@ -124,7 +86,7 @@ static inline long atomic64_add_unless(atomic64_t *v, long a, long u)
124 if (oldval == u) 86 if (oldval == u)
125 break; 87 break;
126 guess = oldval; 88 guess = oldval;
127 oldval = atomic64_cmpxchg(v, guess, guess + a); 89 oldval = cmpxchg(&v->counter, guess, guess + a);
128 } while (guess != oldval); 90 } while (guess != oldval);
129 return oldval != u; 91 return oldval != u;
130} 92}
diff --git a/arch/tile/include/asm/barrier.h b/arch/tile/include/asm/barrier.h
index 990a217a0b72..a9a73da5865d 100644
--- a/arch/tile/include/asm/barrier.h
+++ b/arch/tile/include/asm/barrier.h
@@ -77,7 +77,6 @@
77 77
78#define __sync() __insn_mf() 78#define __sync() __insn_mf()
79 79
80#if !CHIP_HAS_MF_WAITS_FOR_VICTIMS()
81#include <hv/syscall_public.h> 80#include <hv/syscall_public.h>
82/* 81/*
83 * Issue an uncacheable load to each memory controller, then 82 * Issue an uncacheable load to each memory controller, then
@@ -96,7 +95,6 @@ static inline void __mb_incoherent(void)
96 "r20", "r21", "r22", "r23", "r24", 95 "r20", "r21", "r22", "r23", "r24",
97 "r25", "r26", "r27", "r28", "r29"); 96 "r25", "r26", "r27", "r28", "r29");
98} 97}
99#endif
100 98
101/* Fence to guarantee visibility of stores to incoherent memory. */ 99/* Fence to guarantee visibility of stores to incoherent memory. */
102static inline void 100static inline void
@@ -104,7 +102,6 @@ mb_incoherent(void)
104{ 102{
105 __insn_mf(); 103 __insn_mf();
106 104
107#if !CHIP_HAS_MF_WAITS_FOR_VICTIMS()
108 { 105 {
109#if CHIP_HAS_TILE_WRITE_PENDING() 106#if CHIP_HAS_TILE_WRITE_PENDING()
110 const unsigned long WRITE_TIMEOUT_CYCLES = 400; 107 const unsigned long WRITE_TIMEOUT_CYCLES = 400;
@@ -116,7 +113,6 @@ mb_incoherent(void)
116#endif /* CHIP_HAS_TILE_WRITE_PENDING() */ 113#endif /* CHIP_HAS_TILE_WRITE_PENDING() */
117 (void) __mb_incoherent(); 114 (void) __mb_incoherent();
118 } 115 }
119#endif /* CHIP_HAS_MF_WAITS_FOR_VICTIMS() */
120} 116}
121 117
122#define fast_wmb() __sync() 118#define fast_wmb() __sync()
diff --git a/arch/tile/include/asm/bitops.h b/arch/tile/include/asm/bitops.h
index bd186c4eaa50..d5a206865036 100644
--- a/arch/tile/include/asm/bitops.h
+++ b/arch/tile/include/asm/bitops.h
@@ -29,17 +29,6 @@
29#endif 29#endif
30 30
31/** 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 32 * ffz - find first zero bit in word
44 * @word: The word to search 33 * @word: The word to search
45 * 34 *
@@ -50,33 +39,6 @@ static inline unsigned long ffz(unsigned long word)
50 return __builtin_ctzl(~word); 39 return __builtin_ctzl(~word);
51} 40}
52 41
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
80static inline int fls64(__u64 w) 42static inline int fls64(__u64 w)
81{ 43{
82 return (sizeof(__u64) * 8) - __builtin_clzll(w); 44 return (sizeof(__u64) * 8) - __builtin_clzll(w);
@@ -118,6 +80,9 @@ static inline unsigned long __arch_hweight64(__u64 w)
118 return __builtin_popcountll(w); 80 return __builtin_popcountll(w);
119} 81}
120 82
83#include <asm-generic/bitops/builtin-__ffs.h>
84#include <asm-generic/bitops/builtin-__fls.h>
85#include <asm-generic/bitops/builtin-ffs.h>
121#include <asm-generic/bitops/const_hweight.h> 86#include <asm-generic/bitops/const_hweight.h>
122#include <asm-generic/bitops/lock.h> 87#include <asm-generic/bitops/lock.h>
123#include <asm-generic/bitops/find.h> 88#include <asm-generic/bitops/find.h>
diff --git a/arch/tile/include/asm/bitops_32.h b/arch/tile/include/asm/bitops_32.h
index ddc4c1efde43..386865ad2f55 100644
--- a/arch/tile/include/asm/bitops_32.h
+++ b/arch/tile/include/asm/bitops_32.h
@@ -16,7 +16,7 @@
16#define _ASM_TILE_BITOPS_32_H 16#define _ASM_TILE_BITOPS_32_H
17 17
18#include <linux/compiler.h> 18#include <linux/compiler.h>
19#include <linux/atomic.h> 19#include <asm/barrier.h>
20 20
21/* Tile-specific routines to support <asm/bitops.h>. */ 21/* Tile-specific routines to support <asm/bitops.h>. */
22unsigned long _atomic_or(volatile unsigned long *p, unsigned long mask); 22unsigned long _atomic_or(volatile unsigned long *p, unsigned long mask);
diff --git a/arch/tile/include/asm/bitops_64.h b/arch/tile/include/asm/bitops_64.h
index 60b87ee54fb8..ad34cd056085 100644
--- a/arch/tile/include/asm/bitops_64.h
+++ b/arch/tile/include/asm/bitops_64.h
@@ -16,7 +16,7 @@
16#define _ASM_TILE_BITOPS_64_H 16#define _ASM_TILE_BITOPS_64_H
17 17
18#include <linux/compiler.h> 18#include <linux/compiler.h>
19#include <linux/atomic.h> 19#include <asm/cmpxchg.h>
20 20
21/* See <asm/bitops.h> for API comments. */ 21/* See <asm/bitops.h> for API comments. */
22 22
@@ -44,8 +44,7 @@ static inline void change_bit(unsigned nr, volatile unsigned long *addr)
44 oldval = *addr; 44 oldval = *addr;
45 do { 45 do {
46 guess = oldval; 46 guess = oldval;
47 oldval = atomic64_cmpxchg((atomic64_t *)addr, 47 oldval = cmpxchg(addr, guess, guess ^ mask);
48 guess, guess ^ mask);
49 } while (guess != oldval); 48 } while (guess != oldval);
50} 49}
51 50
@@ -90,8 +89,7 @@ static inline int test_and_change_bit(unsigned nr,
90 oldval = *addr; 89 oldval = *addr;
91 do { 90 do {
92 guess = oldval; 91 guess = oldval;
93 oldval = atomic64_cmpxchg((atomic64_t *)addr, 92 oldval = cmpxchg(addr, guess, guess ^ mask);
94 guess, guess ^ mask);
95 } while (guess != oldval); 93 } while (guess != oldval);
96 return (oldval & mask) != 0; 94 return (oldval & mask) != 0;
97} 95}
diff --git a/arch/tile/include/asm/cache.h b/arch/tile/include/asm/cache.h
index a9a529964e07..6160761d5f61 100644
--- a/arch/tile/include/asm/cache.h
+++ b/arch/tile/include/asm/cache.h
@@ -49,9 +49,16 @@
49#define __read_mostly __attribute__((__section__(".data..read_mostly"))) 49#define __read_mostly __attribute__((__section__(".data..read_mostly")))
50 50
51/* 51/*
52 * Attribute for data that is kept read/write coherent until the end of 52 * Originally we used small TLB pages for kernel data and grouped some
53 * initialization, then bumped to read/only incoherent for performance. 53 * things together as "write once", enforcing the property at the end
54 * of initialization by making those pages read-only and non-coherent.
55 * This allowed better cache utilization since cache inclusion did not
56 * need to be maintained. However, to do this requires an extra TLB
57 * entry, which on balance is more of a performance hit than the
58 * non-coherence is a performance gain, so we now just make "read
59 * mostly" and "write once" be synonyms. We keep the attribute
60 * separate in case we change our minds at a future date.
54 */ 61 */
55#define __write_once __attribute__((__section__(".w1data"))) 62#define __write_once __read_mostly
56 63
57#endif /* _ASM_TILE_CACHE_H */ 64#endif /* _ASM_TILE_CACHE_H */
diff --git a/arch/tile/include/asm/cacheflush.h b/arch/tile/include/asm/cacheflush.h
index 0fc63c488edf..92ee4c8a4f76 100644
--- a/arch/tile/include/asm/cacheflush.h
+++ b/arch/tile/include/asm/cacheflush.h
@@ -75,23 +75,6 @@ static inline void copy_to_user_page(struct vm_area_struct *vma,
75#define copy_from_user_page(vma, page, vaddr, dst, src, len) \ 75#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
76 memcpy((dst), (src), (len)) 76 memcpy((dst), (src), (len))
77 77
78/*
79 * Invalidate a VA range; pads to L2 cacheline boundaries.
80 *
81 * Note that on TILE64, __inv_buffer() actually flushes modified
82 * cache lines in addition to invalidating them, i.e., it's the
83 * same as __finv_buffer().
84 */
85static inline void __inv_buffer(void *buffer, size_t size)
86{
87 char *next = (char *)((long)buffer & -L2_CACHE_BYTES);
88 char *finish = (char *)L2_CACHE_ALIGN((long)buffer + size);
89 while (next < finish) {
90 __insn_inv(next);
91 next += CHIP_INV_STRIDE();
92 }
93}
94
95/* Flush a VA range; pads to L2 cacheline boundaries. */ 78/* Flush a VA range; pads to L2 cacheline boundaries. */
96static inline void __flush_buffer(void *buffer, size_t size) 79static inline void __flush_buffer(void *buffer, size_t size)
97{ 80{
@@ -115,13 +98,6 @@ static inline void __finv_buffer(void *buffer, size_t size)
115} 98}
116 99
117 100
118/* Invalidate a VA range and wait for it to be complete. */
119static inline void inv_buffer(void *buffer, size_t size)
120{
121 __inv_buffer(buffer, size);
122 mb();
123}
124
125/* 101/*
126 * Flush a locally-homecached VA range and wait for the evicted 102 * Flush a locally-homecached VA range and wait for the evicted
127 * cachelines to hit memory. 103 * cachelines to hit memory.
@@ -142,6 +118,26 @@ static inline void finv_buffer_local(void *buffer, size_t size)
142 mb_incoherent(); 118 mb_incoherent();
143} 119}
144 120
121#ifdef __tilepro__
122/* Invalidate a VA range; pads to L2 cacheline boundaries. */
123static inline void __inv_buffer(void *buffer, size_t size)
124{
125 char *next = (char *)((long)buffer & -L2_CACHE_BYTES);
126 char *finish = (char *)L2_CACHE_ALIGN((long)buffer + size);
127 while (next < finish) {
128 __insn_inv(next);
129 next += CHIP_INV_STRIDE();
130 }
131}
132
133/* Invalidate a VA range and wait for it to be complete. */
134static inline void inv_buffer(void *buffer, size_t size)
135{
136 __inv_buffer(buffer, size);
137 mb();
138}
139#endif
140
145/* 141/*
146 * Flush and invalidate a VA range that is homed remotely, waiting 142 * Flush and invalidate a VA range that is homed remotely, waiting
147 * until the memory controller holds the flushed values. If "hfh" is 143 * until the memory controller holds the flushed values. If "hfh" is
diff --git a/arch/tile/include/asm/cmpxchg.h b/arch/tile/include/asm/cmpxchg.h
index 276f067e3640..4001d5eab4bb 100644
--- a/arch/tile/include/asm/cmpxchg.h
+++ b/arch/tile/include/asm/cmpxchg.h
@@ -20,53 +20,108 @@
20 20
21#ifndef __ASSEMBLY__ 21#ifndef __ASSEMBLY__
22 22
23/* Nonexistent functions intended to cause link errors. */ 23#include <asm/barrier.h>
24extern unsigned long __xchg_called_with_bad_pointer(void);
25extern unsigned long __cmpxchg_called_with_bad_pointer(void);
26 24
27#define xchg(ptr, x) \ 25/* Nonexistent functions intended to cause compile errors. */
26extern void __xchg_called_with_bad_pointer(void)
27 __compiletime_error("Bad argument size for xchg");
28extern void __cmpxchg_called_with_bad_pointer(void)
29 __compiletime_error("Bad argument size for cmpxchg");
30
31#ifndef __tilegx__
32
33/* Note the _atomic_xxx() routines include a final mb(). */
34int _atomic_xchg(int *ptr, int n);
35int _atomic_xchg_add(int *v, int i);
36int _atomic_xchg_add_unless(int *v, int a, int u);
37int _atomic_cmpxchg(int *ptr, int o, int n);
38u64 _atomic64_xchg(u64 *v, u64 n);
39u64 _atomic64_xchg_add(u64 *v, u64 i);
40u64 _atomic64_xchg_add_unless(u64 *v, u64 a, u64 u);
41u64 _atomic64_cmpxchg(u64 *v, u64 o, u64 n);
42
43#define xchg(ptr, n) \
44 ({ \
45 if (sizeof(*(ptr)) != 4) \
46 __xchg_called_with_bad_pointer(); \
47 smp_mb(); \
48 (typeof(*(ptr)))_atomic_xchg((int *)(ptr), (int)(n)); \
49 })
50
51#define cmpxchg(ptr, o, n) \
52 ({ \
53 if (sizeof(*(ptr)) != 4) \
54 __cmpxchg_called_with_bad_pointer(); \
55 smp_mb(); \
56 (typeof(*(ptr)))_atomic_cmpxchg((int *)ptr, (int)o, (int)n); \
57 })
58
59#define xchg64(ptr, n) \
60 ({ \
61 if (sizeof(*(ptr)) != 8) \
62 __xchg_called_with_bad_pointer(); \
63 smp_mb(); \
64 (typeof(*(ptr)))_atomic64_xchg((u64 *)(ptr), (u64)(n)); \
65 })
66
67#define cmpxchg64(ptr, o, n) \
68 ({ \
69 if (sizeof(*(ptr)) != 8) \
70 __cmpxchg_called_with_bad_pointer(); \
71 smp_mb(); \
72 (typeof(*(ptr)))_atomic64_cmpxchg((u64 *)ptr, (u64)o, (u64)n); \
73 })
74
75#else
76
77#define xchg(ptr, n) \
28 ({ \ 78 ({ \
29 typeof(*(ptr)) __x; \ 79 typeof(*(ptr)) __x; \
80 smp_mb(); \
30 switch (sizeof(*(ptr))) { \ 81 switch (sizeof(*(ptr))) { \
31 case 4: \ 82 case 4: \
32 __x = (typeof(__x))(typeof(__x-__x))atomic_xchg( \ 83 __x = (typeof(__x))(unsigned long) \
33 (atomic_t *)(ptr), \ 84 __insn_exch4((ptr), (u32)(unsigned long)(n)); \
34 (u32)(typeof((x)-(x)))(x)); \
35 break; \ 85 break; \
36 case 8: \ 86 case 8: \
37 __x = (typeof(__x))(typeof(__x-__x))atomic64_xchg( \ 87 __x = (typeof(__x)) \
38 (atomic64_t *)(ptr), \ 88 __insn_exch((ptr), (unsigned long)(n)); \
39 (u64)(typeof((x)-(x)))(x)); \
40 break; \ 89 break; \
41 default: \ 90 default: \
42 __xchg_called_with_bad_pointer(); \ 91 __xchg_called_with_bad_pointer(); \
92 break; \
43 } \ 93 } \
94 smp_mb(); \
44 __x; \ 95 __x; \
45 }) 96 })
46 97
47#define cmpxchg(ptr, o, n) \ 98#define cmpxchg(ptr, o, n) \
48 ({ \ 99 ({ \
49 typeof(*(ptr)) __x; \ 100 typeof(*(ptr)) __x; \
101 __insn_mtspr(SPR_CMPEXCH_VALUE, (unsigned long)(o)); \
102 smp_mb(); \
50 switch (sizeof(*(ptr))) { \ 103 switch (sizeof(*(ptr))) { \
51 case 4: \ 104 case 4: \
52 __x = (typeof(__x))(typeof(__x-__x))atomic_cmpxchg( \ 105 __x = (typeof(__x))(unsigned long) \
53 (atomic_t *)(ptr), \ 106 __insn_cmpexch4((ptr), (u32)(unsigned long)(n)); \
54 (u32)(typeof((o)-(o)))(o), \
55 (u32)(typeof((n)-(n)))(n)); \
56 break; \ 107 break; \
57 case 8: \ 108 case 8: \
58 __x = (typeof(__x))(typeof(__x-__x))atomic64_cmpxchg( \ 109 __x = (typeof(__x))__insn_cmpexch((ptr), (u64)(n)); \
59 (atomic64_t *)(ptr), \
60 (u64)(typeof((o)-(o)))(o), \
61 (u64)(typeof((n)-(n)))(n)); \
62 break; \ 110 break; \
63 default: \ 111 default: \
64 __cmpxchg_called_with_bad_pointer(); \ 112 __cmpxchg_called_with_bad_pointer(); \
113 break; \
65 } \ 114 } \
115 smp_mb(); \
66 __x; \ 116 __x; \
67 }) 117 })
68 118
69#define tas(ptr) (xchg((ptr), 1)) 119#define xchg64 xchg
120#define cmpxchg64 cmpxchg
121
122#endif
123
124#define tas(ptr) xchg((ptr), 1)
70 125
71#endif /* __ASSEMBLY__ */ 126#endif /* __ASSEMBLY__ */
72 127
diff --git a/arch/tile/include/asm/device.h b/arch/tile/include/asm/device.h
index 5182705bd056..6ab8bf146d4c 100644
--- a/arch/tile/include/asm/device.h
+++ b/arch/tile/include/asm/device.h
@@ -23,7 +23,10 @@ struct dev_archdata {
23 /* Offset of the DMA address from the PA. */ 23 /* Offset of the DMA address from the PA. */
24 dma_addr_t dma_offset; 24 dma_addr_t dma_offset;
25 25
26 /* Highest DMA address that can be generated by this device. */ 26 /*
27 * Highest DMA address that can be generated by devices that
28 * have limited DMA capability, i.e. non 64-bit capable.
29 */
27 dma_addr_t max_direct_dma_addr; 30 dma_addr_t max_direct_dma_addr;
28}; 31};
29 32
diff --git a/arch/tile/include/asm/dma-mapping.h b/arch/tile/include/asm/dma-mapping.h
index f2ff191376b4..1eae359d8315 100644
--- a/arch/tile/include/asm/dma-mapping.h
+++ b/arch/tile/include/asm/dma-mapping.h
@@ -20,9 +20,14 @@
20#include <linux/cache.h> 20#include <linux/cache.h>
21#include <linux/io.h> 21#include <linux/io.h>
22 22
23#ifdef __tilegx__
24#define ARCH_HAS_DMA_GET_REQUIRED_MASK
25#endif
26
23extern struct dma_map_ops *tile_dma_map_ops; 27extern struct dma_map_ops *tile_dma_map_ops;
24extern struct dma_map_ops *gx_pci_dma_map_ops; 28extern struct dma_map_ops *gx_pci_dma_map_ops;
25extern struct dma_map_ops *gx_legacy_pci_dma_map_ops; 29extern struct dma_map_ops *gx_legacy_pci_dma_map_ops;
30extern struct dma_map_ops *gx_hybrid_pci_dma_map_ops;
26 31
27static inline struct dma_map_ops *get_dma_ops(struct device *dev) 32static inline struct dma_map_ops *get_dma_ops(struct device *dev)
28{ 33{
@@ -44,12 +49,12 @@ static inline void set_dma_offset(struct device *dev, dma_addr_t off)
44 49
45static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr) 50static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
46{ 51{
47 return paddr + get_dma_offset(dev); 52 return paddr;
48} 53}
49 54
50static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr) 55static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr)
51{ 56{
52 return daddr - get_dma_offset(dev); 57 return daddr;
53} 58}
54 59
55static inline void dma_mark_clean(void *addr, size_t size) {} 60static inline void dma_mark_clean(void *addr, size_t size) {}
@@ -87,11 +92,19 @@ dma_set_mask(struct device *dev, u64 mask)
87{ 92{
88 struct dma_map_ops *dma_ops = get_dma_ops(dev); 93 struct dma_map_ops *dma_ops = get_dma_ops(dev);
89 94
90 /* Handle legacy PCI devices with limited memory addressability. */ 95 /*
91 if ((dma_ops == gx_pci_dma_map_ops) && (mask <= DMA_BIT_MASK(32))) { 96 * For PCI devices with 64-bit DMA addressing capability, promote
92 set_dma_ops(dev, gx_legacy_pci_dma_map_ops); 97 * the dma_ops to hybrid, with the consistent memory DMA space limited
93 set_dma_offset(dev, 0); 98 * to 32-bit. For 32-bit capable devices, limit the streaming DMA
94 if (mask > dev->archdata.max_direct_dma_addr) 99 * address range to max_direct_dma_addr.
100 */
101 if (dma_ops == gx_pci_dma_map_ops ||
102 dma_ops == gx_hybrid_pci_dma_map_ops ||
103 dma_ops == gx_legacy_pci_dma_map_ops) {
104 if (mask == DMA_BIT_MASK(64) &&
105 dma_ops == gx_legacy_pci_dma_map_ops)
106 set_dma_ops(dev, gx_hybrid_pci_dma_map_ops);
107 else if (mask > dev->archdata.max_direct_dma_addr)
95 mask = dev->archdata.max_direct_dma_addr; 108 mask = dev->archdata.max_direct_dma_addr;
96 } 109 }
97 110
diff --git a/arch/tile/include/asm/elf.h b/arch/tile/include/asm/elf.h
index ff8a93408823..41d9878a9686 100644
--- a/arch/tile/include/asm/elf.h
+++ b/arch/tile/include/asm/elf.h
@@ -30,7 +30,6 @@ typedef unsigned long elf_greg_t;
30#define ELF_NGREG (sizeof(struct pt_regs) / sizeof(elf_greg_t)) 30#define ELF_NGREG (sizeof(struct pt_regs) / sizeof(elf_greg_t))
31typedef elf_greg_t elf_gregset_t[ELF_NGREG]; 31typedef elf_greg_t elf_gregset_t[ELF_NGREG];
32 32
33#define EM_TILE64 187
34#define EM_TILEPRO 188 33#define EM_TILEPRO 188
35#define EM_TILEGX 191 34#define EM_TILEGX 191
36 35
@@ -132,6 +131,15 @@ extern int dump_task_regs(struct task_struct *, elf_gregset_t *);
132struct linux_binprm; 131struct linux_binprm;
133extern int arch_setup_additional_pages(struct linux_binprm *bprm, 132extern int arch_setup_additional_pages(struct linux_binprm *bprm,
134 int executable_stack); 133 int executable_stack);
134#define ARCH_DLINFO \
135do { \
136 NEW_AUX_ENT(AT_SYSINFO_EHDR, VDSO_BASE); \
137} while (0)
138
139struct mm_struct;
140extern unsigned long arch_randomize_brk(struct mm_struct *mm);
141#define arch_randomize_brk arch_randomize_brk
142
135#ifdef CONFIG_COMPAT 143#ifdef CONFIG_COMPAT
136 144
137#define COMPAT_ELF_PLATFORM "tilegx-m32" 145#define COMPAT_ELF_PLATFORM "tilegx-m32"
diff --git a/arch/tile/include/asm/fixmap.h b/arch/tile/include/asm/fixmap.h
index e16dbf929cb5..c6b9c1b38fd1 100644
--- a/arch/tile/include/asm/fixmap.h
+++ b/arch/tile/include/asm/fixmap.h
@@ -78,14 +78,6 @@ enum fixed_addresses {
78#endif 78#endif
79}; 79};
80 80
81extern void __set_fixmap(enum fixed_addresses idx,
82 unsigned long phys, pgprot_t flags);
83
84#define set_fixmap(idx, phys) \
85 __set_fixmap(idx, phys, PAGE_KERNEL)
86#define clear_fixmap(idx) \
87 __set_fixmap(idx, 0, __pgprot(0))
88
89#define __FIXADDR_SIZE (__end_of_permanent_fixed_addresses << PAGE_SHIFT) 81#define __FIXADDR_SIZE (__end_of_permanent_fixed_addresses << PAGE_SHIFT)
90#define __FIXADDR_BOOT_SIZE (__end_of_fixed_addresses << PAGE_SHIFT) 82#define __FIXADDR_BOOT_SIZE (__end_of_fixed_addresses << PAGE_SHIFT)
91#define FIXADDR_START (FIXADDR_TOP + PAGE_SIZE - __FIXADDR_SIZE) 83#define FIXADDR_START (FIXADDR_TOP + PAGE_SIZE - __FIXADDR_SIZE)
diff --git a/arch/tile/include/asm/ftrace.h b/arch/tile/include/asm/ftrace.h
index 461459b06d98..13a9bb81a8ab 100644
--- a/arch/tile/include/asm/ftrace.h
+++ b/arch/tile/include/asm/ftrace.h
@@ -15,6 +15,26 @@
15#ifndef _ASM_TILE_FTRACE_H 15#ifndef _ASM_TILE_FTRACE_H
16#define _ASM_TILE_FTRACE_H 16#define _ASM_TILE_FTRACE_H
17 17
18/* empty */ 18#ifdef CONFIG_FUNCTION_TRACER
19
20#define MCOUNT_ADDR ((unsigned long)(__mcount))
21#define MCOUNT_INSN_SIZE 8 /* sizeof mcount call */
22
23#ifndef __ASSEMBLY__
24extern void __mcount(void);
25
26#ifdef CONFIG_DYNAMIC_FTRACE
27static inline unsigned long ftrace_call_adjust(unsigned long addr)
28{
29 return addr;
30}
31
32struct dyn_arch_ftrace {
33};
34#endif /* CONFIG_DYNAMIC_FTRACE */
35
36#endif /* __ASSEMBLY__ */
37
38#endif /* CONFIG_FUNCTION_TRACER */
19 39
20#endif /* _ASM_TILE_FTRACE_H */ 40#endif /* _ASM_TILE_FTRACE_H */
diff --git a/arch/tile/include/asm/futex.h b/arch/tile/include/asm/futex.h
index 5909ac3d7218..1a6ef1b69cb1 100644
--- a/arch/tile/include/asm/futex.h
+++ b/arch/tile/include/asm/futex.h
@@ -43,6 +43,7 @@
43 ".pushsection .fixup,\"ax\"\n" \ 43 ".pushsection .fixup,\"ax\"\n" \
44 "0: { movei %0, %5; j 9f }\n" \ 44 "0: { movei %0, %5; j 9f }\n" \
45 ".section __ex_table,\"a\"\n" \ 45 ".section __ex_table,\"a\"\n" \
46 ".align 8\n" \
46 ".quad 1b, 0b\n" \ 47 ".quad 1b, 0b\n" \
47 ".popsection\n" \ 48 ".popsection\n" \
48 "9:" \ 49 "9:" \
diff --git a/arch/tile/include/asm/homecache.h b/arch/tile/include/asm/homecache.h
index 7b7771328642..7ddd1b8d6910 100644
--- a/arch/tile/include/asm/homecache.h
+++ b/arch/tile/include/asm/homecache.h
@@ -33,8 +33,7 @@ struct zone;
33 33
34/* 34/*
35 * Is this page immutable (unwritable) and thus able to be cached more 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 36 * widely than would otherwise be possible? This means we have "nc" set.
37 * mark the PTE to cache locally; on tilepro it means we have "nc" set.
38 */ 37 */
39#define PAGE_HOME_IMMUTABLE -2 38#define PAGE_HOME_IMMUTABLE -2
40 39
@@ -44,16 +43,8 @@ struct zone;
44 */ 43 */
45#define PAGE_HOME_INCOHERENT -3 44#define PAGE_HOME_INCOHERENT -3
46 45
47#if CHIP_HAS_CBOX_HOME_MAP()
48/* Home for the page is distributed via hash-for-home. */ 46/* Home for the page is distributed via hash-for-home. */
49#define PAGE_HOME_HASH -4 47#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 48
58/* Support wrapper to use instead of explicit hv_flush_remote(). */ 49/* Support wrapper to use instead of explicit hv_flush_remote(). */
59extern void flush_remote(unsigned long cache_pfn, unsigned long cache_length, 50extern void flush_remote(unsigned long cache_pfn, unsigned long cache_length,
diff --git a/arch/tile/include/asm/io.h b/arch/tile/include/asm/io.h
index 31672918064c..9fe434969fab 100644
--- a/arch/tile/include/asm/io.h
+++ b/arch/tile/include/asm/io.h
@@ -19,7 +19,8 @@
19#include <linux/bug.h> 19#include <linux/bug.h>
20#include <asm/page.h> 20#include <asm/page.h>
21 21
22#define IO_SPACE_LIMIT 0xfffffffful 22/* Maximum PCI I/O space address supported. */
23#define IO_SPACE_LIMIT 0xffffffff
23 24
24/* 25/*
25 * Convert a physical pointer to a virtual kernel pointer for /dev/mem 26 * Convert a physical pointer to a virtual kernel pointer for /dev/mem
@@ -254,7 +255,7 @@ static inline void writeq(u64 val, unsigned long addr)
254 255
255static inline void memset_io(volatile void *dst, int val, size_t len) 256static inline void memset_io(volatile void *dst, int val, size_t len)
256{ 257{
257 int x; 258 size_t x;
258 BUG_ON((unsigned long)dst & 0x3); 259 BUG_ON((unsigned long)dst & 0x3);
259 val = (val & 0xff) * 0x01010101; 260 val = (val & 0xff) * 0x01010101;
260 for (x = 0; x < len; x += 4) 261 for (x = 0; x < len; x += 4)
@@ -264,7 +265,7 @@ static inline void memset_io(volatile void *dst, int val, size_t len)
264static inline void memcpy_fromio(void *dst, const volatile void __iomem *src, 265static inline void memcpy_fromio(void *dst, const volatile void __iomem *src,
265 size_t len) 266 size_t len)
266{ 267{
267 int x; 268 size_t x;
268 BUG_ON((unsigned long)src & 0x3); 269 BUG_ON((unsigned long)src & 0x3);
269 for (x = 0; x < len; x += 4) 270 for (x = 0; x < len; x += 4)
270 *(u32 *)(dst + x) = readl(src + x); 271 *(u32 *)(dst + x) = readl(src + x);
@@ -273,7 +274,7 @@ static inline void memcpy_fromio(void *dst, const volatile void __iomem *src,
273static inline void memcpy_toio(volatile void __iomem *dst, const void *src, 274static inline void memcpy_toio(volatile void __iomem *dst, const void *src,
274 size_t len) 275 size_t len)
275{ 276{
276 int x; 277 size_t x;
277 BUG_ON((unsigned long)dst & 0x3); 278 BUG_ON((unsigned long)dst & 0x3);
278 for (x = 0; x < len; x += 4) 279 for (x = 0; x < len; x += 4)
279 writel(*(u32 *)(src + x), dst + x); 280 writel(*(u32 *)(src + x), dst + x);
@@ -281,8 +282,108 @@ static inline void memcpy_toio(volatile void __iomem *dst, const void *src,
281 282
282#endif 283#endif
283 284
285#if CHIP_HAS_MMIO() && defined(CONFIG_TILE_PCI_IO)
286
287static inline u8 inb(unsigned long addr)
288{
289 return readb((volatile void __iomem *) addr);
290}
291
292static inline u16 inw(unsigned long addr)
293{
294 return readw((volatile void __iomem *) addr);
295}
296
297static inline u32 inl(unsigned long addr)
298{
299 return readl((volatile void __iomem *) addr);
300}
301
302static inline void outb(u8 b, unsigned long addr)
303{
304 writeb(b, (volatile void __iomem *) addr);
305}
306
307static inline void outw(u16 b, unsigned long addr)
308{
309 writew(b, (volatile void __iomem *) addr);
310}
311
312static inline void outl(u32 b, unsigned long addr)
313{
314 writel(b, (volatile void __iomem *) addr);
315}
316
317static inline void insb(unsigned long addr, void *buffer, int count)
318{
319 if (count) {
320 u8 *buf = buffer;
321 do {
322 u8 x = inb(addr);
323 *buf++ = x;
324 } while (--count);
325 }
326}
327
328static inline void insw(unsigned long addr, void *buffer, int count)
329{
330 if (count) {
331 u16 *buf = buffer;
332 do {
333 u16 x = inw(addr);
334 *buf++ = x;
335 } while (--count);
336 }
337}
338
339static inline void insl(unsigned long addr, void *buffer, int count)
340{
341 if (count) {
342 u32 *buf = buffer;
343 do {
344 u32 x = inl(addr);
345 *buf++ = x;
346 } while (--count);
347 }
348}
349
350static inline void outsb(unsigned long addr, const void *buffer, int count)
351{
352 if (count) {
353 const u8 *buf = buffer;
354 do {
355 outb(*buf++, addr);
356 } while (--count);
357 }
358}
359
360static inline void outsw(unsigned long addr, const void *buffer, int count)
361{
362 if (count) {
363 const u16 *buf = buffer;
364 do {
365 outw(*buf++, addr);
366 } while (--count);
367 }
368}
369
370static inline void outsl(unsigned long addr, const void *buffer, int count)
371{
372 if (count) {
373 const u32 *buf = buffer;
374 do {
375 outl(*buf++, addr);
376 } while (--count);
377 }
378}
379
380extern void __iomem *ioport_map(unsigned long port, unsigned int len);
381extern void ioport_unmap(void __iomem *addr);
382
383#else
384
284/* 385/*
285 * The Tile architecture does not support IOPORT, even with PCI. 386 * The TilePro architecture does not support IOPORT, even with PCI.
286 * Unfortunately we can't yet simply not declare these methods, 387 * Unfortunately we can't yet simply not declare these methods,
287 * since some generic code that compiles into the kernel, but 388 * since some generic code that compiles into the kernel, but
288 * we never run, uses them unconditionally. 389 * we never run, uses them unconditionally.
@@ -290,7 +391,12 @@ static inline void memcpy_toio(volatile void __iomem *dst, const void *src,
290 391
291static inline long ioport_panic(void) 392static inline long ioport_panic(void)
292{ 393{
394#ifdef __tilegx__
395 panic("PCI IO space support is disabled. Configure the kernel with"
396 " CONFIG_TILE_PCI_IO to enable it");
397#else
293 panic("inb/outb and friends do not exist on tile"); 398 panic("inb/outb and friends do not exist on tile");
399#endif
294 return 0; 400 return 0;
295} 401}
296 402
@@ -335,13 +441,6 @@ static inline void outl(u32 b, unsigned long addr)
335 ioport_panic(); 441 ioport_panic();
336} 442}
337 443
338#define inb_p(addr) inb(addr)
339#define inw_p(addr) inw(addr)
340#define inl_p(addr) inl(addr)
341#define outb_p(x, addr) outb((x), (addr))
342#define outw_p(x, addr) outw((x), (addr))
343#define outl_p(x, addr) outl((x), (addr))
344
345static inline void insb(unsigned long addr, void *buffer, int count) 444static inline void insb(unsigned long addr, void *buffer, int count)
346{ 445{
347 ioport_panic(); 446 ioport_panic();
@@ -372,6 +471,15 @@ static inline void outsl(unsigned long addr, const void *buffer, int count)
372 ioport_panic(); 471 ioport_panic();
373} 472}
374 473
474#endif /* CHIP_HAS_MMIO() && defined(CONFIG_TILE_PCI_IO) */
475
476#define inb_p(addr) inb(addr)
477#define inw_p(addr) inw(addr)
478#define inl_p(addr) inl(addr)
479#define outb_p(x, addr) outb((x), (addr))
480#define outw_p(x, addr) outw((x), (addr))
481#define outl_p(x, addr) outl((x), (addr))
482
375#define ioread16be(addr) be16_to_cpu(ioread16(addr)) 483#define ioread16be(addr) be16_to_cpu(ioread16(addr))
376#define ioread32be(addr) be32_to_cpu(ioread32(addr)) 484#define ioread32be(addr) be32_to_cpu(ioread32(addr))
377#define iowrite16be(v, addr) iowrite16(be16_to_cpu(v), (addr)) 485#define iowrite16be(v, addr) iowrite16(be16_to_cpu(v), (addr))
diff --git a/arch/tile/include/asm/irqflags.h b/arch/tile/include/asm/irqflags.h
index c96f9bbb760d..71af5747874d 100644
--- a/arch/tile/include/asm/irqflags.h
+++ b/arch/tile/include/asm/irqflags.h
@@ -124,6 +124,12 @@
124DECLARE_PER_CPU(unsigned long long, interrupts_enabled_mask); 124DECLARE_PER_CPU(unsigned long long, interrupts_enabled_mask);
125#define INITIAL_INTERRUPTS_ENABLED (1ULL << INT_MEM_ERROR) 125#define INITIAL_INTERRUPTS_ENABLED (1ULL << INT_MEM_ERROR)
126 126
127#ifdef CONFIG_DEBUG_PREEMPT
128/* Due to inclusion issues, we can't rely on <linux/smp.h> here. */
129extern unsigned int debug_smp_processor_id(void);
130# define smp_processor_id() debug_smp_processor_id()
131#endif
132
127/* Disable interrupts. */ 133/* Disable interrupts. */
128#define arch_local_irq_disable() \ 134#define arch_local_irq_disable() \
129 interrupt_mask_set_mask(LINUX_MASKABLE_INTERRUPTS) 135 interrupt_mask_set_mask(LINUX_MASKABLE_INTERRUPTS)
@@ -132,9 +138,18 @@ DECLARE_PER_CPU(unsigned long long, interrupts_enabled_mask);
132#define arch_local_irq_disable_all() \ 138#define arch_local_irq_disable_all() \
133 interrupt_mask_set_mask(-1ULL) 139 interrupt_mask_set_mask(-1ULL)
134 140
141/*
142 * Read the set of maskable interrupts.
143 * We avoid the preemption warning here via __this_cpu_ptr since even
144 * if irqs are already enabled, it's harmless to read the wrong cpu's
145 * enabled mask.
146 */
147#define arch_local_irqs_enabled() \
148 (*__this_cpu_ptr(&interrupts_enabled_mask))
149
135/* Re-enable all maskable interrupts. */ 150/* Re-enable all maskable interrupts. */
136#define arch_local_irq_enable() \ 151#define arch_local_irq_enable() \
137 interrupt_mask_reset_mask(__get_cpu_var(interrupts_enabled_mask)) 152 interrupt_mask_reset_mask(arch_local_irqs_enabled())
138 153
139/* Disable or enable interrupts based on flag argument. */ 154/* Disable or enable interrupts based on flag argument. */
140#define arch_local_irq_restore(disabled) do { \ 155#define arch_local_irq_restore(disabled) do { \
@@ -161,7 +176,7 @@ DECLARE_PER_CPU(unsigned long long, interrupts_enabled_mask);
161 176
162/* Prevent the given interrupt from being enabled next time we enable irqs. */ 177/* Prevent the given interrupt from being enabled next time we enable irqs. */
163#define arch_local_irq_mask(interrupt) \ 178#define arch_local_irq_mask(interrupt) \
164 (__get_cpu_var(interrupts_enabled_mask) &= ~(1ULL << (interrupt))) 179 this_cpu_and(interrupts_enabled_mask, ~(1ULL << (interrupt)))
165 180
166/* Prevent the given interrupt from being enabled immediately. */ 181/* Prevent the given interrupt from being enabled immediately. */
167#define arch_local_irq_mask_now(interrupt) do { \ 182#define arch_local_irq_mask_now(interrupt) do { \
@@ -171,7 +186,7 @@ DECLARE_PER_CPU(unsigned long long, interrupts_enabled_mask);
171 186
172/* Allow the given interrupt to be enabled next time we enable irqs. */ 187/* Allow the given interrupt to be enabled next time we enable irqs. */
173#define arch_local_irq_unmask(interrupt) \ 188#define arch_local_irq_unmask(interrupt) \
174 (__get_cpu_var(interrupts_enabled_mask) |= (1ULL << (interrupt))) 189 this_cpu_or(interrupts_enabled_mask, (1ULL << (interrupt)))
175 190
176/* Allow the given interrupt to be enabled immediately, if !irqs_disabled. */ 191/* Allow the given interrupt to be enabled immediately, if !irqs_disabled. */
177#define arch_local_irq_unmask_now(interrupt) do { \ 192#define arch_local_irq_unmask_now(interrupt) do { \
diff --git a/arch/tile/include/asm/hw_irq.h b/arch/tile/include/asm/kdebug.h
index 4fac5fbf333e..5bbbfa904c2d 100644
--- a/arch/tile/include/asm/hw_irq.h
+++ b/arch/tile/include/asm/kdebug.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright 2010 Tilera Corporation. All Rights Reserved. 2 * Copyright 2012 Tilera Corporation. All Rights Reserved.
3 * 3 *
4 * This program is free software; you can redistribute it and/or 4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License 5 * modify it under the terms of the GNU General Public License
@@ -12,7 +12,17 @@
12 * more details. 12 * more details.
13 */ 13 */
14 14
15#ifndef _ASM_TILE_HW_IRQ_H 15#ifndef _ASM_TILE_KDEBUG_H
16#define _ASM_TILE_HW_IRQ_H 16#define _ASM_TILE_KDEBUG_H
17 17
18#endif /* _ASM_TILE_HW_IRQ_H */ 18#include <linux/notifier.h>
19
20enum die_val {
21 DIE_OOPS = 1,
22 DIE_BREAK,
23 DIE_SSTEPBP,
24 DIE_PAGE_FAULT,
25 DIE_COMPILED_BPT
26};
27
28#endif /* _ASM_TILE_KDEBUG_H */
diff --git a/arch/tile/include/asm/kgdb.h b/arch/tile/include/asm/kgdb.h
new file mode 100644
index 000000000000..280c181cf0db
--- /dev/null
+++ b/arch/tile/include/asm/kgdb.h
@@ -0,0 +1,71 @@
1/*
2 * Copyright 2013 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-Gx KGDB support.
15 */
16
17#ifndef __TILE_KGDB_H__
18#define __TILE_KGDB_H__
19
20#include <linux/kdebug.h>
21#include <arch/opcode.h>
22
23#define GDB_SIZEOF_REG sizeof(unsigned long)
24
25/*
26 * TILE-Gx gdb is expecting the following register layout:
27 * 56 GPRs(R0 - R52, TP, SP, LR), 8 special GPRs(networks and ZERO),
28 * plus the PC and the faultnum.
29 *
30 * Even though kernel not use the 8 special GPRs, they need to be present
31 * in the registers sent for correct processing in the host-side gdb.
32 *
33 */
34#define DBG_MAX_REG_NUM (56+8+2)
35#define NUMREGBYTES (DBG_MAX_REG_NUM * GDB_SIZEOF_REG)
36
37/*
38 * BUFMAX defines the maximum number of characters in inbound/outbound
39 * buffers at least NUMREGBYTES*2 are needed for register packets,
40 * Longer buffer is needed to list all threads.
41 */
42#define BUFMAX 2048
43
44#define BREAK_INSTR_SIZE TILEGX_BUNDLE_SIZE_IN_BYTES
45
46/*
47 * Require cache flush for set/clear a software breakpoint or write memory.
48 */
49#define CACHE_FLUSH_IS_SAFE 1
50
51/*
52 * The compiled-in breakpoint instruction can be used to "break" into
53 * the debugger via magic system request key (sysrq-G).
54 */
55static tile_bundle_bits compiled_bpt = TILEGX_BPT_BUNDLE | DIE_COMPILED_BPT;
56
57enum tilegx_regnum {
58 TILEGX_PC_REGNUM = TREG_LAST_GPR + 9,
59 TILEGX_FAULTNUM_REGNUM,
60};
61
62/*
63 * Generate a breakpoint exception to "break" into the debugger.
64 */
65static inline void arch_kgdb_breakpoint(void)
66{
67 asm volatile (".quad %0\n\t"
68 ::""(compiled_bpt));
69}
70
71#endif /* __TILE_KGDB_H__ */
diff --git a/arch/tile/include/asm/kprobes.h b/arch/tile/include/asm/kprobes.h
new file mode 100644
index 000000000000..d8f9a83943b1
--- /dev/null
+++ b/arch/tile/include/asm/kprobes.h
@@ -0,0 +1,79 @@
1/*
2 * arch/tile/include/asm/kprobes.h
3 *
4 * Copyright 2012 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
17#ifndef _ASM_TILE_KPROBES_H
18#define _ASM_TILE_KPROBES_H
19
20#include <linux/types.h>
21#include <linux/ptrace.h>
22#include <linux/percpu.h>
23
24#include <arch/opcode.h>
25
26#define __ARCH_WANT_KPROBES_INSN_SLOT
27#define MAX_INSN_SIZE 2
28
29#define kretprobe_blacklist_size 0
30
31typedef tile_bundle_bits kprobe_opcode_t;
32
33#define flush_insn_slot(p) \
34 flush_icache_range((unsigned long)p->addr, \
35 (unsigned long)p->addr + \
36 (MAX_INSN_SIZE * sizeof(kprobe_opcode_t)))
37
38struct kprobe;
39
40/* Architecture specific copy of original instruction. */
41struct arch_specific_insn {
42 kprobe_opcode_t *insn;
43};
44
45struct prev_kprobe {
46 struct kprobe *kp;
47 unsigned long status;
48 unsigned long saved_pc;
49};
50
51#define MAX_JPROBES_STACK_SIZE 128
52#define MAX_JPROBES_STACK_ADDR \
53 (((unsigned long)current_thread_info()) + THREAD_SIZE - 32 \
54 - sizeof(struct pt_regs))
55
56#define MIN_JPROBES_STACK_SIZE(ADDR) \
57 ((((ADDR) + MAX_JPROBES_STACK_SIZE) > MAX_JPROBES_STACK_ADDR) \
58 ? MAX_JPROBES_STACK_ADDR - (ADDR) \
59 : MAX_JPROBES_STACK_SIZE)
60
61/* per-cpu kprobe control block. */
62struct kprobe_ctlblk {
63 unsigned long kprobe_status;
64 unsigned long kprobe_saved_pc;
65 unsigned long jprobe_saved_sp;
66 struct prev_kprobe prev_kprobe;
67 struct pt_regs jprobe_saved_regs;
68 char jprobes_stack[MAX_JPROBES_STACK_SIZE];
69};
70
71extern tile_bundle_bits breakpoint2_insn;
72extern tile_bundle_bits breakpoint_insn;
73
74void arch_remove_kprobe(struct kprobe *);
75
76extern int kprobe_exceptions_notify(struct notifier_block *self,
77 unsigned long val, void *data);
78
79#endif /* _ASM_TILE_KPROBES_H */
diff --git a/arch/tile/include/asm/mmu.h b/arch/tile/include/asm/mmu.h
index e2c789096795..0cab1182bde1 100644
--- a/arch/tile/include/asm/mmu.h
+++ b/arch/tile/include/asm/mmu.h
@@ -22,6 +22,7 @@ struct mm_context {
22 * semaphore but atomically, but it is conservatively set. 22 * semaphore but atomically, but it is conservatively set.
23 */ 23 */
24 unsigned long priority_cached; 24 unsigned long priority_cached;
25 unsigned long vdso_base;
25}; 26};
26 27
27typedef struct mm_context mm_context_t; 28typedef struct mm_context mm_context_t;
diff --git a/arch/tile/include/asm/mmu_context.h b/arch/tile/include/asm/mmu_context.h
index 37f0b741dee7..4734215e2ad4 100644
--- a/arch/tile/include/asm/mmu_context.h
+++ b/arch/tile/include/asm/mmu_context.h
@@ -45,7 +45,7 @@ static inline void __install_page_table(pgd_t *pgdir, int asid, pgprot_t prot)
45 45
46static inline void install_page_table(pgd_t *pgdir, int asid) 46static inline void install_page_table(pgd_t *pgdir, int asid)
47{ 47{
48 pte_t *ptep = virt_to_pte(NULL, (unsigned long)pgdir); 48 pte_t *ptep = virt_to_kpte((unsigned long)pgdir);
49 __install_page_table(pgdir, asid, *ptep); 49 __install_page_table(pgdir, asid, *ptep);
50} 50}
51 51
diff --git a/arch/tile/include/asm/mmzone.h b/arch/tile/include/asm/mmzone.h
index 9d3dbce8f953..804f1098b6cd 100644
--- a/arch/tile/include/asm/mmzone.h
+++ b/arch/tile/include/asm/mmzone.h
@@ -42,7 +42,7 @@ static inline int pfn_to_nid(unsigned long pfn)
42 42
43#define kern_addr_valid(kaddr) virt_addr_valid((void *)kaddr) 43#define kern_addr_valid(kaddr) virt_addr_valid((void *)kaddr)
44 44
45static inline int pfn_valid(int pfn) 45static inline int pfn_valid(unsigned long pfn)
46{ 46{
47 int nid = pfn_to_nid(pfn); 47 int nid = pfn_to_nid(pfn);
48 48
diff --git a/arch/tile/include/asm/page.h b/arch/tile/include/asm/page.h
index dd033a4fd627..6346888f7bdc 100644
--- a/arch/tile/include/asm/page.h
+++ b/arch/tile/include/asm/page.h
@@ -39,6 +39,12 @@
39#define HPAGE_MASK (~(HPAGE_SIZE - 1)) 39#define HPAGE_MASK (~(HPAGE_SIZE - 1))
40 40
41/* 41/*
42 * We do define AT_SYSINFO_EHDR to support vDSO,
43 * but don't use the gate mechanism.
44 */
45#define __HAVE_ARCH_GATE_AREA 1
46
47/*
42 * If the Kconfig doesn't specify, set a maximum zone order that 48 * If the Kconfig doesn't specify, set a maximum zone order that
43 * is enough so that we can create huge pages from small pages given 49 * is enough so that we can create huge pages from small pages given
44 * the respective sizes of the two page types. See <linux/mmzone.h>. 50 * the respective sizes of the two page types. See <linux/mmzone.h>.
@@ -142,8 +148,12 @@ static inline __attribute_const__ int get_order(unsigned long size)
142#define HAVE_ARCH_HUGETLB_UNMAPPED_AREA 148#define HAVE_ARCH_HUGETLB_UNMAPPED_AREA
143#endif 149#endif
144 150
151/* Allow overriding how much VA or PA the kernel will use. */
152#define MAX_PA_WIDTH CHIP_PA_WIDTH()
153#define MAX_VA_WIDTH CHIP_VA_WIDTH()
154
145/* Each memory controller has PAs distinct in their high bits. */ 155/* Each memory controller has PAs distinct in their high bits. */
146#define NR_PA_HIGHBIT_SHIFT (CHIP_PA_WIDTH() - CHIP_LOG_NUM_MSHIMS()) 156#define NR_PA_HIGHBIT_SHIFT (MAX_PA_WIDTH - CHIP_LOG_NUM_MSHIMS())
147#define NR_PA_HIGHBIT_VALUES (1 << CHIP_LOG_NUM_MSHIMS()) 157#define NR_PA_HIGHBIT_VALUES (1 << CHIP_LOG_NUM_MSHIMS())
148#define __pa_to_highbits(pa) ((phys_addr_t)(pa) >> NR_PA_HIGHBIT_SHIFT) 158#define __pa_to_highbits(pa) ((phys_addr_t)(pa) >> NR_PA_HIGHBIT_SHIFT)
149#define __pfn_to_highbits(pfn) ((pfn) >> (NR_PA_HIGHBIT_SHIFT - PAGE_SHIFT)) 159#define __pfn_to_highbits(pfn) ((pfn) >> (NR_PA_HIGHBIT_SHIFT - PAGE_SHIFT))
@@ -154,7 +164,7 @@ static inline __attribute_const__ int get_order(unsigned long size)
154 * We reserve the lower half of memory for user-space programs, and the 164 * We reserve the lower half of memory for user-space programs, and the
155 * upper half for system code. We re-map all of physical memory in the 165 * upper half for system code. We re-map all of physical memory in the
156 * upper half, which takes a quarter of our VA space. Then we have 166 * upper half, which takes a quarter of our VA space. Then we have
157 * the vmalloc regions. The supervisor code lives at 0xfffffff700000000, 167 * the vmalloc regions. The supervisor code lives at the highest address,
158 * with the hypervisor above that. 168 * with the hypervisor above that.
159 * 169 *
160 * Loadable kernel modules are placed immediately after the static 170 * Loadable kernel modules are placed immediately after the static
@@ -166,26 +176,19 @@ static inline __attribute_const__ int get_order(unsigned long size)
166 * Similarly, for now we don't play any struct page mapping games. 176 * Similarly, for now we don't play any struct page mapping games.
167 */ 177 */
168 178
169#if CHIP_PA_WIDTH() + 2 > CHIP_VA_WIDTH() 179#if MAX_PA_WIDTH + 2 > MAX_VA_WIDTH
170# error Too much PA to map with the VA available! 180# error Too much PA to map with the VA available!
171#endif 181#endif
172#define HALF_VA_SPACE (_AC(1, UL) << (CHIP_VA_WIDTH() - 1))
173 182
174#define MEM_LOW_END (HALF_VA_SPACE - 1) /* low half */ 183#define PAGE_OFFSET (-(_AC(1, UL) << (MAX_VA_WIDTH - 1)))
175#define MEM_HIGH_START (-HALF_VA_SPACE) /* high half */ 184#define KERNEL_HIGH_VADDR _AC(0xfffffff800000000, UL) /* high 32GB */
176#define PAGE_OFFSET MEM_HIGH_START 185#define FIXADDR_BASE (KERNEL_HIGH_VADDR - 0x400000000) /* 4 GB */
177#define FIXADDR_BASE _AC(0xfffffff400000000, UL) /* 4 GB */ 186#define FIXADDR_TOP (KERNEL_HIGH_VADDR - 0x300000000) /* 4 GB */
178#define FIXADDR_TOP _AC(0xfffffff500000000, UL) /* 4 GB */
179#define _VMALLOC_START FIXADDR_TOP 187#define _VMALLOC_START FIXADDR_TOP
180#define HUGE_VMAP_BASE _AC(0xfffffff600000000, UL) /* 4 GB */ 188#define HUGE_VMAP_BASE (KERNEL_HIGH_VADDR - 0x200000000) /* 4 GB */
181#define MEM_SV_START _AC(0xfffffff700000000, UL) /* 256 MB */ 189#define MEM_SV_START (KERNEL_HIGH_VADDR - 0x100000000) /* 256 MB */
182#define MEM_SV_INTRPT MEM_SV_START 190#define MEM_MODULE_START (MEM_SV_START + (256*1024*1024)) /* 256 MB */
183#define MEM_MODULE_START _AC(0xfffffff710000000, UL) /* 256 MB */
184#define MEM_MODULE_END (MEM_MODULE_START + (256*1024*1024)) 191#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 192
190#else /* !__tilegx__ */ 193#else /* !__tilegx__ */
191 194
@@ -207,25 +210,18 @@ static inline __attribute_const__ int get_order(unsigned long size)
207 * values, and after that, we show "typical" values, since the actual 210 * values, and after that, we show "typical" values, since the actual
208 * addresses depend on kernel #defines. 211 * addresses depend on kernel #defines.
209 * 212 *
210 * MEM_HV_INTRPT 0xfe000000 213 * MEM_HV_START 0xfe000000
211 * MEM_SV_INTRPT (kernel code) 0xfd000000 214 * MEM_SV_START (kernel code) 0xfd000000
212 * MEM_USER_INTRPT (user vector) 0xfc000000 215 * MEM_USER_INTRPT (user vector) 0xfc000000
213 * FIX_KMAP_xxx 0xf8000000 (via NR_CPUS * KM_TYPE_NR) 216 * FIX_KMAP_xxx 0xfa000000 (via NR_CPUS * KM_TYPE_NR)
214 * PKMAP_BASE 0xf7000000 (via LAST_PKMAP) 217 * PKMAP_BASE 0xf9000000 (via LAST_PKMAP)
215 * HUGE_VMAP 0xf3000000 (via CONFIG_NR_HUGE_VMAPS) 218 * VMALLOC_START 0xf7000000 (via VMALLOC_RESERVE)
216 * VMALLOC_START 0xf0000000 (via __VMALLOC_RESERVE)
217 * mapped LOWMEM 0xc0000000 219 * mapped LOWMEM 0xc0000000
218 */ 220 */
219 221
220#define MEM_USER_INTRPT _AC(0xfc000000, UL) 222#define MEM_USER_INTRPT _AC(0xfc000000, UL)
221#if CONFIG_KERNEL_PL == 1 223#define MEM_SV_START _AC(0xfd000000, UL)
222#define MEM_SV_INTRPT _AC(0xfd000000, UL) 224#define MEM_HV_START _AC(0xfe000000, UL)
223#define MEM_HV_INTRPT _AC(0xfe000000, UL)
224#else
225#define MEM_GUEST_INTRPT _AC(0xfd000000, UL)
226#define MEM_SV_INTRPT _AC(0xfe000000, UL)
227#define MEM_HV_INTRPT _AC(0xff000000, UL)
228#endif
229 225
230#define INTRPT_SIZE 0x4000 226#define INTRPT_SIZE 0x4000
231 227
@@ -246,7 +242,7 @@ static inline __attribute_const__ int get_order(unsigned long size)
246 242
247#endif /* __tilegx__ */ 243#endif /* __tilegx__ */
248 244
249#ifndef __ASSEMBLY__ 245#if !defined(__ASSEMBLY__) && !defined(VDSO_BUILD)
250 246
251#ifdef CONFIG_HIGHMEM 247#ifdef CONFIG_HIGHMEM
252 248
@@ -332,6 +328,7 @@ static inline int pfn_valid(unsigned long pfn)
332 328
333struct mm_struct; 329struct mm_struct;
334extern pte_t *virt_to_pte(struct mm_struct *mm, unsigned long addr); 330extern pte_t *virt_to_pte(struct mm_struct *mm, unsigned long addr);
331extern pte_t *virt_to_kpte(unsigned long kaddr);
335 332
336#endif /* !__ASSEMBLY__ */ 333#endif /* !__ASSEMBLY__ */
337 334
diff --git a/arch/tile/include/asm/pci.h b/arch/tile/include/asm/pci.h
index 54a924208d3c..dfedd7ac7298 100644
--- a/arch/tile/include/asm/pci.h
+++ b/arch/tile/include/asm/pci.h
@@ -17,7 +17,6 @@
17 17
18#include <linux/dma-mapping.h> 18#include <linux/dma-mapping.h>
19#include <linux/pci.h> 19#include <linux/pci.h>
20#include <linux/numa.h>
21#include <asm-generic/pci_iomap.h> 20#include <asm-generic/pci_iomap.h>
22 21
23#ifndef __tilegx__ 22#ifndef __tilegx__
@@ -29,7 +28,6 @@ struct pci_controller {
29 int index; /* PCI domain number */ 28 int index; /* PCI domain number */
30 struct pci_bus *root_bus; 29 struct pci_bus *root_bus;
31 30
32 int first_busno;
33 int last_busno; 31 int last_busno;
34 32
35 int hv_cfg_fd[2]; /* config{0,1} fds for this PCIe controller */ 33 int hv_cfg_fd[2]; /* config{0,1} fds for this PCIe controller */
@@ -124,6 +122,11 @@ static inline void pci_iounmap(struct pci_dev *dev, void __iomem *addr) {}
124 * the CPA plus TILE_PCI_MEM_MAP_BASE_OFFSET. To support 32-bit 122 * the CPA plus TILE_PCI_MEM_MAP_BASE_OFFSET. To support 32-bit
125 * devices, we create a separate map region that handles the low 123 * devices, we create a separate map region that handles the low
126 * 4GB. 124 * 4GB.
125 *
126 * This design lets us avoid the "PCI hole" problem where the host bridge
127 * won't pass DMA traffic with target addresses that happen to fall within the
128 * BAR space. This enables us to use all the physical memory for DMA, instead
129 * of wasting the same amount of physical memory as the BAR window size.
127 */ 130 */
128#define TILE_PCI_MEM_MAP_BASE_OFFSET (1ULL << CHIP_PA_WIDTH()) 131#define TILE_PCI_MEM_MAP_BASE_OFFSET (1ULL << CHIP_PA_WIDTH())
129 132
@@ -145,6 +148,10 @@ struct pci_controller {
145 148
146 int pio_mem_index; /* PIO region index for memory access */ 149 int pio_mem_index; /* PIO region index for memory access */
147 150
151#ifdef CONFIG_TILE_PCI_IO
152 int pio_io_index; /* PIO region index for I/O space access */
153#endif
154
148 /* 155 /*
149 * Mem-Map regions for all the memory controllers so that Linux can 156 * Mem-Map regions for all the memory controllers so that Linux can
150 * map all of its physical memory space to the PCI bus. 157 * map all of its physical memory space to the PCI bus.
@@ -154,6 +161,10 @@ struct pci_controller {
154 int index; /* PCI domain number */ 161 int index; /* PCI domain number */
155 struct pci_bus *root_bus; 162 struct pci_bus *root_bus;
156 163
164 /* PCI I/O space resource for this controller. */
165 struct resource io_space;
166 char io_space_name[32];
167
157 /* PCI memory space resource for this controller. */ 168 /* PCI memory space resource for this controller. */
158 struct resource mem_space; 169 struct resource mem_space;
159 char mem_space_name[32]; 170 char mem_space_name[32];
@@ -166,13 +177,11 @@ struct pci_controller {
166 177
167 /* Table that maps the INTx numbers to Linux irq numbers. */ 178 /* Table that maps the INTx numbers to Linux irq numbers. */
168 int irq_intx_table[4]; 179 int irq_intx_table[4];
169
170 /* Address ranges that are routed to this controller/bridge. */
171 struct resource mem_resources[3];
172}; 180};
173 181
174extern struct pci_controller pci_controllers[TILEGX_NUM_TRIO * TILEGX_TRIO_PCIES]; 182extern struct pci_controller pci_controllers[TILEGX_NUM_TRIO * TILEGX_TRIO_PCIES];
175extern gxio_trio_context_t trio_contexts[TILEGX_NUM_TRIO]; 183extern gxio_trio_context_t trio_contexts[TILEGX_NUM_TRIO];
184extern int num_trio_shims;
176 185
177extern void pci_iounmap(struct pci_dev *dev, void __iomem *); 186extern void pci_iounmap(struct pci_dev *dev, void __iomem *);
178 187
@@ -211,7 +220,8 @@ static inline int pcibios_assign_all_busses(void)
211} 220}
212 221
213#define PCIBIOS_MIN_MEM 0 222#define PCIBIOS_MIN_MEM 0
214#define PCIBIOS_MIN_IO 0 223/* Minimum PCI I/O address, starting at the page boundary. */
224#define PCIBIOS_MIN_IO PAGE_SIZE
215 225
216/* Use any cpu for PCI. */ 226/* Use any cpu for PCI. */
217#define cpumask_of_pcibus(bus) cpu_online_mask 227#define cpumask_of_pcibus(bus) cpu_online_mask
diff --git a/arch/tile/include/asm/pgtable_32.h b/arch/tile/include/asm/pgtable_32.h
index 4ce4a7a99c24..63142ab3b3dd 100644
--- a/arch/tile/include/asm/pgtable_32.h
+++ b/arch/tile/include/asm/pgtable_32.h
@@ -84,10 +84,12 @@ extern unsigned long VMALLOC_RESERVE /* = CONFIG_VMALLOC_RESERVE */;
84/* We have no pmd or pud since we are strictly a two-level page table */ 84/* We have no pmd or pud since we are strictly a two-level page table */
85#include <asm-generic/pgtable-nopmd.h> 85#include <asm-generic/pgtable-nopmd.h>
86 86
87static inline int pud_huge_page(pud_t pud) { return 0; }
88
87/* We don't define any pgds for these addresses. */ 89/* We don't define any pgds for these addresses. */
88static inline int pgd_addr_invalid(unsigned long addr) 90static inline int pgd_addr_invalid(unsigned long addr)
89{ 91{
90 return addr >= MEM_HV_INTRPT; 92 return addr >= MEM_HV_START;
91} 93}
92 94
93/* 95/*
diff --git a/arch/tile/include/asm/pgtable_64.h b/arch/tile/include/asm/pgtable_64.h
index 2492fa5478e7..3421177f7370 100644
--- a/arch/tile/include/asm/pgtable_64.h
+++ b/arch/tile/include/asm/pgtable_64.h
@@ -63,6 +63,15 @@
63/* We have no pud since we are a three-level page table. */ 63/* We have no pud since we are a three-level page table. */
64#include <asm-generic/pgtable-nopud.h> 64#include <asm-generic/pgtable-nopud.h>
65 65
66/*
67 * pmds are the same as pgds and ptes, so converting is a no-op.
68 */
69#define pmd_pte(pmd) (pmd)
70#define pmdp_ptep(pmdp) (pmdp)
71#define pte_pmd(pte) (pte)
72
73#define pud_pte(pud) ((pud).pgd)
74
66static inline int pud_none(pud_t pud) 75static inline int pud_none(pud_t pud)
67{ 76{
68 return pud_val(pud) == 0; 77 return pud_val(pud) == 0;
@@ -73,6 +82,11 @@ static inline int pud_present(pud_t pud)
73 return pud_val(pud) & _PAGE_PRESENT; 82 return pud_val(pud) & _PAGE_PRESENT;
74} 83}
75 84
85static inline int pud_huge_page(pud_t pud)
86{
87 return pud_val(pud) & _PAGE_HUGE_PAGE;
88}
89
76#define pmd_ERROR(e) \ 90#define pmd_ERROR(e) \
77 pr_err("%s:%d: bad pmd 0x%016llx.\n", __FILE__, __LINE__, pmd_val(e)) 91 pr_err("%s:%d: bad pmd 0x%016llx.\n", __FILE__, __LINE__, pmd_val(e))
78 92
@@ -89,6 +103,9 @@ static inline int pud_bad(pud_t pud)
89/* Return the page-table frame number (ptfn) that a pud_t points at. */ 103/* Return the page-table frame number (ptfn) that a pud_t points at. */
90#define pud_ptfn(pud) hv_pte_get_ptfn((pud).pgd) 104#define pud_ptfn(pud) hv_pte_get_ptfn((pud).pgd)
91 105
106/* Return the page frame number (pfn) that a pud_t points at. */
107#define pud_pfn(pud) pte_pfn(pud_pte(pud))
108
92/* 109/*
93 * A given kernel pud_t maps to a kernel pmd_t table at a specific 110 * A given kernel pud_t maps to a kernel pmd_t table at a specific
94 * virtual address. Since kernel pmd_t tables can be aligned at 111 * virtual address. Since kernel pmd_t tables can be aligned at
@@ -123,8 +140,7 @@ static inline unsigned long pgd_addr_normalize(unsigned long addr)
123/* We don't define any pgds for these addresses. */ 140/* We don't define any pgds for these addresses. */
124static inline int pgd_addr_invalid(unsigned long addr) 141static inline int pgd_addr_invalid(unsigned long addr)
125{ 142{
126 return addr >= MEM_HV_START || 143 return addr >= KERNEL_HIGH_VADDR || addr != pgd_addr_normalize(addr);
127 (addr > MEM_LOW_END && addr < MEM_HIGH_START);
128} 144}
129 145
130/* 146/*
@@ -152,13 +168,6 @@ static inline pte_t ptep_get_and_clear(struct mm_struct *mm,
152 return hv_pte(__insn_exch(&ptep->val, 0UL)); 168 return hv_pte(__insn_exch(&ptep->val, 0UL));
153} 169}
154 170
155/*
156 * pmds are the same as pgds and ptes, so converting is a no-op.
157 */
158#define pmd_pte(pmd) (pmd)
159#define pmdp_ptep(pmdp) (pmdp)
160#define pte_pmd(pte) (pte)
161
162#endif /* __ASSEMBLY__ */ 171#endif /* __ASSEMBLY__ */
163 172
164#endif /* _ASM_TILE_PGTABLE_64_H */ 173#endif /* _ASM_TILE_PGTABLE_64_H */
diff --git a/arch/tile/include/asm/processor.h b/arch/tile/include/asm/processor.h
index b3f104953da2..42323636c459 100644
--- a/arch/tile/include/asm/processor.h
+++ b/arch/tile/include/asm/processor.h
@@ -15,6 +15,8 @@
15#ifndef _ASM_TILE_PROCESSOR_H 15#ifndef _ASM_TILE_PROCESSOR_H
16#define _ASM_TILE_PROCESSOR_H 16#define _ASM_TILE_PROCESSOR_H
17 17
18#include <arch/chip.h>
19
18#ifndef __ASSEMBLY__ 20#ifndef __ASSEMBLY__
19 21
20/* 22/*
@@ -25,7 +27,6 @@
25#include <asm/ptrace.h> 27#include <asm/ptrace.h>
26#include <asm/percpu.h> 28#include <asm/percpu.h>
27 29
28#include <arch/chip.h>
29#include <arch/spr_def.h> 30#include <arch/spr_def.h>
30 31
31struct task_struct; 32struct task_struct;
@@ -110,18 +111,16 @@ struct thread_struct {
110 unsigned long long interrupt_mask; 111 unsigned long long interrupt_mask;
111 /* User interrupt-control 0 state */ 112 /* User interrupt-control 0 state */
112 unsigned long intctrl_0; 113 unsigned long intctrl_0;
113#if CHIP_HAS_PROC_STATUS_SPR() 114 /* Is this task currently doing a backtrace? */
115 bool in_backtrace;
114 /* Any other miscellaneous processor state bits */ 116 /* Any other miscellaneous processor state bits */
115 unsigned long proc_status; 117 unsigned long proc_status;
116#endif
117#if !CHIP_HAS_FIXED_INTVEC_BASE() 118#if !CHIP_HAS_FIXED_INTVEC_BASE()
118 /* Interrupt base for PL0 interrupts */ 119 /* Interrupt base for PL0 interrupts */
119 unsigned long interrupt_vector_base; 120 unsigned long interrupt_vector_base;
120#endif 121#endif
121#if CHIP_HAS_TILE_RTF_HWM()
122 /* Tile cache retry fifo high-water mark */ 122 /* Tile cache retry fifo high-water mark */
123 unsigned long tile_rtf_hwm; 123 unsigned long tile_rtf_hwm;
124#endif
125#if CHIP_HAS_DSTREAM_PF() 124#if CHIP_HAS_DSTREAM_PF()
126 /* Data stream prefetch control */ 125 /* Data stream prefetch control */
127 unsigned long dstream_pf; 126 unsigned long dstream_pf;
@@ -134,21 +133,16 @@ struct thread_struct {
134 /* Async DMA TLB fault information */ 133 /* Async DMA TLB fault information */
135 struct async_tlb dma_async_tlb; 134 struct async_tlb dma_async_tlb;
136#endif 135#endif
137#if CHIP_HAS_SN_PROC()
138 /* Was static network processor when we were switched out? */
139 int sn_proc_running;
140 /* Async SNI TLB fault information */
141 struct async_tlb sn_async_tlb;
142#endif
143}; 136};
144 137
145#endif /* !__ASSEMBLY__ */ 138#endif /* !__ASSEMBLY__ */
146 139
147/* 140/*
148 * Start with "sp" this many bytes below the top of the kernel stack. 141 * Start with "sp" this many bytes below the top of the kernel stack.
149 * This preserves the invariant that a called function may write to *sp. 142 * This allows us to be cache-aware when handling the initial save
143 * of the pt_regs value to the stack.
150 */ 144 */
151#define STACK_TOP_DELTA 8 145#define STACK_TOP_DELTA 64
152 146
153/* 147/*
154 * When entering the kernel via a fault, start with the top of the 148 * When entering the kernel via a fault, start with the top of the
@@ -164,7 +158,7 @@ struct thread_struct {
164#ifndef __ASSEMBLY__ 158#ifndef __ASSEMBLY__
165 159
166#ifdef __tilegx__ 160#ifdef __tilegx__
167#define TASK_SIZE_MAX (MEM_LOW_END + 1) 161#define TASK_SIZE_MAX (_AC(1, UL) << (MAX_VA_WIDTH - 1))
168#else 162#else
169#define TASK_SIZE_MAX PAGE_OFFSET 163#define TASK_SIZE_MAX PAGE_OFFSET
170#endif 164#endif
@@ -178,10 +172,10 @@ struct thread_struct {
178#define TASK_SIZE TASK_SIZE_MAX 172#define TASK_SIZE TASK_SIZE_MAX
179#endif 173#endif
180 174
181/* We provide a minimal "vdso" a la x86; just the sigreturn code for now. */ 175#define VDSO_BASE ((unsigned long)current->active_mm->context.vdso_base)
182#define VDSO_BASE (TASK_SIZE - PAGE_SIZE) 176#define VDSO_SYM(x) (VDSO_BASE + (unsigned long)(x))
183 177
184#define STACK_TOP VDSO_BASE 178#define STACK_TOP TASK_SIZE
185 179
186/* STACK_TOP_MAX is used temporarily in execve and should not check COMPAT. */ 180/* STACK_TOP_MAX is used temporarily in execve and should not check COMPAT. */
187#define STACK_TOP_MAX TASK_SIZE_MAX 181#define STACK_TOP_MAX TASK_SIZE_MAX
@@ -232,21 +226,28 @@ extern int do_work_pending(struct pt_regs *regs, u32 flags);
232unsigned long get_wchan(struct task_struct *p); 226unsigned long get_wchan(struct task_struct *p);
233 227
234/* Return initial ksp value for given task. */ 228/* Return initial ksp value for given task. */
235#define task_ksp0(task) ((unsigned long)(task)->stack + THREAD_SIZE) 229#define task_ksp0(task) \
230 ((unsigned long)(task)->stack + THREAD_SIZE - STACK_TOP_DELTA)
236 231
237/* Return some info about the user process TASK. */ 232/* Return some info about the user process TASK. */
238#define KSTK_TOP(task) (task_ksp0(task) - STACK_TOP_DELTA)
239#define task_pt_regs(task) \ 233#define task_pt_regs(task) \
240 ((struct pt_regs *)(task_ksp0(task) - KSTK_PTREGS_GAP) - 1) 234 ((struct pt_regs *)(task_ksp0(task) - KSTK_PTREGS_GAP) - 1)
241#define current_pt_regs() \ 235#define current_pt_regs() \
242 ((struct pt_regs *)((stack_pointer | (THREAD_SIZE - 1)) - \ 236 ((struct pt_regs *)((stack_pointer | (THREAD_SIZE - 1)) - \
243 (KSTK_PTREGS_GAP - 1)) - 1) 237 STACK_TOP_DELTA - (KSTK_PTREGS_GAP - 1)) - 1)
244#define task_sp(task) (task_pt_regs(task)->sp) 238#define task_sp(task) (task_pt_regs(task)->sp)
245#define task_pc(task) (task_pt_regs(task)->pc) 239#define task_pc(task) (task_pt_regs(task)->pc)
246/* Aliases for pc and sp (used in fs/proc/array.c) */ 240/* Aliases for pc and sp (used in fs/proc/array.c) */
247#define KSTK_EIP(task) task_pc(task) 241#define KSTK_EIP(task) task_pc(task)
248#define KSTK_ESP(task) task_sp(task) 242#define KSTK_ESP(task) task_sp(task)
249 243
244/* Fine-grained unaligned JIT support */
245#define GET_UNALIGN_CTL(tsk, adr) get_unalign_ctl((tsk), (adr))
246#define SET_UNALIGN_CTL(tsk, val) set_unalign_ctl((tsk), (val))
247
248extern int get_unalign_ctl(struct task_struct *tsk, unsigned long adr);
249extern int set_unalign_ctl(struct task_struct *tsk, unsigned int val);
250
250/* Standard format for printing registers and other word-size data. */ 251/* Standard format for printing registers and other word-size data. */
251#ifdef __tilegx__ 252#ifdef __tilegx__
252# define REGFMT "0x%016lx" 253# define REGFMT "0x%016lx"
@@ -275,7 +276,6 @@ extern char chip_model[64];
275/* Data on which physical memory controller corresponds to which NUMA node. */ 276/* Data on which physical memory controller corresponds to which NUMA node. */
276extern int node_controller[]; 277extern int node_controller[];
277 278
278#if CHIP_HAS_CBOX_HOME_MAP()
279/* Does the heap allocator return hash-for-home pages by default? */ 279/* Does the heap allocator return hash-for-home pages by default? */
280extern int hash_default; 280extern int hash_default;
281 281
@@ -285,11 +285,6 @@ extern int kstack_hash;
285/* Does MAP_ANONYMOUS return hash-for-home pages by default? */ 285/* Does MAP_ANONYMOUS return hash-for-home pages by default? */
286#define uheap_hash hash_default 286#define uheap_hash hash_default
287 287
288#else
289#define hash_default 0
290#define kstack_hash 0
291#define uheap_hash 0
292#endif
293 288
294/* Are we using huge pages in the TLB for kernel data? */ 289/* Are we using huge pages in the TLB for kernel data? */
295extern int kdata_huge; 290extern int kdata_huge;
@@ -337,7 +332,6 @@ extern int kdata_huge;
337 332
338/* 333/*
339 * Provide symbolic constants for PLs. 334 * Provide symbolic constants for PLs.
340 * Note that assembly code assumes that USER_PL is zero.
341 */ 335 */
342#define USER_PL 0 336#define USER_PL 0
343#if CONFIG_KERNEL_PL == 2 337#if CONFIG_KERNEL_PL == 2
@@ -346,20 +340,38 @@ extern int kdata_huge;
346#define KERNEL_PL CONFIG_KERNEL_PL 340#define KERNEL_PL CONFIG_KERNEL_PL
347 341
348/* SYSTEM_SAVE_K_0 holds the current cpu number ORed with ksp0. */ 342/* SYSTEM_SAVE_K_0 holds the current cpu number ORed with ksp0. */
349#define CPU_LOG_MASK_VALUE 12 343#ifdef __tilegx__
350#define CPU_MASK_VALUE ((1 << CPU_LOG_MASK_VALUE) - 1) 344#define CPU_SHIFT 48
351#if CONFIG_NR_CPUS > CPU_MASK_VALUE 345#if CHIP_VA_WIDTH() > CPU_SHIFT
352# error Too many cpus! 346# error Too many VA bits!
353#endif 347#endif
348#define MAX_CPU_ID ((1 << (64 - CPU_SHIFT)) - 1)
349#define raw_smp_processor_id() \
350 ((int)(__insn_mfspr(SPR_SYSTEM_SAVE_K_0) >> CPU_SHIFT))
351#define get_current_ksp0() \
352 ((unsigned long)(((long)__insn_mfspr(SPR_SYSTEM_SAVE_K_0) << \
353 (64 - CPU_SHIFT)) >> (64 - CPU_SHIFT)))
354#define next_current_ksp0(task) ({ \
355 unsigned long __ksp0 = task_ksp0(task) & ((1UL << CPU_SHIFT) - 1); \
356 unsigned long __cpu = (long)raw_smp_processor_id() << CPU_SHIFT; \
357 __ksp0 | __cpu; \
358})
359#else
360#define LOG2_NR_CPU_IDS 6
361#define MAX_CPU_ID ((1 << LOG2_NR_CPU_IDS) - 1)
354#define raw_smp_processor_id() \ 362#define raw_smp_processor_id() \
355 ((int)__insn_mfspr(SPR_SYSTEM_SAVE_K_0) & CPU_MASK_VALUE) 363 ((int)__insn_mfspr(SPR_SYSTEM_SAVE_K_0) & MAX_CPU_ID)
356#define get_current_ksp0() \ 364#define get_current_ksp0() \
357 (__insn_mfspr(SPR_SYSTEM_SAVE_K_0) & ~CPU_MASK_VALUE) 365 (__insn_mfspr(SPR_SYSTEM_SAVE_K_0) & ~MAX_CPU_ID)
358#define next_current_ksp0(task) ({ \ 366#define next_current_ksp0(task) ({ \
359 unsigned long __ksp0 = task_ksp0(task); \ 367 unsigned long __ksp0 = task_ksp0(task); \
360 int __cpu = raw_smp_processor_id(); \ 368 int __cpu = raw_smp_processor_id(); \
361 BUG_ON(__ksp0 & CPU_MASK_VALUE); \ 369 BUG_ON(__ksp0 & MAX_CPU_ID); \
362 __ksp0 | __cpu; \ 370 __ksp0 | __cpu; \
363}) 371})
372#endif
373#if CONFIG_NR_CPUS > (MAX_CPU_ID + 1)
374# error Too many cpus!
375#endif
364 376
365#endif /* _ASM_TILE_PROCESSOR_H */ 377#endif /* _ASM_TILE_PROCESSOR_H */
diff --git a/arch/tile/include/asm/ptrace.h b/arch/tile/include/asm/ptrace.h
index fd412260aff7..b9620c077abc 100644
--- a/arch/tile/include/asm/ptrace.h
+++ b/arch/tile/include/asm/ptrace.h
@@ -33,12 +33,13 @@ typedef unsigned long pt_reg_t;
33 33
34#ifndef __ASSEMBLY__ 34#ifndef __ASSEMBLY__
35 35
36#define regs_return_value(regs) ((regs)->regs[0])
36#define instruction_pointer(regs) ((regs)->pc) 37#define instruction_pointer(regs) ((regs)->pc)
37#define profile_pc(regs) instruction_pointer(regs) 38#define profile_pc(regs) instruction_pointer(regs)
38#define user_stack_pointer(regs) ((regs)->sp) 39#define user_stack_pointer(regs) ((regs)->sp)
39 40
40/* Does the process account for user or for system time? */ 41/* Does the process account for user or for system time? */
41#define user_mode(regs) (EX1_PL((regs)->ex1) == USER_PL) 42#define user_mode(regs) (EX1_PL((regs)->ex1) < KERNEL_PL)
42 43
43/* Fill in a struct pt_regs with the current kernel registers. */ 44/* Fill in a struct pt_regs with the current kernel registers. */
44struct pt_regs *get_pt_regs(struct pt_regs *); 45struct pt_regs *get_pt_regs(struct pt_regs *);
@@ -79,8 +80,7 @@ extern void single_step_execve(void);
79 80
80struct task_struct; 81struct task_struct;
81 82
82extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, 83extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs);
83 int error_code);
84 84
85#ifdef __tilegx__ 85#ifdef __tilegx__
86/* We need this since sigval_t has a user pointer in it, for GETSIGINFO etc. */ 86/* We need this since sigval_t has a user pointer in it, for GETSIGINFO etc. */
diff --git a/arch/tile/include/asm/sections.h b/arch/tile/include/asm/sections.h
index 7d8a935a9238..5d5d3b739a6b 100644
--- a/arch/tile/include/asm/sections.h
+++ b/arch/tile/include/asm/sections.h
@@ -25,10 +25,16 @@ extern char _sinitdata[], _einitdata[];
25/* Write-once data is writable only till the end of initialization. */ 25/* Write-once data is writable only till the end of initialization. */
26extern char __w1data_begin[], __w1data_end[]; 26extern char __w1data_begin[], __w1data_end[];
27 27
28extern char vdso_start[], vdso_end[];
29#ifdef CONFIG_COMPAT
30extern char vdso32_start[], vdso32_end[];
31#endif
28 32
29/* Not exactly sections, but PC comparison points in the code. */ 33/* Not exactly sections, but PC comparison points in the code. */
30extern char __rt_sigreturn[], __rt_sigreturn_end[]; 34extern char __rt_sigreturn[], __rt_sigreturn_end[];
31#ifndef __tilegx__ 35#ifdef __tilegx__
36extern char __start_unalign_asm_code[], __end_unalign_asm_code[];
37#else
32extern char sys_cmpxchg[], __sys_cmpxchg_end[]; 38extern char sys_cmpxchg[], __sys_cmpxchg_end[];
33extern char __sys_cmpxchg_grab_lock[]; 39extern char __sys_cmpxchg_grab_lock[];
34extern char __start_atomic_asm_code[], __end_atomic_asm_code[]; 40extern char __start_atomic_asm_code[], __end_atomic_asm_code[];
diff --git a/arch/tile/include/asm/setup.h b/arch/tile/include/asm/setup.h
index d048888c5d9a..e98909033e5b 100644
--- a/arch/tile/include/asm/setup.h
+++ b/arch/tile/include/asm/setup.h
@@ -24,9 +24,8 @@
24 */ 24 */
25#define MAXMEM_PFN PFN_DOWN(MAXMEM) 25#define MAXMEM_PFN PFN_DOWN(MAXMEM)
26 26
27int tile_console_write(const char *buf, int count);
27void early_panic(const char *fmt, ...); 28void early_panic(const char *fmt, ...);
28void warn_early_printk(void);
29void __init disable_early_printk(void);
30 29
31/* Init-time routine to do tile-specific per-cpu setup. */ 30/* Init-time routine to do tile-specific per-cpu setup. */
32void setup_cpu(int boot); 31void setup_cpu(int boot);
diff --git a/arch/tile/include/asm/smp.h b/arch/tile/include/asm/smp.h
index 1aa759aeb5b3..9a326b64f7ae 100644
--- a/arch/tile/include/asm/smp.h
+++ b/arch/tile/include/asm/smp.h
@@ -101,10 +101,8 @@ void print_disabled_cpus(void);
101extern struct cpumask cpu_lotar_map; 101extern struct cpumask cpu_lotar_map;
102#define cpu_is_valid_lotar(cpu) cpumask_test_cpu((cpu), &cpu_lotar_map) 102#define cpu_is_valid_lotar(cpu) cpumask_test_cpu((cpu), &cpu_lotar_map)
103 103
104#if CHIP_HAS_CBOX_HOME_MAP()
105/* Which processors are used for hash-for-home mapping */ 104/* Which processors are used for hash-for-home mapping */
106extern struct cpumask hash_for_home_map; 105extern struct cpumask hash_for_home_map;
107#endif
108 106
109/* Which cpus can have their cache flushed by hv_flush_remote(). */ 107/* Which cpus can have their cache flushed by hv_flush_remote(). */
110extern struct cpumask cpu_cacheable_map; 108extern struct cpumask cpu_cacheable_map;
diff --git a/arch/tile/include/asm/spinlock_64.h b/arch/tile/include/asm/spinlock_64.h
index 5f8b6a095fd8..9a12b9c7e5d3 100644
--- a/arch/tile/include/asm/spinlock_64.h
+++ b/arch/tile/include/asm/spinlock_64.h
@@ -27,7 +27,7 @@
27 * Return the "current" portion of a ticket lock value, 27 * Return the "current" portion of a ticket lock value,
28 * i.e. the number that currently owns the lock. 28 * i.e. the number that currently owns the lock.
29 */ 29 */
30static inline int arch_spin_current(u32 val) 30static inline u32 arch_spin_current(u32 val)
31{ 31{
32 return val >> __ARCH_SPIN_CURRENT_SHIFT; 32 return val >> __ARCH_SPIN_CURRENT_SHIFT;
33} 33}
@@ -36,7 +36,7 @@ static inline int arch_spin_current(u32 val)
36 * Return the "next" portion of a ticket lock value, 36 * Return the "next" portion of a ticket lock value,
37 * i.e. the number that the next task to try to acquire the lock will get. 37 * i.e. the number that the next task to try to acquire the lock will get.
38 */ 38 */
39static inline int arch_spin_next(u32 val) 39static inline u32 arch_spin_next(u32 val)
40{ 40{
41 return val & __ARCH_SPIN_NEXT_MASK; 41 return val & __ARCH_SPIN_NEXT_MASK;
42} 42}
diff --git a/arch/tile/include/asm/string.h b/arch/tile/include/asm/string.h
index 7535cf1a30e4..92b271bd9ebd 100644
--- a/arch/tile/include/asm/string.h
+++ b/arch/tile/include/asm/string.h
@@ -21,8 +21,10 @@
21#define __HAVE_ARCH_MEMMOVE 21#define __HAVE_ARCH_MEMMOVE
22#define __HAVE_ARCH_STRCHR 22#define __HAVE_ARCH_STRCHR
23#define __HAVE_ARCH_STRLEN 23#define __HAVE_ARCH_STRLEN
24#define __HAVE_ARCH_STRNLEN
24 25
25extern __kernel_size_t strlen(const char *); 26extern __kernel_size_t strlen(const char *);
27extern __kernel_size_t strnlen(const char *, __kernel_size_t);
26extern char *strchr(const char *s, int c); 28extern char *strchr(const char *s, int c);
27extern void *memchr(const void *s, int c, size_t n); 29extern void *memchr(const void *s, int c, size_t n);
28extern void *memset(void *, int, __kernel_size_t); 30extern void *memset(void *, int, __kernel_size_t);
diff --git a/arch/tile/include/asm/thread_info.h b/arch/tile/include/asm/thread_info.h
index d1733dee98a2..b8aa6df3e102 100644
--- a/arch/tile/include/asm/thread_info.h
+++ b/arch/tile/include/asm/thread_info.h
@@ -39,6 +39,11 @@ struct thread_info {
39 struct restart_block restart_block; 39 struct restart_block restart_block;
40 struct single_step_state *step_state; /* single step state 40 struct single_step_state *step_state; /* single step state
41 (if non-zero) */ 41 (if non-zero) */
42 int align_ctl; /* controls unaligned access */
43#ifdef __tilegx__
44 unsigned long unalign_jit_tmp[4]; /* temp r0..r3 storage */
45 void __user *unalign_jit_base; /* unalign fixup JIT base */
46#endif
42}; 47};
43 48
44/* 49/*
@@ -56,6 +61,7 @@ struct thread_info {
56 .fn = do_no_restart_syscall, \ 61 .fn = do_no_restart_syscall, \
57 }, \ 62 }, \
58 .step_state = NULL, \ 63 .step_state = NULL, \
64 .align_ctl = 0, \
59} 65}
60 66
61#define init_thread_info (init_thread_union.thread_info) 67#define init_thread_info (init_thread_union.thread_info)
diff --git a/arch/tile/include/asm/traps.h b/arch/tile/include/asm/traps.h
index e28c3df4176a..4b99a1c3aab2 100644
--- a/arch/tile/include/asm/traps.h
+++ b/arch/tile/include/asm/traps.h
@@ -15,12 +15,13 @@
15#ifndef _ASM_TILE_TRAPS_H 15#ifndef _ASM_TILE_TRAPS_H
16#define _ASM_TILE_TRAPS_H 16#define _ASM_TILE_TRAPS_H
17 17
18#ifndef __ASSEMBLY__
18#include <arch/chip.h> 19#include <arch/chip.h>
19 20
20/* mm/fault.c */ 21/* mm/fault.c */
21void do_page_fault(struct pt_regs *, int fault_num, 22void do_page_fault(struct pt_regs *, int fault_num,
22 unsigned long address, unsigned long write); 23 unsigned long address, unsigned long write);
23#if CHIP_HAS_TILE_DMA() || CHIP_HAS_SN_PROC() 24#if CHIP_HAS_TILE_DMA()
24void do_async_page_fault(struct pt_regs *); 25void do_async_page_fault(struct pt_regs *);
25#endif 26#endif
26 27
@@ -69,6 +70,16 @@ void gx_singlestep_handle(struct pt_regs *, int fault_num);
69 70
70/* kernel/intvec_64.S */ 71/* kernel/intvec_64.S */
71void fill_ra_stack(void); 72void fill_ra_stack(void);
73
74/* Handle unalign data fixup. */
75extern void do_unaligned(struct pt_regs *regs, int vecnum);
76#endif
77
78#endif /* __ASSEMBLY__ */
79
80#ifdef __tilegx__
81/* 128 byte JIT per unalign fixup. */
82#define UNALIGN_JIT_SHIFT 7
72#endif 83#endif
73 84
74#endif /* _ASM_TILE_TRAPS_H */ 85#endif /* _ASM_TILE_TRAPS_H */
diff --git a/arch/tile/include/asm/uaccess.h b/arch/tile/include/asm/uaccess.h
index e4d44bd7df27..b6cde3209b96 100644
--- a/arch/tile/include/asm/uaccess.h
+++ b/arch/tile/include/asm/uaccess.h
@@ -127,8 +127,10 @@ extern int fixup_exception(struct pt_regs *regs);
127 127
128#ifdef __LP64__ 128#ifdef __LP64__
129#define _ASM_PTR ".quad" 129#define _ASM_PTR ".quad"
130#define _ASM_ALIGN ".align 8"
130#else 131#else
131#define _ASM_PTR ".long" 132#define _ASM_PTR ".long"
133#define _ASM_ALIGN ".align 4"
132#endif 134#endif
133 135
134#define __get_user_asm(OP, x, ptr, ret) \ 136#define __get_user_asm(OP, x, ptr, ret) \
@@ -137,6 +139,7 @@ extern int fixup_exception(struct pt_regs *regs);
137 "0: { movei %1, 0; movei %0, %3 }\n" \ 139 "0: { movei %1, 0; movei %0, %3 }\n" \
138 "j 9f\n" \ 140 "j 9f\n" \
139 ".section __ex_table,\"a\"\n" \ 141 ".section __ex_table,\"a\"\n" \
142 _ASM_ALIGN "\n" \
140 _ASM_PTR " 1b, 0b\n" \ 143 _ASM_PTR " 1b, 0b\n" \
141 ".popsection\n" \ 144 ".popsection\n" \
142 "9:" \ 145 "9:" \
@@ -168,6 +171,7 @@ extern int fixup_exception(struct pt_regs *regs);
168 "0: { movei %1, 0; movei %2, 0 }\n" \ 171 "0: { movei %1, 0; movei %2, 0 }\n" \
169 "{ movei %0, %4; j 9f }\n" \ 172 "{ movei %0, %4; j 9f }\n" \
170 ".section __ex_table,\"a\"\n" \ 173 ".section __ex_table,\"a\"\n" \
174 ".align 4\n" \
171 ".word 1b, 0b\n" \ 175 ".word 1b, 0b\n" \
172 ".word 2b, 0b\n" \ 176 ".word 2b, 0b\n" \
173 ".popsection\n" \ 177 ".popsection\n" \
@@ -224,6 +228,7 @@ extern int __get_user_bad(void)
224 ".pushsection .fixup,\"ax\"\n" \ 228 ".pushsection .fixup,\"ax\"\n" \
225 "0: { movei %0, %3; j 9f }\n" \ 229 "0: { movei %0, %3; j 9f }\n" \
226 ".section __ex_table,\"a\"\n" \ 230 ".section __ex_table,\"a\"\n" \
231 _ASM_ALIGN "\n" \
227 _ASM_PTR " 1b, 0b\n" \ 232 _ASM_PTR " 1b, 0b\n" \
228 ".popsection\n" \ 233 ".popsection\n" \
229 "9:" \ 234 "9:" \
@@ -248,6 +253,7 @@ extern int __get_user_bad(void)
248 ".pushsection .fixup,\"ax\"\n" \ 253 ".pushsection .fixup,\"ax\"\n" \
249 "0: { movei %0, %4; j 9f }\n" \ 254 "0: { movei %0, %4; j 9f }\n" \
250 ".section __ex_table,\"a\"\n" \ 255 ".section __ex_table,\"a\"\n" \
256 ".align 4\n" \
251 ".word 1b, 0b\n" \ 257 ".word 1b, 0b\n" \
252 ".word 2b, 0b\n" \ 258 ".word 2b, 0b\n" \
253 ".popsection\n" \ 259 ".popsection\n" \
@@ -567,37 +573,6 @@ static inline unsigned long __must_check flush_user(
567} 573}
568 574
569/** 575/**
570 * inv_user: - Invalidate a block of memory in user space from cache.
571 * @mem: Destination address, in user space.
572 * @len: Number of bytes to invalidate.
573 *
574 * Returns number of bytes that could not be invalidated.
575 * On success, this will be zero.
576 *
577 * Note that on Tile64, the "inv" operation is in fact a
578 * "flush and invalidate", so cache write-backs will occur prior
579 * to the cache being marked invalid.
580 */
581extern unsigned long inv_user_asm(void __user *mem, unsigned long len);
582static inline unsigned long __must_check __inv_user(
583 void __user *mem, unsigned long len)
584{
585 int retval;
586
587 might_fault();
588 retval = inv_user_asm(mem, len);
589 mb_incoherent();
590 return retval;
591}
592static inline unsigned long __must_check inv_user(
593 void __user *mem, unsigned long len)
594{
595 if (access_ok(VERIFY_WRITE, mem, len))
596 return __inv_user(mem, len);
597 return len;
598}
599
600/**
601 * finv_user: - Flush-inval a block of memory in user space from cache. 576 * finv_user: - Flush-inval a block of memory in user space from cache.
602 * @mem: Destination address, in user space. 577 * @mem: Destination address, in user space.
603 * @len: Number of bytes to invalidate. 578 * @len: Number of bytes to invalidate.
diff --git a/arch/tile/include/asm/unaligned.h b/arch/tile/include/asm/unaligned.h
index 37dfbe598872..5a58a0d11449 100644
--- a/arch/tile/include/asm/unaligned.h
+++ b/arch/tile/include/asm/unaligned.h
@@ -15,11 +15,15 @@
15#ifndef _ASM_TILE_UNALIGNED_H 15#ifndef _ASM_TILE_UNALIGNED_H
16#define _ASM_TILE_UNALIGNED_H 16#define _ASM_TILE_UNALIGNED_H
17 17
18#include <linux/unaligned/le_struct.h> 18/*
19#include <linux/unaligned/be_byteshift.h> 19 * We could implement faster get_unaligned_[be/le]64 using the ldna
20#include <linux/unaligned/generic.h> 20 * instruction on tilegx; however, we need to either copy all of the
21#define get_unaligned __get_unaligned_le 21 * other generic functions to here (which is pretty ugly) or else
22#define put_unaligned __put_unaligned_le 22 * modify both the generic code and other arch code to allow arch
23 * specific unaligned data access functions. Given these functions
24 * are not often called, we'll stick with the generic version.
25 */
26#include <asm-generic/unaligned.h>
23 27
24/* 28/*
25 * Is the kernel doing fixups of unaligned accesses? If <0, no kernel 29 * Is the kernel doing fixups of unaligned accesses? If <0, no kernel
diff --git a/arch/tile/include/asm/vdso.h b/arch/tile/include/asm/vdso.h
new file mode 100644
index 000000000000..9f6a78d665fa
--- /dev/null
+++ b/arch/tile/include/asm/vdso.h
@@ -0,0 +1,49 @@
1/*
2 * Copyright 2012 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_VDSO_H__
16#define __TILE_VDSO_H__
17
18#include <linux/types.h>
19
20/*
21 * Note about the vdso_data structure:
22 *
23 * NEVER USE THEM IN USERSPACE CODE DIRECTLY. The layout of the
24 * structure is supposed to be known only to the function in the vdso
25 * itself and may change without notice.
26 */
27
28struct vdso_data {
29 __u64 tz_update_count; /* Timezone atomicity ctr */
30 __u64 tb_update_count; /* Timebase atomicity ctr */
31 __u64 xtime_tod_stamp; /* TOD clock for xtime */
32 __u64 xtime_clock_sec; /* Kernel time second */
33 __u64 xtime_clock_nsec; /* Kernel time nanosecond */
34 __u64 wtom_clock_sec; /* Wall to monotonic clock second */
35 __u64 wtom_clock_nsec; /* Wall to monotonic clock nanosecond */
36 __u32 mult; /* Cycle to nanosecond multiplier */
37 __u32 shift; /* Cycle to nanosecond divisor (power of two) */
38 __u32 tz_minuteswest; /* Minutes west of Greenwich */
39 __u32 tz_dsttime; /* Type of dst correction */
40};
41
42extern struct vdso_data *vdso_data;
43
44/* __vdso_rt_sigreturn is defined with the addresses in the vdso page. */
45extern void __vdso_rt_sigreturn(void);
46
47extern int setup_vdso_pages(void);
48
49#endif /* __TILE_VDSO_H__ */
diff --git a/arch/tile/include/gxio/iorpc_trio.h b/arch/tile/include/gxio/iorpc_trio.h
index 58105c31228b..d95b96fd6c93 100644
--- a/arch/tile/include/gxio/iorpc_trio.h
+++ b/arch/tile/include/gxio/iorpc_trio.h
@@ -30,6 +30,7 @@
30 30
31#define GXIO_TRIO_OP_ALLOC_MEMORY_MAPS IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1404) 31#define GXIO_TRIO_OP_ALLOC_MEMORY_MAPS IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1404)
32 32
33#define GXIO_TRIO_OP_ALLOC_SCATTER_QUEUES IORPC_OPCODE(IORPC_FORMAT_NONE, 0x140e)
33#define GXIO_TRIO_OP_ALLOC_PIO_REGIONS IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1412) 34#define GXIO_TRIO_OP_ALLOC_PIO_REGIONS IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1412)
34 35
35#define GXIO_TRIO_OP_INIT_PIO_REGION_AUX IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1414) 36#define GXIO_TRIO_OP_INIT_PIO_REGION_AUX IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1414)
@@ -54,6 +55,10 @@ int gxio_trio_alloc_memory_maps(gxio_trio_context_t * context,
54 unsigned int flags); 55 unsigned int flags);
55 56
56 57
58int gxio_trio_alloc_scatter_queues(gxio_trio_context_t * context,
59 unsigned int count, unsigned int first,
60 unsigned int flags);
61
57int gxio_trio_alloc_pio_regions(gxio_trio_context_t * context, 62int gxio_trio_alloc_pio_regions(gxio_trio_context_t * context,
58 unsigned int count, unsigned int first, 63 unsigned int count, unsigned int first,
59 unsigned int flags); 64 unsigned int flags);
diff --git a/arch/tile/include/gxio/iorpc_uart.h b/arch/tile/include/gxio/iorpc_uart.h
new file mode 100644
index 000000000000..55429d48ea56
--- /dev/null
+++ b/arch/tile/include/gxio/iorpc_uart.h
@@ -0,0 +1,40 @@
1/*
2 * Copyright 2013 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#ifndef __GXIO_UART_LINUX_RPC_H__
17#define __GXIO_UART_LINUX_RPC_H__
18
19#include <hv/iorpc.h>
20
21#include <hv/drv_uart_intf.h>
22#include <gxio/uart.h>
23#include <gxio/kiorpc.h>
24#include <linux/string.h>
25#include <linux/module.h>
26#include <asm/pgtable.h>
27
28#define GXIO_UART_OP_CFG_INTERRUPT IORPC_OPCODE(IORPC_FORMAT_KERNEL_INTERRUPT, 0x1900)
29#define GXIO_UART_OP_GET_MMIO_BASE IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x8000)
30#define GXIO_UART_OP_CHECK_MMIO_OFFSET IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x8001)
31
32int gxio_uart_cfg_interrupt(gxio_uart_context_t *context, int inter_x,
33 int inter_y, int inter_ipi, int inter_event);
34
35int gxio_uart_get_mmio_base(gxio_uart_context_t *context, HV_PTE *base);
36
37int gxio_uart_check_mmio_offset(gxio_uart_context_t *context,
38 unsigned long offset, unsigned long size);
39
40#endif /* !__GXIO_UART_LINUX_RPC_H__ */
diff --git a/arch/tile/include/gxio/uart.h b/arch/tile/include/gxio/uart.h
new file mode 100644
index 000000000000..438ee7e46c7b
--- /dev/null
+++ b/arch/tile/include/gxio/uart.h
@@ -0,0 +1,105 @@
1/*
2 * Copyright 2013 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 _GXIO_UART_H_
16#define _GXIO_UART_H_
17
18#include "common.h"
19
20#include <hv/drv_uart_intf.h>
21#include <hv/iorpc.h>
22
23/*
24 *
25 * An API for manipulating UART interface.
26 */
27
28/*
29 *
30 * The Rshim allows access to the processor's UART interface.
31 */
32
33/* A context object used to manage UART resources. */
34typedef struct {
35
36 /* File descriptor for calling up to the hypervisor. */
37 int fd;
38
39 /* The VA at which our MMIO registers are mapped. */
40 char *mmio_base;
41
42} gxio_uart_context_t;
43
44/* Request UART interrupts.
45 *
46 * Request that interrupts be delivered to a tile when the UART's
47 * Receive FIFO is written, or the Write FIFO is read.
48 *
49 * @param context Pointer to a properly initialized gxio_uart_context_t.
50 * @param bind_cpu_x X coordinate of CPU to which interrupt will be delivered.
51 * @param bind_cpu_y Y coordinate of CPU to which interrupt will be delivered.
52 * @param bind_interrupt IPI interrupt number.
53 * @param bind_event Sub-interrupt event bit number; a negative value can
54 * disable the interrupt.
55 * @return Zero if all of the requested UART events were successfully
56 * configured to interrupt.
57 */
58extern int gxio_uart_cfg_interrupt(gxio_uart_context_t *context,
59 int bind_cpu_x,
60 int bind_cpu_y,
61 int bind_interrupt, int bind_event);
62
63/* Initialize a UART context.
64 *
65 * A properly initialized context must be obtained before any of the other
66 * gxio_uart routines may be used.
67 *
68 * @param context Pointer to a gxio_uart_context_t, which will be initialized
69 * by this routine, if it succeeds.
70 * @param uart_index Index of the UART to use.
71 * @return Zero if the context was successfully initialized, else a
72 * GXIO_ERR_xxx error code.
73 */
74extern int gxio_uart_init(gxio_uart_context_t *context, int uart_index);
75
76/* Destroy a UART context.
77 *
78 * Once destroyed, a context may not be used with any gxio_uart routines
79 * other than gxio_uart_init(). After this routine returns, no further
80 * interrupts requested on this context will be delivered. The state and
81 * configuration of the pins which had been attached to this context are
82 * unchanged by this operation.
83 *
84 * @param context Pointer to a gxio_uart_context_t.
85 * @return Zero if the context was successfully destroyed, else a
86 * GXIO_ERR_xxx error code.
87 */
88extern int gxio_uart_destroy(gxio_uart_context_t *context);
89
90/* Write UART register.
91 * @param context Pointer to a gxio_uart_context_t.
92 * @param offset UART register offset.
93 * @param word Data will be wrote to UART reigister.
94 */
95extern void gxio_uart_write(gxio_uart_context_t *context, uint64_t offset,
96 uint64_t word);
97
98/* Read UART register.
99 * @param context Pointer to a gxio_uart_context_t.
100 * @param offset UART register offset.
101 * @return Data read from UART register.
102 */
103extern uint64_t gxio_uart_read(gxio_uart_context_t *context, uint64_t offset);
104
105#endif /* _GXIO_UART_H_ */
diff --git a/arch/tile/include/hv/drv_trio_intf.h b/arch/tile/include/hv/drv_trio_intf.h
index ef9f3f52ee27..237e04dee66c 100644
--- a/arch/tile/include/hv/drv_trio_intf.h
+++ b/arch/tile/include/hv/drv_trio_intf.h
@@ -64,8 +64,9 @@ struct pcie_port_property
64 * will not consider it an error if the link comes up as a x8 link. */ 64 * will not consider it an error if the link comes up as a x8 link. */
65 uint8_t allow_x8: 1; 65 uint8_t allow_x8: 1;
66 66
67 /** Reserved. */ 67 /** If true, this link is connected to a device which may or may not
68 uint8_t reserved: 1; 68 * be present. */
69 uint8_t removable: 1;
69 70
70}; 71};
71 72
@@ -167,6 +168,9 @@ pcie_stream_intr_config_sel_t;
167struct pcie_trio_ports_property 168struct pcie_trio_ports_property
168{ 169{
169 struct pcie_port_property ports[TILEGX_TRIO_PCIES]; 170 struct pcie_port_property ports[TILEGX_TRIO_PCIES];
171
172 /** Set if this TRIO belongs to a Gx72 device. */
173 uint8_t is_gx72;
170}; 174};
171 175
172/* Flags indicating traffic class. */ 176/* Flags indicating traffic class. */
diff --git a/arch/tile/include/hv/drv_uart_intf.h b/arch/tile/include/hv/drv_uart_intf.h
new file mode 100644
index 000000000000..f5379e2404fd
--- /dev/null
+++ b/arch/tile/include/hv/drv_uart_intf.h
@@ -0,0 +1,33 @@
1/*
2 * Copyright 2013 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 * Interface definitions for the UART driver.
17 */
18
19#ifndef _SYS_HV_DRV_UART_INTF_H
20#define _SYS_HV_DRV_UART_INTF_H
21
22#include <arch/uart.h>
23
24/** Number of UART ports supported. */
25#define TILEGX_UART_NR 2
26
27/** The mmap file offset (PA) of the UART MMIO region. */
28#define HV_UART_MMIO_OFFSET 0
29
30/** The maximum size of the UARTs MMIO region (64K Bytes). */
31#define HV_UART_MMIO_SIZE (1UL << 16)
32
33#endif /* _SYS_HV_DRV_UART_INTF_H */
diff --git a/arch/tile/include/hv/hypervisor.h b/arch/tile/include/hv/hypervisor.h
index 837dca5328c2..dfcdeb61ba34 100644
--- a/arch/tile/include/hv/hypervisor.h
+++ b/arch/tile/include/hv/hypervisor.h
@@ -318,8 +318,11 @@
318/** hv_set_pte_super_shift */ 318/** hv_set_pte_super_shift */
319#define HV_DISPATCH_SET_PTE_SUPER_SHIFT 57 319#define HV_DISPATCH_SET_PTE_SUPER_SHIFT 57
320 320
321/** hv_console_set_ipi */
322#define HV_DISPATCH_CONSOLE_SET_IPI 63
323
321/** One more than the largest dispatch value */ 324/** One more than the largest dispatch value */
322#define _HV_DISPATCH_END 58 325#define _HV_DISPATCH_END 64
323 326
324 327
325#ifndef __ASSEMBLER__ 328#ifndef __ASSEMBLER__
@@ -541,14 +544,24 @@ typedef enum {
541 HV_CONFSTR_CPUMOD_REV = 18, 544 HV_CONFSTR_CPUMOD_REV = 18,
542 545
543 /** Human-readable CPU module description. */ 546 /** Human-readable CPU module description. */
544 HV_CONFSTR_CPUMOD_DESC = 19 547 HV_CONFSTR_CPUMOD_DESC = 19,
548
549 /** Per-tile hypervisor statistics. When this identifier is specified,
550 * the hv_confstr call takes two extra arguments. The first is the
551 * HV_XY_TO_LOTAR of the target tile's coordinates. The second is
552 * a flag word. The only current flag is the lowest bit, which means
553 * "zero out the stats instead of retrieving them"; in this case the
554 * buffer and buffer length are ignored. */
555 HV_CONFSTR_HV_STATS = 20
545 556
546} HV_ConfstrQuery; 557} HV_ConfstrQuery;
547 558
548/** Query a configuration string from the hypervisor. 559/** Query a configuration string from the hypervisor.
549 * 560 *
550 * @param query Identifier for the specific string to be retrieved 561 * @param query Identifier for the specific string to be retrieved
551 * (HV_CONFSTR_xxx). 562 * (HV_CONFSTR_xxx). Some strings may require or permit extra
563 * arguments to be appended which select specific objects to be
564 * described; see the string descriptions above.
552 * @param buf Buffer in which to place the string. 565 * @param buf Buffer in which to place the string.
553 * @param len Length of the buffer. 566 * @param len Length of the buffer.
554 * @return If query is valid, then the length of the corresponding string, 567 * @return If query is valid, then the length of the corresponding string,
@@ -556,21 +569,16 @@ typedef enum {
556 * was truncated. If query is invalid, HV_EINVAL. If the specified 569 * was truncated. If query is invalid, HV_EINVAL. If the specified
557 * buffer is not writable by the client, HV_EFAULT. 570 * buffer is not writable by the client, HV_EFAULT.
558 */ 571 */
559int hv_confstr(HV_ConfstrQuery query, HV_VirtAddr buf, int len); 572int hv_confstr(HV_ConfstrQuery query, HV_VirtAddr buf, int len, ...);
560 573
561/** Tile coordinate */ 574/** Tile coordinate */
562typedef struct 575typedef struct
563{ 576{
564#ifndef __BIG_ENDIAN__
565 /** X coordinate, relative to supervisor's top-left coordinate */ 577 /** X coordinate, relative to supervisor's top-left coordinate */
566 int x; 578 int x;
567 579
568 /** Y coordinate, relative to supervisor's top-left coordinate */ 580 /** Y coordinate, relative to supervisor's top-left coordinate */
569 int y; 581 int y;
570#else
571 int y;
572 int x;
573#endif
574} HV_Coord; 582} HV_Coord;
575 583
576 584
@@ -585,6 +593,30 @@ typedef struct
585 */ 593 */
586int hv_get_ipi_pte(HV_Coord tile, int pl, HV_PTE* pte); 594int hv_get_ipi_pte(HV_Coord tile, int pl, HV_PTE* pte);
587 595
596/** Configure the console interrupt.
597 *
598 * When the console client interrupt is enabled, the hypervisor will
599 * deliver the specified IPI to the client in the following situations:
600 *
601 * - The console has at least one character available for input.
602 *
603 * - The console can accept new characters for output, and the last call
604 * to hv_console_write() did not write all of the characters requested
605 * by the client.
606 *
607 * Note that in some system configurations, console interrupt will not
608 * be available; clients should be prepared for this routine to fail and
609 * to fall back to periodic console polling in that case.
610 *
611 * @param ipi Index of the IPI register which will receive the interrupt.
612 * @param event IPI event number for console interrupt. If less than 0,
613 * disable the console IPI interrupt.
614 * @param coord Tile to be targeted for console interrupt.
615 * @return 0 on success, otherwise, HV_EINVAL if illegal parameter,
616 * HV_ENOTSUP if console interrupt are not available.
617 */
618int hv_console_set_ipi(int ipi, int event, HV_Coord coord);
619
588#else /* !CHIP_HAS_IPI() */ 620#else /* !CHIP_HAS_IPI() */
589 621
590/** A set of interrupts. */ 622/** A set of interrupts. */
@@ -1092,13 +1124,8 @@ HV_VirtAddrRange hv_inquire_virtual(int idx);
1092/** A range of ASID values. */ 1124/** A range of ASID values. */
1093typedef struct 1125typedef struct
1094{ 1126{
1095#ifndef __BIG_ENDIAN__
1096 HV_ASID start; /**< First ASID in the range. */ 1127 HV_ASID start; /**< First ASID in the range. */
1097 unsigned int size; /**< Number of ASIDs. Zero for an invalid range. */ 1128 unsigned int size; /**< Number of ASIDs. Zero for an invalid range. */
1098#else
1099 unsigned int size; /**< Number of ASIDs. Zero for an invalid range. */
1100 HV_ASID start; /**< First ASID in the range. */
1101#endif
1102} HV_ASIDRange; 1129} HV_ASIDRange;
1103 1130
1104/** Returns information about a range of ASIDs. 1131/** Returns information about a range of ASIDs.
@@ -1422,7 +1449,6 @@ typedef enum
1422/** Message recipient. */ 1449/** Message recipient. */
1423typedef struct 1450typedef struct
1424{ 1451{
1425#ifndef __BIG_ENDIAN__
1426 /** X coordinate, relative to supervisor's top-left coordinate */ 1452 /** X coordinate, relative to supervisor's top-left coordinate */
1427 unsigned int x:11; 1453 unsigned int x:11;
1428 1454
@@ -1431,11 +1457,6 @@ typedef struct
1431 1457
1432 /** Status of this recipient */ 1458 /** Status of this recipient */
1433 HV_Recip_State state:10; 1459 HV_Recip_State state:10;
1434#else //__BIG_ENDIAN__
1435 HV_Recip_State state:10;
1436 unsigned int y:11;
1437 unsigned int x:11;
1438#endif
1439} HV_Recipient; 1460} HV_Recipient;
1440 1461
1441/** Send a message to a set of recipients. 1462/** Send a message to a set of recipients.
diff --git a/arch/tile/include/uapi/arch/Kbuild b/arch/tile/include/uapi/arch/Kbuild
index 4ebc34f4768d..97dfbecec6b6 100644
--- a/arch/tile/include/uapi/arch/Kbuild
+++ b/arch/tile/include/uapi/arch/Kbuild
@@ -1,7 +1,6 @@
1# UAPI Header export list 1# UAPI Header export list
2header-y += abi.h 2header-y += abi.h
3header-y += chip.h 3header-y += chip.h
4header-y += chip_tile64.h
5header-y += chip_tilegx.h 4header-y += chip_tilegx.h
6header-y += chip_tilepro.h 5header-y += chip_tilepro.h
7header-y += icache.h 6header-y += icache.h
diff --git a/arch/tile/include/uapi/arch/chip.h b/arch/tile/include/uapi/arch/chip.h
index 926d3db0e91e..4c91f90b9369 100644
--- a/arch/tile/include/uapi/arch/chip.h
+++ b/arch/tile/include/uapi/arch/chip.h
@@ -12,9 +12,7 @@
12 * more details. 12 * more details.
13 */ 13 */
14 14
15#if __tile_chip__ == 0 15#if __tile_chip__ == 1
16#include <arch/chip_tile64.h>
17#elif __tile_chip__ == 1
18#include <arch/chip_tilepro.h> 16#include <arch/chip_tilepro.h>
19#elif defined(__tilegx__) 17#elif defined(__tilegx__)
20#include <arch/chip_tilegx.h> 18#include <arch/chip_tilegx.h>
diff --git a/arch/tile/include/uapi/arch/chip_tile64.h b/arch/tile/include/uapi/arch/chip_tile64.h
deleted file mode 100644
index 261aaba092d4..000000000000
--- a/arch/tile/include/uapi/arch/chip_tile64.h
+++ /dev/null
@@ -1,258 +0,0 @@
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/** Is the DSTREAM_PF SPR supported? */
154#define CHIP_HAS_DSTREAM_PF() 0
155
156/** Log of the number of mshims we have. */
157#define CHIP_LOG_NUM_MSHIMS() 2
158
159/** Are the bases of the interrupt vector areas fixed? */
160#define CHIP_HAS_FIXED_INTVEC_BASE() 1
161
162/** Are the interrupt masks split up into 2 SPRs? */
163#define CHIP_HAS_SPLIT_INTR_MASK() 1
164
165/** Is the cycle count split up into 2 SPRs? */
166#define CHIP_HAS_SPLIT_CYCLE() 1
167
168/** Does the chip have a static network? */
169#define CHIP_HAS_SN() 1
170
171/** Does the chip have a static network processor? */
172#define CHIP_HAS_SN_PROC() 1
173
174/** Size of the L1 static network processor instruction cache, in bytes. */
175#define CHIP_L1SNI_CACHE_SIZE() 2048
176
177/** Does the chip have DMA support in each tile? */
178#define CHIP_HAS_TILE_DMA() 1
179
180/** Does the chip have the second revision of the directly accessible
181 * dynamic networks? This encapsulates a number of characteristics,
182 * including the absence of the catch-all, the absence of inline message
183 * tags, the absence of support for network context-switching, and so on.
184 */
185#define CHIP_HAS_REV1_XDN() 0
186
187/** Does the chip have cmpexch and similar (fetchadd, exch, etc.)? */
188#define CHIP_HAS_CMPEXCH() 0
189
190/** Does the chip have memory-mapped I/O support? */
191#define CHIP_HAS_MMIO() 0
192
193/** Does the chip have post-completion interrupts? */
194#define CHIP_HAS_POST_COMPLETION_INTERRUPTS() 0
195
196/** Does the chip have native single step support? */
197#define CHIP_HAS_SINGLE_STEP() 0
198
199#ifndef __OPEN_SOURCE__ /* features only relevant to hypervisor-level code */
200
201/** How many entries are present in the instruction TLB? */
202#define CHIP_ITLB_ENTRIES() 8
203
204/** How many entries are present in the data TLB? */
205#define CHIP_DTLB_ENTRIES() 16
206
207/** How many MAF entries does the XAUI shim have? */
208#define CHIP_XAUI_MAF_ENTRIES() 16
209
210/** Does the memory shim have a source-id table? */
211#define CHIP_HAS_MSHIM_SRCID_TABLE() 1
212
213/** Does the L1 instruction cache clear on reset? */
214#define CHIP_HAS_L1I_CLEAR_ON_RESET() 0
215
216/** Does the chip come out of reset with valid coordinates on all tiles?
217 * Note that if defined, this also implies that the upper left is 1,1.
218 */
219#define CHIP_HAS_VALID_TILE_COORD_RESET() 0
220
221/** Does the chip have unified packet formats? */
222#define CHIP_HAS_UNIFIED_PACKET_FORMATS() 0
223
224/** Does the chip support write reordering? */
225#define CHIP_HAS_WRITE_REORDERING() 0
226
227/** Does the chip support Y-X routing as well as X-Y? */
228#define CHIP_HAS_Y_X_ROUTING() 0
229
230/** Is INTCTRL_3 managed with the correct MPL? */
231#define CHIP_HAS_INTCTRL_3_STATUS_FIX() 0
232
233/** Is it possible to configure the chip to be big-endian? */
234#define CHIP_HAS_BIG_ENDIAN_CONFIG() 0
235
236/** Is the CACHE_RED_WAY_OVERRIDDEN SPR supported? */
237#define CHIP_HAS_CACHE_RED_WAY_OVERRIDDEN() 0
238
239/** Is the DIAG_TRACE_WAY SPR supported? */
240#define CHIP_HAS_DIAG_TRACE_WAY() 0
241
242/** Is the MEM_STRIPE_CONFIG SPR supported? */
243#define CHIP_HAS_MEM_STRIPE_CONFIG() 0
244
245/** Are the TLB_PERF SPRs supported? */
246#define CHIP_HAS_TLB_PERF() 0
247
248/** Is the VDN_SNOOP_SHIM_CTL SPR supported? */
249#define CHIP_HAS_VDN_SNOOP_SHIM_CTL() 0
250
251/** Does the chip support rev1 DMA packets? */
252#define CHIP_HAS_REV1_DMA_PACKETS() 0
253
254/** Does the chip have an IPI shim? */
255#define CHIP_HAS_IPI() 0
256
257#endif /* !__OPEN_SOURCE__ */
258#endif /* __ARCH_CHIP_H__ */
diff --git a/arch/tile/include/uapi/arch/opcode_tilegx.h b/arch/tile/include/uapi/arch/opcode_tilegx.h
index c14d02c81600..d76ff2db745e 100644
--- a/arch/tile/include/uapi/arch/opcode_tilegx.h
+++ b/arch/tile/include/uapi/arch/opcode_tilegx.h
@@ -61,6 +61,7 @@ typedef tilegx_bundle_bits tile_bundle_bits;
61#define TILE_BUNDLE_ALIGNMENT_IN_BYTES TILEGX_BUNDLE_ALIGNMENT_IN_BYTES 61#define TILE_BUNDLE_ALIGNMENT_IN_BYTES TILEGX_BUNDLE_ALIGNMENT_IN_BYTES
62#define TILE_LOG2_BUNDLE_ALIGNMENT_IN_BYTES \ 62#define TILE_LOG2_BUNDLE_ALIGNMENT_IN_BYTES \
63 TILEGX_LOG2_BUNDLE_ALIGNMENT_IN_BYTES 63 TILEGX_LOG2_BUNDLE_ALIGNMENT_IN_BYTES
64#define TILE_BPT_BUNDLE TILEGX_BPT_BUNDLE
64 65
65/* 64-bit pattern for a { bpt ; nop } bundle. */ 66/* 64-bit pattern for a { bpt ; nop } bundle. */
66#define TILEGX_BPT_BUNDLE 0x286a44ae51485000ULL 67#define TILEGX_BPT_BUNDLE 0x286a44ae51485000ULL
diff --git a/arch/tile/include/uapi/arch/opcode_tilepro.h b/arch/tile/include/uapi/arch/opcode_tilepro.h
index 71b763b8ce83..4451cff1a861 100644
--- a/arch/tile/include/uapi/arch/opcode_tilepro.h
+++ b/arch/tile/include/uapi/arch/opcode_tilepro.h
@@ -71,6 +71,7 @@ typedef tilepro_bundle_bits tile_bundle_bits;
71#define TILE_BUNDLE_ALIGNMENT_IN_BYTES TILEPRO_BUNDLE_ALIGNMENT_IN_BYTES 71#define TILE_BUNDLE_ALIGNMENT_IN_BYTES TILEPRO_BUNDLE_ALIGNMENT_IN_BYTES
72#define TILE_LOG2_BUNDLE_ALIGNMENT_IN_BYTES \ 72#define TILE_LOG2_BUNDLE_ALIGNMENT_IN_BYTES \
73 TILEPRO_LOG2_BUNDLE_ALIGNMENT_IN_BYTES 73 TILEPRO_LOG2_BUNDLE_ALIGNMENT_IN_BYTES
74#define TILE_BPT_BUNDLE TILEPRO_BPT_BUNDLE
74 75
75/* 64-bit pattern for a { bpt ; nop } bundle. */ 76/* 64-bit pattern for a { bpt ; nop } bundle. */
76#define TILEPRO_BPT_BUNDLE 0x400b3cae70166000ULL 77#define TILEPRO_BPT_BUNDLE 0x400b3cae70166000ULL
diff --git a/arch/tile/include/uapi/arch/spr_def_32.h b/arch/tile/include/uapi/arch/spr_def_32.h
index c689446e6284..78daa3146d25 100644
--- a/arch/tile/include/uapi/arch/spr_def_32.h
+++ b/arch/tile/include/uapi/arch/spr_def_32.h
@@ -200,8 +200,6 @@
200#define SPR_SIM_CONTROL 0x4e0c 200#define SPR_SIM_CONTROL 0x4e0c
201#define SPR_SNCTL 0x0805 201#define SPR_SNCTL 0x0805
202#define SPR_SNCTL__FRZFABRIC_MASK 0x1 202#define SPR_SNCTL__FRZFABRIC_MASK 0x1
203#define SPR_SNCTL__FRZPROC_MASK 0x2
204#define SPR_SNPC 0x080b
205#define SPR_SNSTATIC 0x080c 203#define SPR_SNSTATIC 0x080c
206#define SPR_SYSTEM_SAVE_0_0 0x4b00 204#define SPR_SYSTEM_SAVE_0_0 0x4b00
207#define SPR_SYSTEM_SAVE_0_1 0x4b01 205#define SPR_SYSTEM_SAVE_0_1 0x4b01
diff --git a/arch/tile/include/uapi/asm/auxvec.h b/arch/tile/include/uapi/asm/auxvec.h
index 1d393edb0641..c93e92709f14 100644
--- a/arch/tile/include/uapi/asm/auxvec.h
+++ b/arch/tile/include/uapi/asm/auxvec.h
@@ -15,6 +15,7 @@
15#ifndef _ASM_TILE_AUXVEC_H 15#ifndef _ASM_TILE_AUXVEC_H
16#define _ASM_TILE_AUXVEC_H 16#define _ASM_TILE_AUXVEC_H
17 17
18/* No extensions to auxvec */ 18/* The vDSO location. */
19#define AT_SYSINFO_EHDR 33
19 20
20#endif /* _ASM_TILE_AUXVEC_H */ 21#endif /* _ASM_TILE_AUXVEC_H */
diff --git a/arch/tile/include/uapi/asm/cachectl.h b/arch/tile/include/uapi/asm/cachectl.h
index af4c9f9154d1..572ddcad2090 100644
--- a/arch/tile/include/uapi/asm/cachectl.h
+++ b/arch/tile/include/uapi/asm/cachectl.h
@@ -29,8 +29,8 @@
29 * to honor the arguments at some point.) 29 * to honor the arguments at some point.)
30 * 30 *
31 * Flush and invalidation of memory can normally be performed with the 31 * Flush and invalidation of memory can normally be performed with the
32 * __insn_flush(), __insn_inv(), and __insn_finv() instructions from 32 * __insn_flush() and __insn_finv() instructions from userspace.
33 * userspace. The DCACHE option to the system call allows userspace 33 * The DCACHE option to the system call allows userspace
34 * to flush the entire L1+L2 data cache from the core. In this case, 34 * to flush the entire L1+L2 data cache from the core. In this case,
35 * the address and length arguments are not used. The DCACHE flush is 35 * the address and length arguments are not used. The DCACHE flush is
36 * restricted to the current core, not all cores in the address space. 36 * restricted to the current core, not all cores in the address space.
diff --git a/arch/tile/kernel/Makefile b/arch/tile/kernel/Makefile
index 5334be8e2538..27a2bf39dae8 100644
--- a/arch/tile/kernel/Makefile
+++ b/arch/tile/kernel/Makefile
@@ -3,11 +3,17 @@
3# 3#
4 4
5extra-y := vmlinux.lds head_$(BITS).o 5extra-y := vmlinux.lds head_$(BITS).o
6obj-y := backtrace.o entry.o irq.o messaging.o \ 6obj-y := backtrace.o entry.o hvglue.o irq.o messaging.o \
7 pci-dma.o proc.o process.o ptrace.o reboot.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 sysfs.o time.o traps.o \ 8 setup.o signal.o single_step.o stack.o sys.o \
9 sysfs.o time.o traps.o unaligned.o vdso.o \
9 intvec_$(BITS).o regs_$(BITS).o tile-desc_$(BITS).o 10 intvec_$(BITS).o regs_$(BITS).o tile-desc_$(BITS).o
10 11
12ifdef CONFIG_FUNCTION_TRACER
13CFLAGS_REMOVE_ftrace.o = -pg
14CFLAGS_REMOVE_early_printk.o = -pg
15endif
16
11obj-$(CONFIG_HARDWALL) += hardwall.o 17obj-$(CONFIG_HARDWALL) += hardwall.o
12obj-$(CONFIG_COMPAT) += compat.o compat_signal.o 18obj-$(CONFIG_COMPAT) += compat.o compat_signal.o
13obj-$(CONFIG_SMP) += smpboot.o smp.o tlb.o 19obj-$(CONFIG_SMP) += smpboot.o smp.o tlb.o
@@ -20,3 +26,9 @@ else
20obj-$(CONFIG_PCI) += pci.o 26obj-$(CONFIG_PCI) += pci.o
21endif 27endif
22obj-$(CONFIG_TILE_USB) += usb.o 28obj-$(CONFIG_TILE_USB) += usb.o
29obj-$(CONFIG_TILE_HVGLUE_TRACE) += hvglue_trace.o
30obj-$(CONFIG_FUNCTION_TRACER) += ftrace.o mcount_64.o
31obj-$(CONFIG_KPROBES) += kprobes.o
32obj-$(CONFIG_KGDB) += kgdb.o
33
34obj-y += vdso/
diff --git a/arch/tile/kernel/asm-offsets.c b/arch/tile/kernel/asm-offsets.c
index 01ddf19cc36d..375e7c321eef 100644
--- a/arch/tile/kernel/asm-offsets.c
+++ b/arch/tile/kernel/asm-offsets.c
@@ -14,13 +14,6 @@
14 * Generates definitions from c-type structures used by assembly sources. 14 * Generates definitions from c-type structures used by assembly sources.
15 */ 15 */
16 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. */ 17/* Check for compatible compiler early in the build. */
25#ifdef CONFIG_TILEGX 18#ifdef CONFIG_TILEGX
26# ifndef __tilegx__ 19# ifndef __tilegx__
@@ -31,46 +24,61 @@
31# endif 24# endif
32#else 25#else
33# ifdef __tilegx__ 26# ifdef __tilegx__
34# error Can not build TILEPro/TILE64 configurations with tilegx compiler 27# error Can not build TILEPro configurations with tilegx compiler
35# endif 28# endif
36#endif 29#endif
37 30
31#include <linux/kbuild.h>
32#include <linux/thread_info.h>
33#include <linux/sched.h>
34#include <linux/hardirq.h>
35#include <linux/ptrace.h>
36#include <hv/hypervisor.h>
37
38void foo(void) 38void foo(void)
39{ 39{
40 DEFINE(SINGLESTEP_STATE_BUFFER_OFFSET, \ 40 DEFINE(SINGLESTEP_STATE_BUFFER_OFFSET,
41 offsetof(struct single_step_state, buffer)); 41 offsetof(struct single_step_state, buffer));
42 DEFINE(SINGLESTEP_STATE_FLAGS_OFFSET, \ 42 DEFINE(SINGLESTEP_STATE_FLAGS_OFFSET,
43 offsetof(struct single_step_state, flags)); 43 offsetof(struct single_step_state, flags));
44 DEFINE(SINGLESTEP_STATE_ORIG_PC_OFFSET, \ 44 DEFINE(SINGLESTEP_STATE_ORIG_PC_OFFSET,
45 offsetof(struct single_step_state, orig_pc)); 45 offsetof(struct single_step_state, orig_pc));
46 DEFINE(SINGLESTEP_STATE_NEXT_PC_OFFSET, \ 46 DEFINE(SINGLESTEP_STATE_NEXT_PC_OFFSET,
47 offsetof(struct single_step_state, next_pc)); 47 offsetof(struct single_step_state, next_pc));
48 DEFINE(SINGLESTEP_STATE_BRANCH_NEXT_PC_OFFSET, \ 48 DEFINE(SINGLESTEP_STATE_BRANCH_NEXT_PC_OFFSET,
49 offsetof(struct single_step_state, branch_next_pc)); 49 offsetof(struct single_step_state, branch_next_pc));
50 DEFINE(SINGLESTEP_STATE_UPDATE_VALUE_OFFSET, \ 50 DEFINE(SINGLESTEP_STATE_UPDATE_VALUE_OFFSET,
51 offsetof(struct single_step_state, update_value)); 51 offsetof(struct single_step_state, update_value));
52 52
53 DEFINE(THREAD_INFO_TASK_OFFSET, \ 53 DEFINE(THREAD_INFO_TASK_OFFSET,
54 offsetof(struct thread_info, task)); 54 offsetof(struct thread_info, task));
55 DEFINE(THREAD_INFO_FLAGS_OFFSET, \ 55 DEFINE(THREAD_INFO_FLAGS_OFFSET,
56 offsetof(struct thread_info, flags)); 56 offsetof(struct thread_info, flags));
57 DEFINE(THREAD_INFO_STATUS_OFFSET, \ 57 DEFINE(THREAD_INFO_STATUS_OFFSET,
58 offsetof(struct thread_info, status)); 58 offsetof(struct thread_info, status));
59 DEFINE(THREAD_INFO_HOMECACHE_CPU_OFFSET, \ 59 DEFINE(THREAD_INFO_HOMECACHE_CPU_OFFSET,
60 offsetof(struct thread_info, homecache_cpu)); 60 offsetof(struct thread_info, homecache_cpu));
61 DEFINE(THREAD_INFO_STEP_STATE_OFFSET, \ 61 DEFINE(THREAD_INFO_PREEMPT_COUNT_OFFSET,
62 offsetof(struct thread_info, preempt_count));
63 DEFINE(THREAD_INFO_STEP_STATE_OFFSET,
62 offsetof(struct thread_info, step_state)); 64 offsetof(struct thread_info, step_state));
65#ifdef __tilegx__
66 DEFINE(THREAD_INFO_UNALIGN_JIT_BASE_OFFSET,
67 offsetof(struct thread_info, unalign_jit_base));
68 DEFINE(THREAD_INFO_UNALIGN_JIT_TMP_OFFSET,
69 offsetof(struct thread_info, unalign_jit_tmp));
70#endif
63 71
64 DEFINE(TASK_STRUCT_THREAD_KSP_OFFSET, 72 DEFINE(TASK_STRUCT_THREAD_KSP_OFFSET,
65 offsetof(struct task_struct, thread.ksp)); 73 offsetof(struct task_struct, thread.ksp));
66 DEFINE(TASK_STRUCT_THREAD_PC_OFFSET, 74 DEFINE(TASK_STRUCT_THREAD_PC_OFFSET,
67 offsetof(struct task_struct, thread.pc)); 75 offsetof(struct task_struct, thread.pc));
68 76
69 DEFINE(HV_TOPOLOGY_WIDTH_OFFSET, \ 77 DEFINE(HV_TOPOLOGY_WIDTH_OFFSET,
70 offsetof(HV_Topology, width)); 78 offsetof(HV_Topology, width));
71 DEFINE(HV_TOPOLOGY_HEIGHT_OFFSET, \ 79 DEFINE(HV_TOPOLOGY_HEIGHT_OFFSET,
72 offsetof(HV_Topology, height)); 80 offsetof(HV_Topology, height));
73 81
74 DEFINE(IRQ_CPUSTAT_SYSCALL_COUNT_OFFSET, \ 82 DEFINE(IRQ_CPUSTAT_SYSCALL_COUNT_OFFSET,
75 offsetof(irq_cpustat_t, irq_syscall_count)); 83 offsetof(irq_cpustat_t, irq_syscall_count));
76} 84}
diff --git a/arch/tile/kernel/compat_signal.c b/arch/tile/kernel/compat_signal.c
index d0a052e725be..85e00b2f39bf 100644
--- a/arch/tile/kernel/compat_signal.c
+++ b/arch/tile/kernel/compat_signal.c
@@ -32,6 +32,7 @@
32#include <asm/ucontext.h> 32#include <asm/ucontext.h>
33#include <asm/sigframe.h> 33#include <asm/sigframe.h>
34#include <asm/syscalls.h> 34#include <asm/syscalls.h>
35#include <asm/vdso.h>
35#include <arch/interrupts.h> 36#include <arch/interrupts.h>
36 37
37struct compat_ucontext { 38struct compat_ucontext {
@@ -227,7 +228,7 @@ int compat_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
227 if (err) 228 if (err)
228 goto give_sigsegv; 229 goto give_sigsegv;
229 230
230 restorer = VDSO_BASE; 231 restorer = VDSO_SYM(&__vdso_rt_sigreturn);
231 if (ka->sa.sa_flags & SA_RESTORER) 232 if (ka->sa.sa_flags & SA_RESTORER)
232 restorer = ptr_to_compat_reg(ka->sa.sa_restorer); 233 restorer = ptr_to_compat_reg(ka->sa.sa_restorer);
233 234
diff --git a/arch/tile/kernel/early_printk.c b/arch/tile/kernel/early_printk.c
index 34d72a151bf3..b608e00e7f6d 100644
--- a/arch/tile/kernel/early_printk.c
+++ b/arch/tile/kernel/early_printk.c
@@ -23,19 +23,24 @@
23 23
24static void early_hv_write(struct console *con, const char *s, unsigned n) 24static void early_hv_write(struct console *con, const char *s, unsigned n)
25{ 25{
26 hv_console_write((HV_VirtAddr) s, n); 26 tile_console_write(s, n);
27
28 /*
29 * Convert NL to NLCR (close enough to CRNL) during early boot.
30 * We assume newlines are at the ends of strings, which turns out
31 * to be good enough for early boot console output.
32 */
33 if (n && s[n-1] == '\n')
34 tile_console_write("\r", 1);
27} 35}
28 36
29static struct console early_hv_console = { 37static struct console early_hv_console = {
30 .name = "earlyhv", 38 .name = "earlyhv",
31 .write = early_hv_write, 39 .write = early_hv_write,
32 .flags = CON_PRINTBUFFER, 40 .flags = CON_PRINTBUFFER | CON_BOOT,
33 .index = -1, 41 .index = -1,
34}; 42};
35 43
36/* Direct interface for emergencies */
37static int early_console_complete;
38
39void early_panic(const char *fmt, ...) 44void early_panic(const char *fmt, ...)
40{ 45{
41 va_list ap; 46 va_list ap;
@@ -43,51 +48,21 @@ void early_panic(const char *fmt, ...)
43 va_start(ap, fmt); 48 va_start(ap, fmt);
44 early_printk("Kernel panic - not syncing: "); 49 early_printk("Kernel panic - not syncing: ");
45 early_vprintk(fmt, ap); 50 early_vprintk(fmt, ap);
46 early_console->write(early_console, "\n", 1); 51 early_printk("\n");
47 va_end(ap); 52 va_end(ap);
48 dump_stack(); 53 dump_stack();
49 hv_halt(); 54 hv_halt();
50} 55}
51 56
52static int __initdata keep_early;
53
54static int __init setup_early_printk(char *str) 57static int __init setup_early_printk(char *str)
55{ 58{
56 if (early_console) 59 if (early_console)
57 return 1; 60 return 1;
58 61
59 if (str != NULL && strncmp(str, "keep", 4) == 0)
60 keep_early = 1;
61
62 early_console = &early_hv_console; 62 early_console = &early_hv_console;
63 register_console(early_console); 63 register_console(early_console);
64 64
65 return 0; 65 return 0;
66} 66}
67 67
68void __init disable_early_printk(void)
69{
70 early_console_complete = 1;
71 if (!early_console)
72 return;
73 if (!keep_early) {
74 early_printk("disabling early console\n");
75 unregister_console(early_console);
76 early_console = NULL;
77 } else {
78 early_printk("keeping early console\n");
79 }
80}
81
82void warn_early_printk(void)
83{
84 if (early_console_complete || early_console)
85 return;
86 early_printk("\
87Machine shutting down before console output is fully initialized.\n\
88You may wish to reboot and add the option 'earlyprintk' to your\n\
89boot command line to see any diagnostic early console output.\n\
90");
91}
92
93early_param("earlyprintk", setup_early_printk); 68early_param("earlyprintk", setup_early_printk);
diff --git a/arch/tile/kernel/entry.S b/arch/tile/kernel/entry.S
index f116cb0bce20..3d9175992a20 100644
--- a/arch/tile/kernel/entry.S
+++ b/arch/tile/kernel/entry.S
@@ -27,22 +27,6 @@ STD_ENTRY(current_text_addr)
27 { move r0, lr; jrp lr } 27 { move r0, lr; jrp lr }
28 STD_ENDPROC(current_text_addr) 28 STD_ENDPROC(current_text_addr)
29 29
30/*
31 * We don't run this function directly, but instead copy it to a page
32 * we map into every user process. See vdso_setup().
33 *
34 * Note that libc has a copy of this function that it uses to compare
35 * against the PC when a stack backtrace ends, so if this code is
36 * changed, the libc implementation(s) should also be updated.
37 */
38 .pushsection .data
39ENTRY(__rt_sigreturn)
40 moveli TREG_SYSCALL_NR_NAME,__NR_rt_sigreturn
41 swint1
42 ENDPROC(__rt_sigreturn)
43 ENTRY(__rt_sigreturn_end)
44 .popsection
45
46STD_ENTRY(dump_stack) 30STD_ENTRY(dump_stack)
47 { move r2, lr; lnk r1 } 31 { move r2, lr; lnk r1 }
48 { move r4, r52; addli r1, r1, dump_stack - . } 32 { move r4, r52; addli r1, r1, dump_stack - . }
diff --git a/arch/tile/kernel/ftrace.c b/arch/tile/kernel/ftrace.c
new file mode 100644
index 000000000000..f1c452092eeb
--- /dev/null
+++ b/arch/tile/kernel/ftrace.c
@@ -0,0 +1,246 @@
1/*
2 * Copyright 2012 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-Gx specific ftrace support
15 */
16
17#include <linux/ftrace.h>
18#include <linux/uaccess.h>
19
20#include <asm/cacheflush.h>
21#include <asm/ftrace.h>
22#include <asm/sections.h>
23
24#include <arch/opcode.h>
25
26#ifdef CONFIG_DYNAMIC_FTRACE
27
28static inline tilegx_bundle_bits NOP(void)
29{
30 return create_UnaryOpcodeExtension_X0(FNOP_UNARY_OPCODE_X0) |
31 create_RRROpcodeExtension_X0(UNARY_RRR_0_OPCODE_X0) |
32 create_Opcode_X0(RRR_0_OPCODE_X0) |
33 create_UnaryOpcodeExtension_X1(NOP_UNARY_OPCODE_X1) |
34 create_RRROpcodeExtension_X1(UNARY_RRR_0_OPCODE_X1) |
35 create_Opcode_X1(RRR_0_OPCODE_X1);
36}
37
38static int machine_stopped __read_mostly;
39
40int ftrace_arch_code_modify_prepare(void)
41{
42 machine_stopped = 1;
43 return 0;
44}
45
46int ftrace_arch_code_modify_post_process(void)
47{
48 flush_icache_range(0, CHIP_L1I_CACHE_SIZE());
49 machine_stopped = 0;
50 return 0;
51}
52
53/*
54 * Put { move r10, lr; jal ftrace_caller } in a bundle, this lets dynamic
55 * tracer just add one cycle overhead to every kernel function when disabled.
56 */
57static unsigned long ftrace_gen_branch(unsigned long pc, unsigned long addr,
58 bool link)
59{
60 tilegx_bundle_bits opcode_x0, opcode_x1;
61 long pcrel_by_instr = (addr - pc) >> TILEGX_LOG2_BUNDLE_SIZE_IN_BYTES;
62
63 if (link) {
64 /* opcode: jal addr */
65 opcode_x1 =
66 create_Opcode_X1(JUMP_OPCODE_X1) |
67 create_JumpOpcodeExtension_X1(JAL_JUMP_OPCODE_X1) |
68 create_JumpOff_X1(pcrel_by_instr);
69 } else {
70 /* opcode: j addr */
71 opcode_x1 =
72 create_Opcode_X1(JUMP_OPCODE_X1) |
73 create_JumpOpcodeExtension_X1(J_JUMP_OPCODE_X1) |
74 create_JumpOff_X1(pcrel_by_instr);
75 }
76
77 if (addr == FTRACE_ADDR) {
78 /* opcode: or r10, lr, zero */
79 opcode_x0 =
80 create_Dest_X0(10) |
81 create_SrcA_X0(TREG_LR) |
82 create_SrcB_X0(TREG_ZERO) |
83 create_RRROpcodeExtension_X0(OR_RRR_0_OPCODE_X0) |
84 create_Opcode_X0(RRR_0_OPCODE_X0);
85 } else {
86 /* opcode: fnop */
87 opcode_x0 =
88 create_UnaryOpcodeExtension_X0(FNOP_UNARY_OPCODE_X0) |
89 create_RRROpcodeExtension_X0(UNARY_RRR_0_OPCODE_X0) |
90 create_Opcode_X0(RRR_0_OPCODE_X0);
91 }
92
93 return opcode_x1 | opcode_x0;
94}
95
96static unsigned long ftrace_nop_replace(struct dyn_ftrace *rec)
97{
98 return NOP();
99}
100
101static unsigned long ftrace_call_replace(unsigned long pc, unsigned long addr)
102{
103 return ftrace_gen_branch(pc, addr, true);
104}
105
106static int ftrace_modify_code(unsigned long pc, unsigned long old,
107 unsigned long new)
108{
109 unsigned long pc_wr;
110
111 /* Check if the address is in kernel text space and module space. */
112 if (!kernel_text_address(pc))
113 return -EINVAL;
114
115 /* Operate on writable kernel text mapping. */
116 pc_wr = pc - MEM_SV_START + PAGE_OFFSET;
117
118 if (probe_kernel_write((void *)pc_wr, &new, MCOUNT_INSN_SIZE))
119 return -EPERM;
120
121 smp_wmb();
122
123 if (!machine_stopped && num_online_cpus() > 1)
124 flush_icache_range(pc, pc + MCOUNT_INSN_SIZE);
125
126 return 0;
127}
128
129int ftrace_update_ftrace_func(ftrace_func_t func)
130{
131 unsigned long pc, old;
132 unsigned long new;
133 int ret;
134
135 pc = (unsigned long)&ftrace_call;
136 memcpy(&old, &ftrace_call, MCOUNT_INSN_SIZE);
137 new = ftrace_call_replace(pc, (unsigned long)func);
138
139 ret = ftrace_modify_code(pc, old, new);
140
141 return ret;
142}
143
144int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
145{
146 unsigned long new, old;
147 unsigned long ip = rec->ip;
148
149 old = ftrace_nop_replace(rec);
150 new = ftrace_call_replace(ip, addr);
151
152 return ftrace_modify_code(rec->ip, old, new);
153}
154
155int ftrace_make_nop(struct module *mod,
156 struct dyn_ftrace *rec, unsigned long addr)
157{
158 unsigned long ip = rec->ip;
159 unsigned long old;
160 unsigned long new;
161 int ret;
162
163 old = ftrace_call_replace(ip, addr);
164 new = ftrace_nop_replace(rec);
165 ret = ftrace_modify_code(ip, old, new);
166
167 return ret;
168}
169
170int __init ftrace_dyn_arch_init(void *data)
171{
172 *(unsigned long *)data = 0;
173
174 return 0;
175}
176#endif /* CONFIG_DYNAMIC_FTRACE */
177
178#ifdef CONFIG_FUNCTION_GRAPH_TRACER
179void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr,
180 unsigned long frame_pointer)
181{
182 unsigned long return_hooker = (unsigned long) &return_to_handler;
183 struct ftrace_graph_ent trace;
184 unsigned long old;
185 int err;
186
187 if (unlikely(atomic_read(&current->tracing_graph_pause)))
188 return;
189
190 old = *parent;
191 *parent = return_hooker;
192
193 err = ftrace_push_return_trace(old, self_addr, &trace.depth,
194 frame_pointer);
195 if (err == -EBUSY) {
196 *parent = old;
197 return;
198 }
199
200 trace.func = self_addr;
201
202 /* Only trace if the calling function expects to */
203 if (!ftrace_graph_entry(&trace)) {
204 current->curr_ret_stack--;
205 *parent = old;
206 }
207}
208
209#ifdef CONFIG_DYNAMIC_FTRACE
210extern unsigned long ftrace_graph_call;
211
212static int __ftrace_modify_caller(unsigned long *callsite,
213 void (*func) (void), bool enable)
214{
215 unsigned long caller_fn = (unsigned long) func;
216 unsigned long pc = (unsigned long) callsite;
217 unsigned long branch = ftrace_gen_branch(pc, caller_fn, false);
218 unsigned long nop = NOP();
219 unsigned long old = enable ? nop : branch;
220 unsigned long new = enable ? branch : nop;
221
222 return ftrace_modify_code(pc, old, new);
223}
224
225static int ftrace_modify_graph_caller(bool enable)
226{
227 int ret;
228
229 ret = __ftrace_modify_caller(&ftrace_graph_call,
230 ftrace_graph_caller,
231 enable);
232
233 return ret;
234}
235
236int ftrace_enable_ftrace_graph_caller(void)
237{
238 return ftrace_modify_graph_caller(true);
239}
240
241int ftrace_disable_ftrace_graph_caller(void)
242{
243 return ftrace_modify_graph_caller(false);
244}
245#endif /* CONFIG_DYNAMIC_FTRACE */
246#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
diff --git a/arch/tile/kernel/hardwall.c b/arch/tile/kernel/hardwall.c
index 38ac189d9575..df27a1fd94a3 100644
--- a/arch/tile/kernel/hardwall.c
+++ b/arch/tile/kernel/hardwall.c
@@ -272,9 +272,9 @@ static void hardwall_setup_func(void *info)
272 struct hardwall_info *r = info; 272 struct hardwall_info *r = info;
273 struct hardwall_type *hwt = r->type; 273 struct hardwall_type *hwt = r->type;
274 274
275 int cpu = smp_processor_id(); 275 int cpu = smp_processor_id(); /* on_each_cpu disables preemption */
276 int x = cpu % smp_width; 276 int x = cpu_x(cpu);
277 int y = cpu / smp_width; 277 int y = cpu_y(cpu);
278 int bits = 0; 278 int bits = 0;
279 if (x == r->ulhc_x) 279 if (x == r->ulhc_x)
280 bits |= W_PROTECT; 280 bits |= W_PROTECT;
@@ -317,6 +317,7 @@ static void hardwall_protect_rectangle(struct hardwall_info *r)
317 on_each_cpu_mask(&rect_cpus, hardwall_setup_func, r, 1); 317 on_each_cpu_mask(&rect_cpus, hardwall_setup_func, r, 1);
318} 318}
319 319
320/* Entered from INT_xDN_FIREWALL interrupt vector with irqs disabled. */
320void __kprobes do_hardwall_trap(struct pt_regs* regs, int fault_num) 321void __kprobes do_hardwall_trap(struct pt_regs* regs, int fault_num)
321{ 322{
322 struct hardwall_info *rect; 323 struct hardwall_info *rect;
@@ -325,7 +326,6 @@ void __kprobes do_hardwall_trap(struct pt_regs* regs, int fault_num)
325 struct siginfo info; 326 struct siginfo info;
326 int cpu = smp_processor_id(); 327 int cpu = smp_processor_id();
327 int found_processes; 328 int found_processes;
328 unsigned long flags;
329 struct pt_regs *old_regs = set_irq_regs(regs); 329 struct pt_regs *old_regs = set_irq_regs(regs);
330 330
331 irq_enter(); 331 irq_enter();
@@ -346,7 +346,7 @@ void __kprobes do_hardwall_trap(struct pt_regs* regs, int fault_num)
346 BUG_ON(hwt->disabled); 346 BUG_ON(hwt->disabled);
347 347
348 /* This tile trapped a network access; find the rectangle. */ 348 /* This tile trapped a network access; find the rectangle. */
349 spin_lock_irqsave(&hwt->lock, flags); 349 spin_lock(&hwt->lock);
350 list_for_each_entry(rect, &hwt->list, list) { 350 list_for_each_entry(rect, &hwt->list, list) {
351 if (cpumask_test_cpu(cpu, &rect->cpumask)) 351 if (cpumask_test_cpu(cpu, &rect->cpumask))
352 break; 352 break;
@@ -401,7 +401,7 @@ void __kprobes do_hardwall_trap(struct pt_regs* regs, int fault_num)
401 pr_notice("hardwall: no associated processes!\n"); 401 pr_notice("hardwall: no associated processes!\n");
402 402
403 done: 403 done:
404 spin_unlock_irqrestore(&hwt->lock, flags); 404 spin_unlock(&hwt->lock);
405 405
406 /* 406 /*
407 * We have to disable firewall interrupts now, or else when we 407 * We have to disable firewall interrupts now, or else when we
@@ -540,6 +540,14 @@ static struct hardwall_info *hardwall_create(struct hardwall_type *hwt,
540 } 540 }
541 } 541 }
542 542
543 /*
544 * Eliminate cpus that are not part of this Linux client.
545 * Note that this allows for configurations that we might not want to
546 * support, such as one client on every even cpu, another client on
547 * every odd cpu.
548 */
549 cpumask_and(&info->cpumask, &info->cpumask, cpu_online_mask);
550
543 /* Confirm it doesn't overlap and add it to the list. */ 551 /* Confirm it doesn't overlap and add it to the list. */
544 spin_lock_irqsave(&hwt->lock, flags); 552 spin_lock_irqsave(&hwt->lock, flags);
545 list_for_each_entry(iter, &hwt->list, list) { 553 list_for_each_entry(iter, &hwt->list, list) {
@@ -612,7 +620,7 @@ static int hardwall_activate(struct hardwall_info *info)
612 620
613/* 621/*
614 * Deactivate a task's hardwall. Must hold lock for hardwall_type. 622 * Deactivate a task's hardwall. Must hold lock for hardwall_type.
615 * This method may be called from free_task(), so we don't want to 623 * This method may be called from exit_thread(), so we don't want to
616 * rely on too many fields of struct task_struct still being valid. 624 * rely on too many fields of struct task_struct still being valid.
617 * We assume the cpus_allowed, pid, and comm fields are still valid. 625 * We assume the cpus_allowed, pid, and comm fields are still valid.
618 */ 626 */
@@ -653,7 +661,7 @@ static int hardwall_deactivate(struct hardwall_type *hwt,
653 return -EINVAL; 661 return -EINVAL;
654 662
655 printk(KERN_DEBUG "Pid %d (%s) deactivated for %s hardwall: cpu %d\n", 663 printk(KERN_DEBUG "Pid %d (%s) deactivated for %s hardwall: cpu %d\n",
656 task->pid, task->comm, hwt->name, smp_processor_id()); 664 task->pid, task->comm, hwt->name, raw_smp_processor_id());
657 return 0; 665 return 0;
658} 666}
659 667
@@ -795,8 +803,8 @@ static void reset_xdn_network_state(struct hardwall_type *hwt)
795 /* Reset UDN coordinates to their standard value */ 803 /* Reset UDN coordinates to their standard value */
796 { 804 {
797 unsigned int cpu = smp_processor_id(); 805 unsigned int cpu = smp_processor_id();
798 unsigned int x = cpu % smp_width; 806 unsigned int x = cpu_x(cpu);
799 unsigned int y = cpu / smp_width; 807 unsigned int y = cpu_y(cpu);
800 __insn_mtspr(SPR_UDN_TILE_COORD, (x << 18) | (y << 7)); 808 __insn_mtspr(SPR_UDN_TILE_COORD, (x << 18) | (y << 7));
801 } 809 }
802 810
diff --git a/arch/tile/kernel/head_32.S b/arch/tile/kernel/head_32.S
index ac115307e5e4..8d5b40ff2922 100644
--- a/arch/tile/kernel/head_32.S
+++ b/arch/tile/kernel/head_32.S
@@ -39,12 +39,12 @@ ENTRY(_start)
39 } 39 }
40 { 40 {
41 moveli r0, _HV_VERSION_OLD_HV_INIT 41 moveli r0, _HV_VERSION_OLD_HV_INIT
42 jal hv_init 42 jal _hv_init
43 } 43 }
44 /* Get a reasonable default ASID in r0 */ 44 /* Get a reasonable default ASID in r0 */
45 { 45 {
46 move r0, zero 46 move r0, zero
47 jal hv_inquire_asid 47 jal _hv_inquire_asid
48 } 48 }
49 /* Install the default page table */ 49 /* Install the default page table */
50 { 50 {
@@ -64,7 +64,7 @@ ENTRY(_start)
64 auli r0, r0, ha16(swapper_pg_dir - PAGE_OFFSET) 64 auli r0, r0, ha16(swapper_pg_dir - PAGE_OFFSET)
65 } 65 }
66 { 66 {
67 inv r6 67 finv r6
68 move r1, zero /* high 32 bits of CPA is zero */ 68 move r1, zero /* high 32 bits of CPA is zero */
69 } 69 }
70 { 70 {
@@ -73,12 +73,12 @@ ENTRY(_start)
73 } 73 }
74 { 74 {
75 auli lr, lr, ha16(1f) 75 auli lr, lr, ha16(1f)
76 j hv_install_context 76 j _hv_install_context
77 } 77 }
781: 781:
79 79
80 /* Get our processor number and save it away in SAVE_K_0. */ 80 /* Get our processor number and save it away in SAVE_K_0. */
81 jal hv_inquire_topology 81 jal _hv_inquire_topology
82 mulll_uu r4, r1, r2 /* r1 == y, r2 == width */ 82 mulll_uu r4, r1, r2 /* r1 == y, r2 == width */
83 add r4, r4, r0 /* r0 == x, so r4 == cpu == y*width + x */ 83 add r4, r4, r0 /* r0 == x, so r4 == cpu == y*width + x */
84 84
@@ -86,7 +86,7 @@ ENTRY(_start)
86 /* 86 /*
87 * Load up our per-cpu offset. When the first (master) tile 87 * Load up our per-cpu offset. When the first (master) tile
88 * boots, this value is still zero, so we will load boot_pc 88 * boots, this value is still zero, so we will load boot_pc
89 * with start_kernel, and boot_sp with init_stack + THREAD_SIZE. 89 * with start_kernel, and boot_sp at the top of init_stack.
90 * The master tile initializes the per-cpu offset array, so that 90 * The master tile initializes the per-cpu offset array, so that
91 * when subsequent (secondary) tiles boot, they will instead load 91 * when subsequent (secondary) tiles boot, they will instead load
92 * from their per-cpu versions of boot_sp and boot_pc. 92 * from their per-cpu versions of boot_sp and boot_pc.
@@ -126,7 +126,6 @@ ENTRY(_start)
126 lw sp, r1 126 lw sp, r1
127 or r4, sp, r4 127 or r4, sp, r4
128 mtspr SPR_SYSTEM_SAVE_K_0, r4 /* save ksp0 + cpu */ 128 mtspr SPR_SYSTEM_SAVE_K_0, r4 /* save ksp0 + cpu */
129 addi sp, sp, -STACK_TOP_DELTA
130 { 129 {
131 move lr, zero /* stop backtraces in the called function */ 130 move lr, zero /* stop backtraces in the called function */
132 jr r0 131 jr r0
@@ -163,8 +162,8 @@ ENTRY(swapper_pg_dir)
163 .set addr, addr + PGDIR_SIZE 162 .set addr, addr + PGDIR_SIZE
164 .endr 163 .endr
165 164
166 /* The true text VAs are mapped as VA = PA + MEM_SV_INTRPT */ 165 /* The true text VAs are mapped as VA = PA + MEM_SV_START */
167 PTE MEM_SV_INTRPT, 0, (1 << (HV_PTE_INDEX_READABLE - 32)) | \ 166 PTE MEM_SV_START, 0, (1 << (HV_PTE_INDEX_READABLE - 32)) | \
168 (1 << (HV_PTE_INDEX_EXECUTABLE - 32)) 167 (1 << (HV_PTE_INDEX_EXECUTABLE - 32))
169 .org swapper_pg_dir + PGDIR_SIZE 168 .org swapper_pg_dir + PGDIR_SIZE
170 END(swapper_pg_dir) 169 END(swapper_pg_dir)
diff --git a/arch/tile/kernel/head_64.S b/arch/tile/kernel/head_64.S
index 6093964fa5c7..bd0e12f283f3 100644
--- a/arch/tile/kernel/head_64.S
+++ b/arch/tile/kernel/head_64.S
@@ -25,6 +25,15 @@
25#include <arch/chip.h> 25#include <arch/chip.h>
26#include <arch/spr_def.h> 26#include <arch/spr_def.h>
27 27
28/* Extract two 32-bit bit values that were read into one register. */
29#ifdef __BIG_ENDIAN__
30#define GET_FIRST_INT(rd, rs) shrsi rd, rs, 32
31#define GET_SECOND_INT(rd, rs) addxi rd, rs, 0
32#else
33#define GET_FIRST_INT(rd, rs) addxi rd, rs, 0
34#define GET_SECOND_INT(rd, rs) shrsi rd, rs, 32
35#endif
36
28/* 37/*
29 * This module contains the entry code for kernel images. It performs the 38 * This module contains the entry code for kernel images. It performs the
30 * minimal setup needed to call the generic C routines. 39 * minimal setup needed to call the generic C routines.
@@ -46,11 +55,11 @@ ENTRY(_start)
46 movei r2, TILE_CHIP_REV 55 movei r2, TILE_CHIP_REV
47 movei r3, KERNEL_PL 56 movei r3, KERNEL_PL
48 } 57 }
49 jal hv_init 58 jal _hv_init
50 /* Get a reasonable default ASID in r0 */ 59 /* Get a reasonable default ASID in r0 */
51 { 60 {
52 move r0, zero 61 move r0, zero
53 jal hv_inquire_asid 62 jal _hv_inquire_asid
54 } 63 }
55 64
56 /* 65 /*
@@ -61,7 +70,7 @@ ENTRY(_start)
61 * other CPUs should see a properly-constructed page table. 70 * other CPUs should see a properly-constructed page table.
62 */ 71 */
63 { 72 {
64 v4int_l r2, zero, r0 /* ASID for hv_install_context */ 73 GET_FIRST_INT(r2, r0) /* ASID for hv_install_context */
65 moveli r4, hw1_last(swapper_pgprot - PAGE_OFFSET) 74 moveli r4, hw1_last(swapper_pgprot - PAGE_OFFSET)
66 } 75 }
67 { 76 {
@@ -77,7 +86,7 @@ ENTRY(_start)
77 { 86 {
78 /* After initializing swapper_pgprot, HV_PTE_GLOBAL is set. */ 87 /* After initializing swapper_pgprot, HV_PTE_GLOBAL is set. */
79 bfextu r7, r1, HV_PTE_INDEX_GLOBAL, HV_PTE_INDEX_GLOBAL 88 bfextu r7, r1, HV_PTE_INDEX_GLOBAL, HV_PTE_INDEX_GLOBAL
80 inv r4 89 finv r4
81 } 90 }
82 bnez r7, .Lno_write 91 bnez r7, .Lno_write
83 { 92 {
@@ -121,29 +130,24 @@ ENTRY(_start)
121 } 130 }
122 { 131 {
123 moveli r3, CTX_PAGE_FLAG 132 moveli r3, CTX_PAGE_FLAG
124 j hv_install_context 133 j _hv_install_context
125 } 134 }
1261: 1351:
127 136
128 /* Install the interrupt base. */ 137 /* Install the interrupt base. */
129 moveli r0, hw2_last(MEM_SV_START) 138 moveli r0, hw2_last(intrpt_start)
130 shl16insli r0, r0, hw1(MEM_SV_START) 139 shl16insli r0, r0, hw1(intrpt_start)
131 shl16insli r0, r0, hw0(MEM_SV_START) 140 shl16insli r0, r0, hw0(intrpt_start)
132 mtspr SPR_INTERRUPT_VECTOR_BASE_K, r0 141 mtspr SPR_INTERRUPT_VECTOR_BASE_K, r0
133 142
134 /* 143 /* Get our processor number and save it away in SAVE_K_0. */
135 * Get our processor number and save it away in SAVE_K_0. 144 jal _hv_inquire_topology
136 * Extract stuff from the topology structure: r4 = y, r6 = x,
137 * r5 = width. FIXME: consider whether we want to just make these
138 * 64-bit values (and if so fix smp_topology write below, too).
139 */
140 jal hv_inquire_topology
141 { 145 {
142 v4int_l r5, zero, r1 /* r5 = width */ 146 GET_FIRST_INT(r5, r1) /* r5 = width */
143 shrui r4, r0, 32 /* r4 = y */ 147 GET_SECOND_INT(r4, r0) /* r4 = y */
144 } 148 }
145 { 149 {
146 v4int_l r6, zero, r0 /* r6 = x */ 150 GET_FIRST_INT(r6, r0) /* r6 = x */
147 mul_lu_lu r4, r4, r5 151 mul_lu_lu r4, r4, r5
148 } 152 }
149 { 153 {
@@ -154,7 +158,7 @@ ENTRY(_start)
154 /* 158 /*
155 * Load up our per-cpu offset. When the first (master) tile 159 * Load up our per-cpu offset. When the first (master) tile
156 * boots, this value is still zero, so we will load boot_pc 160 * boots, this value is still zero, so we will load boot_pc
157 * with start_kernel, and boot_sp with init_stack + THREAD_SIZE. 161 * with start_kernel, and boot_sp with at the top of init_stack.
158 * The master tile initializes the per-cpu offset array, so that 162 * The master tile initializes the per-cpu offset array, so that
159 * when subsequent (secondary) tiles boot, they will instead load 163 * when subsequent (secondary) tiles boot, they will instead load
160 * from their per-cpu versions of boot_sp and boot_pc. 164 * from their per-cpu versions of boot_sp and boot_pc.
@@ -198,9 +202,9 @@ ENTRY(_start)
198 } 202 }
199 ld r0, r0 203 ld r0, r0
200 ld sp, r1 204 ld sp, r1
201 or r4, sp, r4 205 shli r4, r4, CPU_SHIFT
206 bfins r4, sp, 0, CPU_SHIFT-1
202 mtspr SPR_SYSTEM_SAVE_K_0, r4 /* save ksp0 + cpu */ 207 mtspr SPR_SYSTEM_SAVE_K_0, r4 /* save ksp0 + cpu */
203 addi sp, sp, -STACK_TOP_DELTA
204 { 208 {
205 move lr, zero /* stop backtraces in the called function */ 209 move lr, zero /* stop backtraces in the called function */
206 jr r0 210 jr r0
diff --git a/arch/tile/kernel/hvglue.S b/arch/tile/kernel/hvglue.S
new file mode 100644
index 000000000000..2ab456622391
--- /dev/null
+++ b/arch/tile/kernel/hvglue.S
@@ -0,0 +1,74 @@
1/* Hypervisor call vector addresses; see <hv/hypervisor.h> */
2.macro gensym sym, val, size
3.org \val
4.global _\sym
5.type _\sym,function
6_\sym:
7.size _\sym,\size
8#ifndef CONFIG_TILE_HVGLUE_TRACE
9.globl \sym
10.set \sym,_\sym
11#endif
12.endm
13
14.section .hvglue,"x",@nobits
15.align 8
16gensym hv_init, 0x20, 32
17gensym hv_install_context, 0x40, 32
18gensym hv_sysconf, 0x60, 32
19gensym hv_get_rtc, 0x80, 32
20gensym hv_set_rtc, 0xa0, 32
21gensym hv_flush_asid, 0xc0, 32
22gensym hv_flush_page, 0xe0, 32
23gensym hv_flush_pages, 0x100, 32
24gensym hv_restart, 0x120, 32
25gensym hv_halt, 0x140, 32
26gensym hv_power_off, 0x160, 32
27gensym hv_inquire_physical, 0x180, 32
28gensym hv_inquire_memory_controller, 0x1a0, 32
29gensym hv_inquire_virtual, 0x1c0, 32
30gensym hv_inquire_asid, 0x1e0, 32
31gensym hv_nanosleep, 0x200, 32
32gensym hv_console_read_if_ready, 0x220, 32
33gensym hv_console_write, 0x240, 32
34gensym hv_downcall_dispatch, 0x260, 32
35gensym hv_inquire_topology, 0x280, 32
36gensym hv_fs_findfile, 0x2a0, 32
37gensym hv_fs_fstat, 0x2c0, 32
38gensym hv_fs_pread, 0x2e0, 32
39gensym hv_physaddr_read64, 0x300, 32
40gensym hv_physaddr_write64, 0x320, 32
41gensym hv_get_command_line, 0x340, 32
42gensym hv_set_caching, 0x360, 32
43gensym hv_bzero_page, 0x380, 32
44gensym hv_register_message_state, 0x3a0, 32
45gensym hv_send_message, 0x3c0, 32
46gensym hv_receive_message, 0x3e0, 32
47gensym hv_inquire_context, 0x400, 32
48gensym hv_start_all_tiles, 0x420, 32
49gensym hv_dev_open, 0x440, 32
50gensym hv_dev_close, 0x460, 32
51gensym hv_dev_pread, 0x480, 32
52gensym hv_dev_pwrite, 0x4a0, 32
53gensym hv_dev_poll, 0x4c0, 32
54gensym hv_dev_poll_cancel, 0x4e0, 32
55gensym hv_dev_preada, 0x500, 32
56gensym hv_dev_pwritea, 0x520, 32
57gensym hv_flush_remote, 0x540, 32
58gensym hv_console_putc, 0x560, 32
59gensym hv_inquire_tiles, 0x580, 32
60gensym hv_confstr, 0x5a0, 32
61gensym hv_reexec, 0x5c0, 32
62gensym hv_set_command_line, 0x5e0, 32
63gensym hv_clear_intr, 0x600, 32
64gensym hv_enable_intr, 0x620, 32
65gensym hv_disable_intr, 0x640, 32
66gensym hv_raise_intr, 0x660, 32
67gensym hv_trigger_ipi, 0x680, 32
68gensym hv_store_mapping, 0x6a0, 32
69gensym hv_inquire_realpa, 0x6c0, 32
70gensym hv_flush_all, 0x6e0, 32
71gensym hv_get_ipi_pte, 0x700, 32
72gensym hv_set_pte_super_shift, 0x720, 32
73gensym hv_console_set_ipi, 0x7e0, 32
74gensym hv_glue_internals, 0x800, 30720
diff --git a/arch/tile/kernel/hvglue.lds b/arch/tile/kernel/hvglue.lds
deleted file mode 100644
index d44c5a67a1ed..000000000000
--- a/arch/tile/kernel/hvglue.lds
+++ /dev/null
@@ -1,59 +0,0 @@
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_set_pte_super_shift = TEXT_OFFSET + 0x10720;
59hv_glue_internals = TEXT_OFFSET + 0x10740;
diff --git a/arch/tile/kernel/hvglue_trace.c b/arch/tile/kernel/hvglue_trace.c
new file mode 100644
index 000000000000..85c74ad29312
--- /dev/null
+++ b/arch/tile/kernel/hvglue_trace.c
@@ -0,0 +1,266 @@
1/*
2 * Copyright 2013 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 * Pull in the hypervisor header so we declare all the ABI functions
17 * with the underscore versions, then undef the names so that we can
18 * provide our own wrapper versions.
19 */
20#define hv_init _hv_init
21#define hv_install_context _hv_install_context
22#define hv_sysconf _hv_sysconf
23#define hv_get_rtc _hv_get_rtc
24#define hv_set_rtc _hv_set_rtc
25#define hv_flush_asid _hv_flush_asid
26#define hv_flush_page _hv_flush_page
27#define hv_flush_pages _hv_flush_pages
28#define hv_restart _hv_restart
29#define hv_halt _hv_halt
30#define hv_power_off _hv_power_off
31#define hv_inquire_physical _hv_inquire_physical
32#define hv_inquire_memory_controller _hv_inquire_memory_controller
33#define hv_inquire_virtual _hv_inquire_virtual
34#define hv_inquire_asid _hv_inquire_asid
35#define hv_nanosleep _hv_nanosleep
36#define hv_console_read_if_ready _hv_console_read_if_ready
37#define hv_console_write _hv_console_write
38#define hv_downcall_dispatch _hv_downcall_dispatch
39#define hv_inquire_topology _hv_inquire_topology
40#define hv_fs_findfile _hv_fs_findfile
41#define hv_fs_fstat _hv_fs_fstat
42#define hv_fs_pread _hv_fs_pread
43#define hv_physaddr_read64 _hv_physaddr_read64
44#define hv_physaddr_write64 _hv_physaddr_write64
45#define hv_get_command_line _hv_get_command_line
46#define hv_set_caching _hv_set_caching
47#define hv_bzero_page _hv_bzero_page
48#define hv_register_message_state _hv_register_message_state
49#define hv_send_message _hv_send_message
50#define hv_receive_message _hv_receive_message
51#define hv_inquire_context _hv_inquire_context
52#define hv_start_all_tiles _hv_start_all_tiles
53#define hv_dev_open _hv_dev_open
54#define hv_dev_close _hv_dev_close
55#define hv_dev_pread _hv_dev_pread
56#define hv_dev_pwrite _hv_dev_pwrite
57#define hv_dev_poll _hv_dev_poll
58#define hv_dev_poll_cancel _hv_dev_poll_cancel
59#define hv_dev_preada _hv_dev_preada
60#define hv_dev_pwritea _hv_dev_pwritea
61#define hv_flush_remote _hv_flush_remote
62#define hv_console_putc _hv_console_putc
63#define hv_inquire_tiles _hv_inquire_tiles
64#define hv_confstr _hv_confstr
65#define hv_reexec _hv_reexec
66#define hv_set_command_line _hv_set_command_line
67#define hv_clear_intr _hv_clear_intr
68#define hv_enable_intr _hv_enable_intr
69#define hv_disable_intr _hv_disable_intr
70#define hv_raise_intr _hv_raise_intr
71#define hv_trigger_ipi _hv_trigger_ipi
72#define hv_store_mapping _hv_store_mapping
73#define hv_inquire_realpa _hv_inquire_realpa
74#define hv_flush_all _hv_flush_all
75#define hv_get_ipi_pte _hv_get_ipi_pte
76#define hv_set_pte_super_shift _hv_set_pte_super_shift
77#define hv_console_set_ipi _hv_console_set_ipi
78#include <hv/hypervisor.h>
79#undef hv_init
80#undef hv_install_context
81#undef hv_sysconf
82#undef hv_get_rtc
83#undef hv_set_rtc
84#undef hv_flush_asid
85#undef hv_flush_page
86#undef hv_flush_pages
87#undef hv_restart
88#undef hv_halt
89#undef hv_power_off
90#undef hv_inquire_physical
91#undef hv_inquire_memory_controller
92#undef hv_inquire_virtual
93#undef hv_inquire_asid
94#undef hv_nanosleep
95#undef hv_console_read_if_ready
96#undef hv_console_write
97#undef hv_downcall_dispatch
98#undef hv_inquire_topology
99#undef hv_fs_findfile
100#undef hv_fs_fstat
101#undef hv_fs_pread
102#undef hv_physaddr_read64
103#undef hv_physaddr_write64
104#undef hv_get_command_line
105#undef hv_set_caching
106#undef hv_bzero_page
107#undef hv_register_message_state
108#undef hv_send_message
109#undef hv_receive_message
110#undef hv_inquire_context
111#undef hv_start_all_tiles
112#undef hv_dev_open
113#undef hv_dev_close
114#undef hv_dev_pread
115#undef hv_dev_pwrite
116#undef hv_dev_poll
117#undef hv_dev_poll_cancel
118#undef hv_dev_preada
119#undef hv_dev_pwritea
120#undef hv_flush_remote
121#undef hv_console_putc
122#undef hv_inquire_tiles
123#undef hv_confstr
124#undef hv_reexec
125#undef hv_set_command_line
126#undef hv_clear_intr
127#undef hv_enable_intr
128#undef hv_disable_intr
129#undef hv_raise_intr
130#undef hv_trigger_ipi
131#undef hv_store_mapping
132#undef hv_inquire_realpa
133#undef hv_flush_all
134#undef hv_get_ipi_pte
135#undef hv_set_pte_super_shift
136#undef hv_console_set_ipi
137
138/*
139 * Provide macros based on <linux/syscalls.h> to provide a wrapper
140 * function that invokes the same function with an underscore prefix.
141 * We can't use the existing __SC_xxx macros because we need to
142 * support up to nine arguments rather than up to six, and also this
143 * way the file stands alone from possible changes in the
144 * implementation of <linux/syscalls.h>.
145 */
146#define HV_WRAP0(type, name) \
147 type name(void); \
148 type name(void) \
149 { \
150 return _##name(); \
151 }
152#define __HV_DECL1(t1, a1) t1 a1
153#define __HV_DECL2(t2, a2, ...) t2 a2, __HV_DECL1(__VA_ARGS__)
154#define __HV_DECL3(t3, a3, ...) t3 a3, __HV_DECL2(__VA_ARGS__)
155#define __HV_DECL4(t4, a4, ...) t4 a4, __HV_DECL3(__VA_ARGS__)
156#define __HV_DECL5(t5, a5, ...) t5 a5, __HV_DECL4(__VA_ARGS__)
157#define __HV_DECL6(t6, a6, ...) t6 a6, __HV_DECL5(__VA_ARGS__)
158#define __HV_DECL7(t7, a7, ...) t7 a7, __HV_DECL6(__VA_ARGS__)
159#define __HV_DECL8(t8, a8, ...) t8 a8, __HV_DECL7(__VA_ARGS__)
160#define __HV_DECL9(t9, a9, ...) t9 a9, __HV_DECL8(__VA_ARGS__)
161#define __HV_PASS1(t1, a1) a1
162#define __HV_PASS2(t2, a2, ...) a2, __HV_PASS1(__VA_ARGS__)
163#define __HV_PASS3(t3, a3, ...) a3, __HV_PASS2(__VA_ARGS__)
164#define __HV_PASS4(t4, a4, ...) a4, __HV_PASS3(__VA_ARGS__)
165#define __HV_PASS5(t5, a5, ...) a5, __HV_PASS4(__VA_ARGS__)
166#define __HV_PASS6(t6, a6, ...) a6, __HV_PASS5(__VA_ARGS__)
167#define __HV_PASS7(t7, a7, ...) a7, __HV_PASS6(__VA_ARGS__)
168#define __HV_PASS8(t8, a8, ...) a8, __HV_PASS7(__VA_ARGS__)
169#define __HV_PASS9(t9, a9, ...) a9, __HV_PASS8(__VA_ARGS__)
170#define HV_WRAPx(x, type, name, ...) \
171 type name(__HV_DECL##x(__VA_ARGS__)); \
172 type name(__HV_DECL##x(__VA_ARGS__)) \
173 { \
174 return _##name(__HV_PASS##x(__VA_ARGS__)); \
175 }
176#define HV_WRAP1(type, name, ...) HV_WRAPx(1, type, name, __VA_ARGS__)
177#define HV_WRAP2(type, name, ...) HV_WRAPx(2, type, name, __VA_ARGS__)
178#define HV_WRAP3(type, name, ...) HV_WRAPx(3, type, name, __VA_ARGS__)
179#define HV_WRAP4(type, name, ...) HV_WRAPx(4, type, name, __VA_ARGS__)
180#define HV_WRAP5(type, name, ...) HV_WRAPx(5, type, name, __VA_ARGS__)
181#define HV_WRAP6(type, name, ...) HV_WRAPx(6, type, name, __VA_ARGS__)
182#define HV_WRAP7(type, name, ...) HV_WRAPx(7, type, name, __VA_ARGS__)
183#define HV_WRAP8(type, name, ...) HV_WRAPx(8, type, name, __VA_ARGS__)
184#define HV_WRAP9(type, name, ...) HV_WRAPx(9, type, name, __VA_ARGS__)
185
186/* List all the hypervisor API functions. */
187HV_WRAP4(void, hv_init, HV_VersionNumber, interface_version_number,
188 int, chip_num, int, chip_rev_num, int, client_pl)
189HV_WRAP1(long, hv_sysconf, HV_SysconfQuery, query)
190HV_WRAP3(int, hv_confstr, HV_ConfstrQuery, query, HV_VirtAddr, buf, int, len)
191#if CHIP_HAS_IPI()
192HV_WRAP3(int, hv_get_ipi_pte, HV_Coord, tile, int, pl, HV_PTE*, pte)
193HV_WRAP3(int, hv_console_set_ipi, int, ipi, int, event, HV_Coord, coord);
194#else
195HV_WRAP1(void, hv_enable_intr, HV_IntrMask, enab_mask)
196HV_WRAP1(void, hv_disable_intr, HV_IntrMask, disab_mask)
197HV_WRAP1(void, hv_clear_intr, HV_IntrMask, clear_mask)
198HV_WRAP1(void, hv_raise_intr, HV_IntrMask, raise_mask)
199HV_WRAP2(HV_Errno, hv_trigger_ipi, HV_Coord, tile, int, interrupt)
200#endif /* !CHIP_HAS_IPI() */
201HV_WRAP3(int, hv_store_mapping, HV_VirtAddr, va, unsigned int, len,
202 HV_PhysAddr, pa)
203HV_WRAP2(HV_PhysAddr, hv_inquire_realpa, HV_PhysAddr, cpa, unsigned int, len)
204HV_WRAP0(HV_RTCTime, hv_get_rtc)
205HV_WRAP1(void, hv_set_rtc, HV_RTCTime, time)
206HV_WRAP4(int, hv_install_context, HV_PhysAddr, page_table, HV_PTE, access,
207 HV_ASID, asid, __hv32, flags)
208HV_WRAP2(int, hv_set_pte_super_shift, int, level, int, log2_count)
209HV_WRAP0(HV_Context, hv_inquire_context)
210HV_WRAP1(int, hv_flush_asid, HV_ASID, asid)
211HV_WRAP2(int, hv_flush_page, HV_VirtAddr, address, HV_PageSize, page_size)
212HV_WRAP3(int, hv_flush_pages, HV_VirtAddr, start, HV_PageSize, page_size,
213 unsigned long, size)
214HV_WRAP1(int, hv_flush_all, int, preserve_global)
215HV_WRAP2(void, hv_restart, HV_VirtAddr, cmd, HV_VirtAddr, args)
216HV_WRAP0(void, hv_halt)
217HV_WRAP0(void, hv_power_off)
218HV_WRAP1(int, hv_reexec, HV_PhysAddr, entry)
219HV_WRAP0(HV_Topology, hv_inquire_topology)
220HV_WRAP3(HV_Errno, hv_inquire_tiles, HV_InqTileSet, set, HV_VirtAddr, cpumask,
221 int, length)
222HV_WRAP1(HV_PhysAddrRange, hv_inquire_physical, int, idx)
223HV_WRAP2(HV_MemoryControllerInfo, hv_inquire_memory_controller, HV_Coord, coord,
224 int, controller)
225HV_WRAP1(HV_VirtAddrRange, hv_inquire_virtual, int, idx)
226HV_WRAP1(HV_ASIDRange, hv_inquire_asid, int, idx)
227HV_WRAP1(void, hv_nanosleep, int, nanosecs)
228HV_WRAP0(int, hv_console_read_if_ready)
229HV_WRAP1(void, hv_console_putc, int, byte)
230HV_WRAP2(int, hv_console_write, HV_VirtAddr, bytes, int, len)
231HV_WRAP0(void, hv_downcall_dispatch)
232HV_WRAP1(int, hv_fs_findfile, HV_VirtAddr, filename)
233HV_WRAP1(HV_FS_StatInfo, hv_fs_fstat, int, inode)
234HV_WRAP4(int, hv_fs_pread, int, inode, HV_VirtAddr, buf,
235 int, length, int, offset)
236HV_WRAP2(unsigned long long, hv_physaddr_read64, HV_PhysAddr, addr,
237 HV_PTE, access)
238HV_WRAP3(void, hv_physaddr_write64, HV_PhysAddr, addr, HV_PTE, access,
239 unsigned long long, val)
240HV_WRAP2(int, hv_get_command_line, HV_VirtAddr, buf, int, length)
241HV_WRAP2(HV_Errno, hv_set_command_line, HV_VirtAddr, buf, int, length)
242HV_WRAP1(void, hv_set_caching, unsigned long, bitmask)
243HV_WRAP2(void, hv_bzero_page, HV_VirtAddr, va, unsigned int, size)
244HV_WRAP1(HV_Errno, hv_register_message_state, HV_MsgState*, msgstate)
245HV_WRAP4(int, hv_send_message, HV_Recipient *, recips, int, nrecip,
246 HV_VirtAddr, buf, int, buflen)
247HV_WRAP3(HV_RcvMsgInfo, hv_receive_message, HV_MsgState, msgstate,
248 HV_VirtAddr, buf, int, buflen)
249HV_WRAP0(void, hv_start_all_tiles)
250HV_WRAP2(int, hv_dev_open, HV_VirtAddr, name, __hv32, flags)
251HV_WRAP1(int, hv_dev_close, int, devhdl)
252HV_WRAP5(int, hv_dev_pread, int, devhdl, __hv32, flags, HV_VirtAddr, va,
253 __hv32, len, __hv64, offset)
254HV_WRAP5(int, hv_dev_pwrite, int, devhdl, __hv32, flags, HV_VirtAddr, va,
255 __hv32, len, __hv64, offset)
256HV_WRAP3(int, hv_dev_poll, int, devhdl, __hv32, events, HV_IntArg, intarg)
257HV_WRAP1(int, hv_dev_poll_cancel, int, devhdl)
258HV_WRAP6(int, hv_dev_preada, int, devhdl, __hv32, flags, __hv32, sgl_len,
259 HV_SGL *, sglp, __hv64, offset, HV_IntArg, intarg)
260HV_WRAP6(int, hv_dev_pwritea, int, devhdl, __hv32, flags, __hv32, sgl_len,
261 HV_SGL *, sglp, __hv64, offset, HV_IntArg, intarg)
262HV_WRAP9(int, hv_flush_remote, HV_PhysAddr, cache_pa,
263 unsigned long, cache_control, unsigned long*, cache_cpumask,
264 HV_VirtAddr, tlb_va, unsigned long, tlb_length,
265 unsigned long, tlb_pgsize, unsigned long*, tlb_cpumask,
266 HV_Remote_ASID*, asids, int, asidcount)
diff --git a/arch/tile/kernel/intvec_32.S b/arch/tile/kernel/intvec_32.S
index cb52d66343ed..088d5c141e68 100644
--- a/arch/tile/kernel/intvec_32.S
+++ b/arch/tile/kernel/intvec_32.S
@@ -28,20 +28,10 @@
28#include <arch/interrupts.h> 28#include <arch/interrupts.h>
29#include <arch/spr_def.h> 29#include <arch/spr_def.h>
30 30
31#ifdef CONFIG_PREEMPT
32# error "No support for kernel preemption currently"
33#endif
34
35#define PTREGS_PTR(reg, ptreg) addli reg, sp, C_ABI_SAVE_AREA_SIZE + (ptreg) 31#define PTREGS_PTR(reg, ptreg) addli reg, sp, C_ABI_SAVE_AREA_SIZE + (ptreg)
36 32
37#define PTREGS_OFFSET_SYSCALL PTREGS_OFFSET_REG(TREG_SYSCALL_NR) 33#define PTREGS_OFFSET_SYSCALL PTREGS_OFFSET_REG(TREG_SYSCALL_NR)
38 34
39#if !CHIP_HAS_WH64()
40 /* By making this an empty macro, we can use wh64 in the code. */
41 .macro wh64 reg
42 .endm
43#endif
44
45 .macro push_reg reg, ptr=sp, delta=-4 35 .macro push_reg reg, ptr=sp, delta=-4
46 { 36 {
47 sw \ptr, \reg 37 sw \ptr, \reg
@@ -189,7 +179,7 @@ intvec_\vecname:
189 * point sp at the top aligned address on the actual stack page. 179 * point sp at the top aligned address on the actual stack page.
190 */ 180 */
191 mfspr r0, SPR_SYSTEM_SAVE_K_0 181 mfspr r0, SPR_SYSTEM_SAVE_K_0
192 mm r0, r0, zero, LOG2_THREAD_SIZE, 31 182 mm r0, r0, zero, LOG2_NR_CPU_IDS, 31
193 183
1940: 1840:
195 /* 185 /*
@@ -207,6 +197,9 @@ intvec_\vecname:
207 * cache line 1: r14...r29 197 * cache line 1: r14...r29
208 * cache line 0: 2 x frame, r0..r13 198 * cache line 0: 2 x frame, r0..r13
209 */ 199 */
200#if STACK_TOP_DELTA != 64
201#error STACK_TOP_DELTA must be 64 for assumptions here and in task_pt_regs()
202#endif
210 andi r0, r0, -64 203 andi r0, r0, -64
211 204
212 /* 205 /*
@@ -326,18 +319,14 @@ intvec_\vecname:
326 movei r3, -1 /* not used, but set for consistency */ 319 movei r3, -1 /* not used, but set for consistency */
327 } 320 }
328 .else 321 .else
329#if CHIP_HAS_AUX_PERF_COUNTERS()
330 .ifc \c_routine, op_handle_aux_perf_interrupt 322 .ifc \c_routine, op_handle_aux_perf_interrupt
331 { 323 {
332 mfspr r2, AUX_PERF_COUNT_STS 324 mfspr r2, AUX_PERF_COUNT_STS
333 movei r3, -1 /* not used, but set for consistency */ 325 movei r3, -1 /* not used, but set for consistency */
334 } 326 }
335 .else 327 .else
336#endif
337 movei r3, 0 328 movei r3, 0
338#if CHIP_HAS_AUX_PERF_COUNTERS()
339 .endif 329 .endif
340#endif
341 .endif 330 .endif
342 .endif 331 .endif
343 .endif 332 .endif
@@ -354,7 +343,7 @@ intvec_\vecname:
354#ifdef __COLLECT_LINKER_FEEDBACK__ 343#ifdef __COLLECT_LINKER_FEEDBACK__
355 .pushsection .text.intvec_feedback,"ax" 344 .pushsection .text.intvec_feedback,"ax"
356 .org (\vecnum << 5) 345 .org (\vecnum << 5)
357 FEEDBACK_ENTER_EXPLICIT(intvec_\vecname, .intrpt1, 1 << 8) 346 FEEDBACK_ENTER_EXPLICIT(intvec_\vecname, .intrpt, 1 << 8)
358 jrp lr 347 jrp lr
359 .popsection 348 .popsection
360#endif 349#endif
@@ -468,7 +457,7 @@ intvec_\vecname:
468 } 457 }
469 { 458 {
470 auli r21, r21, ha16(__per_cpu_offset) 459 auli r21, r21, ha16(__per_cpu_offset)
471 mm r20, r20, zero, 0, LOG2_THREAD_SIZE-1 460 mm r20, r20, zero, 0, LOG2_NR_CPU_IDS-1
472 } 461 }
473 s2a r20, r20, r21 462 s2a r20, r20, r21
474 lw tp, r20 463 lw tp, r20
@@ -562,7 +551,6 @@ intvec_\vecname:
562 .endif 551 .endif
563 mtspr INTERRUPT_CRITICAL_SECTION, zero 552 mtspr INTERRUPT_CRITICAL_SECTION, zero
564 553
565#if CHIP_HAS_WH64()
566 /* 554 /*
567 * Prepare the first 256 stack bytes to be rapidly accessible 555 * Prepare the first 256 stack bytes to be rapidly accessible
568 * without having to fetch the background data. We don't really 556 * without having to fetch the background data. We don't really
@@ -583,7 +571,6 @@ intvec_\vecname:
583 addi r52, r52, -64 571 addi r52, r52, -64
584 } 572 }
585 wh64 r52 573 wh64 r52
586#endif
587 574
588#ifdef CONFIG_TRACE_IRQFLAGS 575#ifdef CONFIG_TRACE_IRQFLAGS
589 .ifnc \function,handle_nmi 576 .ifnc \function,handle_nmi
@@ -762,7 +749,7 @@ intvec_\vecname:
762 .macro dc_dispatch vecnum, vecname 749 .macro dc_dispatch vecnum, vecname
763 .org (\vecnum << 8) 750 .org (\vecnum << 8)
764intvec_\vecname: 751intvec_\vecname:
765 j hv_downcall_dispatch 752 j _hv_downcall_dispatch
766 ENDPROC(intvec_\vecname) 753 ENDPROC(intvec_\vecname)
767 .endm 754 .endm
768 755
@@ -812,17 +799,34 @@ STD_ENTRY(interrupt_return)
812 } 799 }
813 lw r29, r29 800 lw r29, r29
814 andi r29, r29, SPR_EX_CONTEXT_1_1__PL_MASK /* mask off ICS */ 801 andi r29, r29, SPR_EX_CONTEXT_1_1__PL_MASK /* mask off ICS */
802 bzt r29, .Lresume_userspace
803
804#ifdef CONFIG_PREEMPT
805 /* Returning to kernel space. Check if we need preemption. */
806 GET_THREAD_INFO(r29)
807 addli r28, r29, THREAD_INFO_FLAGS_OFFSET
815 { 808 {
816 bzt r29, .Lresume_userspace 809 lw r28, r28
817 PTREGS_PTR(r29, PTREGS_OFFSET_PC) 810 addli r29, r29, THREAD_INFO_PREEMPT_COUNT_OFFSET
818 } 811 }
812 {
813 andi r28, r28, _TIF_NEED_RESCHED
814 lw r29, r29
815 }
816 bzt r28, 1f
817 bnz r29, 1f
818 jal preempt_schedule_irq
819 FEEDBACK_REENTER(interrupt_return)
8201:
821#endif
819 822
820 /* If we're resuming to _cpu_idle_nap, bump PC forward by 8. */ 823 /* If we're resuming to _cpu_idle_nap, bump PC forward by 8. */
821 { 824 {
822 lw r28, r29 825 PTREGS_PTR(r29, PTREGS_OFFSET_PC)
823 moveli r27, lo16(_cpu_idle_nap) 826 moveli r27, lo16(_cpu_idle_nap)
824 } 827 }
825 { 828 {
829 lw r28, r29
826 auli r27, r27, ha16(_cpu_idle_nap) 830 auli r27, r27, ha16(_cpu_idle_nap)
827 } 831 }
828 { 832 {
@@ -1420,7 +1424,6 @@ handle_ill:
1420 { 1424 {
1421 lw r0, r0 /* indirect thru thread_info to get task_info*/ 1425 lw r0, r0 /* indirect thru thread_info to get task_info*/
1422 addi r1, sp, C_ABI_SAVE_AREA_SIZE /* put ptregs pointer into r1 */ 1426 addi r1, sp, C_ABI_SAVE_AREA_SIZE /* put ptregs pointer into r1 */
1423 move r2, zero /* load error code into r2 */
1424 } 1427 }
1425 1428
1426 jal send_sigtrap /* issue a SIGTRAP */ 1429 jal send_sigtrap /* issue a SIGTRAP */
@@ -1518,12 +1521,10 @@ STD_ENTRY(_sys_clone)
1518 __HEAD 1521 __HEAD
1519 .align 64 1522 .align 64
1520 /* Align much later jump on the start of a cache line. */ 1523 /* Align much later jump on the start of a cache line. */
1521#if !ATOMIC_LOCKS_FOUND_VIA_TABLE()
1522 nop 1524 nop
1523#if PAGE_SIZE >= 0x10000 1525#if PAGE_SIZE >= 0x10000
1524 nop 1526 nop
1525#endif 1527#endif
1526#endif
1527ENTRY(sys_cmpxchg) 1528ENTRY(sys_cmpxchg)
1528 1529
1529 /* 1530 /*
@@ -1557,45 +1558,6 @@ ENTRY(sys_cmpxchg)
1557# error Code here assumes PAGE_OFFSET can be loaded with just hi16() 1558# error Code here assumes PAGE_OFFSET can be loaded with just hi16()
1558#endif 1559#endif
1559 1560
1560#if ATOMIC_LOCKS_FOUND_VIA_TABLE()
1561 {
1562 /* Check for unaligned input. */
1563 bnz sp, .Lcmpxchg_badaddr
1564 mm r25, r0, zero, 3, PAGE_SHIFT-1
1565 }
1566 {
1567 crc32_32 r25, zero, r25
1568 moveli r21, lo16(atomic_lock_ptr)
1569 }
1570 {
1571 auli r21, r21, ha16(atomic_lock_ptr)
1572 auli r23, zero, hi16(PAGE_OFFSET) /* hugepage-aligned */
1573 }
1574 {
1575 shri r20, r25, 32 - ATOMIC_HASH_L1_SHIFT
1576 slt_u r23, r0, r23
1577 lw r26, r0 /* see comment in the "#else" for the "lw r26". */
1578 }
1579 {
1580 s2a r21, r20, r21
1581 bbns r23, .Lcmpxchg_badaddr
1582 }
1583 {
1584 lw r21, r21
1585 seqi r23, TREG_SYSCALL_NR_NAME, __NR_FAST_cmpxchg64
1586 andi r25, r25, ATOMIC_HASH_L2_SIZE - 1
1587 }
1588 {
1589 /* Branch away at this point if we're doing a 64-bit cmpxchg. */
1590 bbs r23, .Lcmpxchg64
1591 andi r23, r0, 7 /* Precompute alignment for cmpxchg64. */
1592 }
1593 {
1594 s2a ATOMIC_LOCK_REG_NAME, r25, r21
1595 j .Lcmpxchg32_tns /* see comment in the #else for the jump. */
1596 }
1597
1598#else /* ATOMIC_LOCKS_FOUND_VIA_TABLE() */
1599 { 1561 {
1600 /* Check for unaligned input. */ 1562 /* Check for unaligned input. */
1601 bnz sp, .Lcmpxchg_badaddr 1563 bnz sp, .Lcmpxchg_badaddr
@@ -1609,7 +1571,7 @@ ENTRY(sys_cmpxchg)
1609 * Because of C pointer arithmetic, we want to compute this: 1571 * Because of C pointer arithmetic, we want to compute this:
1610 * 1572 *
1611 * ((char*)atomic_locks + 1573 * ((char*)atomic_locks +
1612 * (((r0 >> 3) & (1 << (ATOMIC_HASH_SIZE - 1))) << 2)) 1574 * (((r0 >> 3) & ((1 << ATOMIC_HASH_SHIFT) - 1)) << 2))
1613 * 1575 *
1614 * Instead of two shifts we just ">> 1", and use 'mm' 1576 * Instead of two shifts we just ">> 1", and use 'mm'
1615 * to ignore the low and high bits we don't want. 1577 * to ignore the low and high bits we don't want.
@@ -1620,12 +1582,9 @@ ENTRY(sys_cmpxchg)
1620 1582
1621 /* 1583 /*
1622 * Ensure that the TLB is loaded before we take out the lock. 1584 * Ensure that the TLB is loaded before we take out the lock.
1623 * On tilepro, this will start fetching the value all the way 1585 * This will start fetching the value all the way into our L1
1624 * into our L1 as well (and if it gets modified before we 1586 * as well (and if it gets modified before we grab the lock,
1625 * grab the lock, it will be invalidated from our cache 1587 * it will be invalidated from our cache before we reload it).
1626 * before we reload it). On tile64, we'll start fetching it
1627 * into our L1 if we're the home, and if we're not, we'll
1628 * still at least start fetching it into the home's L2.
1629 */ 1588 */
1630 lw r26, r0 1589 lw r26, r0
1631 } 1590 }
@@ -1668,8 +1627,6 @@ ENTRY(sys_cmpxchg)
1668 j .Lcmpxchg32_tns 1627 j .Lcmpxchg32_tns
1669 } 1628 }
1670 1629
1671#endif /* ATOMIC_LOCKS_FOUND_VIA_TABLE() */
1672
1673/* Symbol for do_page_fault_ics() to use to compare against the PC. */ 1630/* Symbol for do_page_fault_ics() to use to compare against the PC. */
1674.global __sys_cmpxchg_grab_lock 1631.global __sys_cmpxchg_grab_lock
1675__sys_cmpxchg_grab_lock: 1632__sys_cmpxchg_grab_lock:
@@ -1807,9 +1764,6 @@ __sys_cmpxchg_grab_lock:
1807 .align 64 1764 .align 64
1808.Lcmpxchg64: 1765.Lcmpxchg64:
1809 { 1766 {
1810#if ATOMIC_LOCKS_FOUND_VIA_TABLE()
1811 s2a ATOMIC_LOCK_REG_NAME, r25, r21
1812#endif
1813 bzt r23, .Lcmpxchg64_tns 1767 bzt r23, .Lcmpxchg64_tns
1814 } 1768 }
1815 j .Lcmpxchg_badaddr 1769 j .Lcmpxchg_badaddr
@@ -1875,8 +1829,8 @@ int_unalign:
1875 push_extra_callee_saves r0 1829 push_extra_callee_saves r0
1876 j do_trap 1830 j do_trap
1877 1831
1878/* Include .intrpt1 array of interrupt vectors */ 1832/* Include .intrpt array of interrupt vectors */
1879 .section ".intrpt1", "ax" 1833 .section ".intrpt", "ax"
1880 1834
1881#define op_handle_perf_interrupt bad_intr 1835#define op_handle_perf_interrupt bad_intr
1882#define op_handle_aux_perf_interrupt bad_intr 1836#define op_handle_aux_perf_interrupt bad_intr
@@ -1944,10 +1898,8 @@ int_unalign:
1944 do_page_fault 1898 do_page_fault
1945 int_hand INT_SN_CPL, SN_CPL, bad_intr 1899 int_hand INT_SN_CPL, SN_CPL, bad_intr
1946 int_hand INT_DOUBLE_FAULT, DOUBLE_FAULT, do_trap 1900 int_hand INT_DOUBLE_FAULT, DOUBLE_FAULT, do_trap
1947#if CHIP_HAS_AUX_PERF_COUNTERS()
1948 int_hand INT_AUX_PERF_COUNT, AUX_PERF_COUNT, \ 1901 int_hand INT_AUX_PERF_COUNT, AUX_PERF_COUNT, \
1949 op_handle_aux_perf_interrupt, handle_nmi 1902 op_handle_aux_perf_interrupt, handle_nmi
1950#endif
1951 1903
1952 /* Synthetic interrupt delivered only by the simulator */ 1904 /* Synthetic interrupt delivered only by the simulator */
1953 int_hand INT_BREAKPOINT, BREAKPOINT, do_breakpoint 1905 int_hand INT_BREAKPOINT, BREAKPOINT, do_breakpoint
diff --git a/arch/tile/kernel/intvec_64.S b/arch/tile/kernel/intvec_64.S
index 85d483957027..ec755d3f3734 100644
--- a/arch/tile/kernel/intvec_64.S
+++ b/arch/tile/kernel/intvec_64.S
@@ -17,25 +17,33 @@
17#include <linux/linkage.h> 17#include <linux/linkage.h>
18#include <linux/errno.h> 18#include <linux/errno.h>
19#include <linux/unistd.h> 19#include <linux/unistd.h>
20#include <linux/init.h>
20#include <asm/ptrace.h> 21#include <asm/ptrace.h>
21#include <asm/thread_info.h> 22#include <asm/thread_info.h>
22#include <asm/irqflags.h> 23#include <asm/irqflags.h>
23#include <asm/asm-offsets.h> 24#include <asm/asm-offsets.h>
24#include <asm/types.h> 25#include <asm/types.h>
26#include <asm/traps.h>
25#include <asm/signal.h> 27#include <asm/signal.h>
26#include <hv/hypervisor.h> 28#include <hv/hypervisor.h>
27#include <arch/abi.h> 29#include <arch/abi.h>
28#include <arch/interrupts.h> 30#include <arch/interrupts.h>
29#include <arch/spr_def.h> 31#include <arch/spr_def.h>
30 32
31#ifdef CONFIG_PREEMPT
32# error "No support for kernel preemption currently"
33#endif
34
35#define PTREGS_PTR(reg, ptreg) addli reg, sp, C_ABI_SAVE_AREA_SIZE + (ptreg) 33#define PTREGS_PTR(reg, ptreg) addli reg, sp, C_ABI_SAVE_AREA_SIZE + (ptreg)
36 34
37#define PTREGS_OFFSET_SYSCALL PTREGS_OFFSET_REG(TREG_SYSCALL_NR) 35#define PTREGS_OFFSET_SYSCALL PTREGS_OFFSET_REG(TREG_SYSCALL_NR)
38 36
37#if CONFIG_KERNEL_PL == 1 || CONFIG_KERNEL_PL == 2
38/*
39 * Set "result" non-zero if ex1 holds the PL of the kernel
40 * (with or without ICS being set). Note this works only
41 * because we never find the PL at level 3.
42 */
43# define IS_KERNEL_EX1(result, ex1) andi result, ex1, CONFIG_KERNEL_PL
44#else
45# error Recode IS_KERNEL_EX1 for CONFIG_KERNEL_PL
46#endif
39 47
40 .macro push_reg reg, ptr=sp, delta=-8 48 .macro push_reg reg, ptr=sp, delta=-8
41 { 49 {
@@ -98,6 +106,185 @@
98 } 106 }
99 .endm 107 .endm
100 108
109 /*
110 * Unalign data exception fast handling: In order to handle
111 * unaligned data access, a fast JIT version is generated and stored
112 * in a specific area in user space. We first need to do a quick poke
113 * to see if the JIT is available. We use certain bits in the fault
114 * PC (3 to 9 is used for 16KB page size) as index to address the JIT
115 * code area. The first 64bit word is the fault PC, and the 2nd one is
116 * the fault bundle itself. If these 2 words both match, then we
117 * directly "iret" to JIT code. If not, a slow path is invoked to
118 * generate new JIT code. Note: the current JIT code WILL be
119 * overwritten if it existed. So, ideally we can handle 128 unalign
120 * fixups via JIT. For lookup efficiency and to effectively support
121 * tight loops with multiple unaligned reference, a simple
122 * direct-mapped cache is used.
123 *
124 * SPR_EX_CONTEXT_K_0 is modified to return to JIT code.
125 * SPR_EX_CONTEXT_K_1 has ICS set.
126 * SPR_EX_CONTEXT_0_0 is setup to user program's next PC.
127 * SPR_EX_CONTEXT_0_1 = 0.
128 */
129 .macro int_hand_unalign_fast vecnum, vecname
130 .org (\vecnum << 8)
131intvec_\vecname:
132 /* Put r3 in SPR_SYSTEM_SAVE_K_1. */
133 mtspr SPR_SYSTEM_SAVE_K_1, r3
134
135 mfspr r3, SPR_EX_CONTEXT_K_1
136 /*
137 * Examine if exception comes from user without ICS set.
138 * If not, just go directly to the slow path.
139 */
140 bnez r3, hand_unalign_slow_nonuser
141
142 mfspr r3, SPR_SYSTEM_SAVE_K_0
143
144 /* Get &thread_info->unalign_jit_tmp[0] in r3. */
145 bfexts r3, r3, 0, CPU_SHIFT-1
146 mm r3, zero, LOG2_THREAD_SIZE, 63
147 addli r3, r3, THREAD_INFO_UNALIGN_JIT_TMP_OFFSET
148
149 /*
150 * Save r0, r1, r2 into thread_info array r3 points to
151 * from low to high memory in order.
152 */
153 st_add r3, r0, 8
154 st_add r3, r1, 8
155 {
156 st_add r3, r2, 8
157 andi r2, sp, 7
158 }
159
160 /* Save stored r3 value so we can revert it on a page fault. */
161 mfspr r1, SPR_SYSTEM_SAVE_K_1
162 st r3, r1
163
164 {
165 /* Generate a SIGBUS if sp is not 8-byte aligned. */
166 bnez r2, hand_unalign_slow_badsp
167 }
168
169 /*
170 * Get the thread_info in r0; load r1 with pc. Set the low bit of sp
171 * as an indicator to the page fault code in case we fault.
172 */
173 {
174 ori sp, sp, 1
175 mfspr r1, SPR_EX_CONTEXT_K_0
176 }
177
178 /* Add the jit_info offset in thread_info; extract r1 [3:9] into r2. */
179 {
180 addli r0, r3, THREAD_INFO_UNALIGN_JIT_BASE_OFFSET - \
181 (THREAD_INFO_UNALIGN_JIT_TMP_OFFSET + (3 * 8))
182 bfextu r2, r1, 3, (2 + PAGE_SHIFT - UNALIGN_JIT_SHIFT)
183 }
184
185 /* Load the jit_info; multiply r2 by 128. */
186 {
187 ld r0, r0
188 shli r2, r2, UNALIGN_JIT_SHIFT
189 }
190
191 /*
192 * If r0 is NULL, the JIT page is not mapped, so go to slow path;
193 * add offset r2 to r0 at the same time.
194 */
195 {
196 beqz r0, hand_unalign_slow
197 add r2, r0, r2
198 }
199
200 /*
201 * We are loading from userspace (both the JIT info PC and
202 * instruction word, and the instruction word we executed)
203 * and since either could fault while holding the interrupt
204 * critical section, we must tag this region and check it in
205 * do_page_fault() to handle it properly.
206 */
207ENTRY(__start_unalign_asm_code)
208
209 /* Load first word of JIT in r0 and increment r2 by 8. */
210 ld_add r0, r2, 8
211
212 /*
213 * Compare the PC with the 1st word in JIT; load the fault bundle
214 * into r1.
215 */
216 {
217 cmpeq r0, r0, r1
218 ld r1, r1
219 }
220
221 /* Go to slow path if PC doesn't match. */
222 beqz r0, hand_unalign_slow
223
224 /*
225 * Load the 2nd word of JIT, which is supposed to be the fault
226 * bundle for a cache hit. Increment r2; after this bundle r2 will
227 * point to the potential start of the JIT code we want to run.
228 */
229 ld_add r0, r2, 8
230
231 /* No further accesses to userspace are done after this point. */
232ENTRY(__end_unalign_asm_code)
233
234 /* Compare the real bundle with what is saved in the JIT area. */
235 {
236 cmpeq r0, r1, r0
237 mtspr SPR_EX_CONTEXT_0_1, zero
238 }
239
240 /* Go to slow path if the fault bundle does not match. */
241 beqz r0, hand_unalign_slow
242
243 /*
244 * A cache hit is found.
245 * r2 points to start of JIT code (3rd word).
246 * r0 is the fault pc.
247 * r1 is the fault bundle.
248 * Reset the low bit of sp.
249 */
250 {
251 mfspr r0, SPR_EX_CONTEXT_K_0
252 andi sp, sp, ~1
253 }
254
255 /* Write r2 into EX_CONTEXT_K_0 and increment PC. */
256 {
257 mtspr SPR_EX_CONTEXT_K_0, r2
258 addi r0, r0, 8
259 }
260
261 /*
262 * Set ICS on kernel EX_CONTEXT_K_1 in order to "iret" to
263 * user with ICS set. This way, if the JIT fixup causes another
264 * unalign exception (which shouldn't be possible) the user
265 * process will be terminated with SIGBUS. Also, our fixup will
266 * run without interleaving with external interrupts.
267 * Each fixup is at most 14 bundles, so it won't hold ICS for long.
268 */
269 {
270 movei r1, PL_ICS_EX1(USER_PL, 1)
271 mtspr SPR_EX_CONTEXT_0_0, r0
272 }
273
274 {
275 mtspr SPR_EX_CONTEXT_K_1, r1
276 addi r3, r3, -(3 * 8)
277 }
278
279 /* Restore r0..r3. */
280 ld_add r0, r3, 8
281 ld_add r1, r3, 8
282 ld_add r2, r3, 8
283 ld r3, r3
284
285 iret
286 ENDPROC(intvec_\vecname)
287 .endm
101 288
102#ifdef __COLLECT_LINKER_FEEDBACK__ 289#ifdef __COLLECT_LINKER_FEEDBACK__
103 .pushsection .text.intvec_feedback,"ax" 290 .pushsection .text.intvec_feedback,"ax"
@@ -118,15 +305,21 @@ intvec_feedback:
118 * The "processing" argument specifies the code for processing 305 * The "processing" argument specifies the code for processing
119 * the interrupt. Defaults to "handle_interrupt". 306 * the interrupt. Defaults to "handle_interrupt".
120 */ 307 */
121 .macro int_hand vecnum, vecname, c_routine, processing=handle_interrupt 308 .macro __int_hand vecnum, vecname, c_routine,processing=handle_interrupt
122 .org (\vecnum << 8)
123intvec_\vecname: 309intvec_\vecname:
124 /* Temporarily save a register so we have somewhere to work. */ 310 /* Temporarily save a register so we have somewhere to work. */
125 311
126 mtspr SPR_SYSTEM_SAVE_K_1, r0 312 mtspr SPR_SYSTEM_SAVE_K_1, r0
127 mfspr r0, SPR_EX_CONTEXT_K_1 313 mfspr r0, SPR_EX_CONTEXT_K_1
128 314
129 andi r0, r0, SPR_EX_CONTEXT_1_1__PL_MASK /* mask off ICS */ 315 /*
316 * The unalign data fastpath code sets the low bit in sp to
317 * force us to reset it here on fault.
318 */
319 {
320 blbs sp, 2f
321 IS_KERNEL_EX1(r0, r0)
322 }
130 323
131 .ifc \vecnum, INT_DOUBLE_FAULT 324 .ifc \vecnum, INT_DOUBLE_FAULT
132 /* 325 /*
@@ -176,15 +369,15 @@ intvec_\vecname:
176 } 369 }
177 .endif 370 .endif
178 371
179 3722:
180 /* 373 /*
181 * SYSTEM_SAVE_K_0 holds the cpu number in the low bits, and 374 * SYSTEM_SAVE_K_0 holds the cpu number in the high bits, and
182 * the current stack top in the higher bits. So we recover 375 * the current stack top in the lower bits. So we recover
183 * our stack top by just masking off the low bits, then 376 * our starting stack value by sign-extending the low bits, then
184 * point sp at the top aligned address on the actual stack page. 377 * point sp at the top aligned address on the actual stack page.
185 */ 378 */
186 mfspr r0, SPR_SYSTEM_SAVE_K_0 379 mfspr r0, SPR_SYSTEM_SAVE_K_0
187 mm r0, zero, LOG2_THREAD_SIZE, 63 380 bfexts r0, r0, 0, CPU_SHIFT-1
188 381
1890: 3820:
190 /* 383 /*
@@ -206,6 +399,9 @@ intvec_\vecname:
206 * cache line 1: r6...r13 399 * cache line 1: r6...r13
207 * cache line 0: 2 x frame, r0..r5 400 * cache line 0: 2 x frame, r0..r5
208 */ 401 */
402#if STACK_TOP_DELTA != 64
403#error STACK_TOP_DELTA must be 64 for assumptions here and in task_pt_regs()
404#endif
209 andi r0, r0, -64 405 andi r0, r0, -64
210 406
211 /* 407 /*
@@ -305,7 +501,7 @@ intvec_\vecname:
305 mfspr r3, SPR_SYSTEM_SAVE_K_2 /* info about page fault */ 501 mfspr r3, SPR_SYSTEM_SAVE_K_2 /* info about page fault */
306 .else 502 .else
307 .ifc \vecnum, INT_ILL_TRANS 503 .ifc \vecnum, INT_ILL_TRANS
308 mfspr r2, ILL_TRANS_REASON 504 mfspr r2, ILL_VA_PC
309 .else 505 .else
310 .ifc \vecnum, INT_DOUBLE_FAULT 506 .ifc \vecnum, INT_DOUBLE_FAULT
311 mfspr r2, SPR_SYSTEM_SAVE_K_2 /* double fault info from HV */ 507 mfspr r2, SPR_SYSTEM_SAVE_K_2 /* double fault info from HV */
@@ -315,12 +511,10 @@ intvec_\vecname:
315 .else 511 .else
316 .ifc \c_routine, op_handle_perf_interrupt 512 .ifc \c_routine, op_handle_perf_interrupt
317 mfspr r2, PERF_COUNT_STS 513 mfspr r2, PERF_COUNT_STS
318#if CHIP_HAS_AUX_PERF_COUNTERS()
319 .else 514 .else
320 .ifc \c_routine, op_handle_aux_perf_interrupt 515 .ifc \c_routine, op_handle_aux_perf_interrupt
321 mfspr r2, AUX_PERF_COUNT_STS 516 mfspr r2, AUX_PERF_COUNT_STS
322 .endif 517 .endif
323#endif
324 .endif 518 .endif
325 .endif 519 .endif
326 .endif 520 .endif
@@ -339,7 +533,7 @@ intvec_\vecname:
339#ifdef __COLLECT_LINKER_FEEDBACK__ 533#ifdef __COLLECT_LINKER_FEEDBACK__
340 .pushsection .text.intvec_feedback,"ax" 534 .pushsection .text.intvec_feedback,"ax"
341 .org (\vecnum << 5) 535 .org (\vecnum << 5)
342 FEEDBACK_ENTER_EXPLICIT(intvec_\vecname, .intrpt1, 1 << 8) 536 FEEDBACK_ENTER_EXPLICIT(intvec_\vecname, .intrpt, 1 << 8)
343 jrp lr 537 jrp lr
344 .popsection 538 .popsection
345#endif 539#endif
@@ -455,11 +649,12 @@ intvec_\vecname:
455 /* 649 /*
456 * If we will be returning to the kernel, we will need to 650 * If we will be returning to the kernel, we will need to
457 * reset the interrupt masks to the state they had before. 651 * reset the interrupt masks to the state they had before.
458 * Set DISABLE_IRQ in flags iff we came from PL1 with irqs disabled. 652 * Set DISABLE_IRQ in flags iff we came from kernel pl with
653 * irqs disabled.
459 */ 654 */
460 mfspr r32, SPR_EX_CONTEXT_K_1 655 mfspr r32, SPR_EX_CONTEXT_K_1
461 { 656 {
462 andi r32, r32, SPR_EX_CONTEXT_1_1__PL_MASK /* mask off ICS */ 657 IS_KERNEL_EX1(r22, r22)
463 PTREGS_PTR(r21, PTREGS_OFFSET_FLAGS) 658 PTREGS_PTR(r21, PTREGS_OFFSET_FLAGS)
464 } 659 }
465 beqzt r32, 1f /* zero if from user space */ 660 beqzt r32, 1f /* zero if from user space */
@@ -503,7 +698,7 @@ intvec_\vecname:
503 } 698 }
504 { 699 {
505 shl16insli r21, r21, hw1(__per_cpu_offset) 700 shl16insli r21, r21, hw1(__per_cpu_offset)
506 bfextu r20, r20, 0, LOG2_THREAD_SIZE-1 701 bfextu r20, r20, CPU_SHIFT, 63
507 } 702 }
508 shl16insli r21, r21, hw0(__per_cpu_offset) 703 shl16insli r21, r21, hw0(__per_cpu_offset)
509 shl3add r20, r20, r21 704 shl3add r20, r20, r21
@@ -585,7 +780,7 @@ intvec_\vecname:
585 .macro dc_dispatch vecnum, vecname 780 .macro dc_dispatch vecnum, vecname
586 .org (\vecnum << 8) 781 .org (\vecnum << 8)
587intvec_\vecname: 782intvec_\vecname:
588 j hv_downcall_dispatch 783 j _hv_downcall_dispatch
589 ENDPROC(intvec_\vecname) 784 ENDPROC(intvec_\vecname)
590 .endm 785 .endm
591 786
@@ -626,14 +821,36 @@ STD_ENTRY(interrupt_return)
626 PTREGS_PTR(r29, PTREGS_OFFSET_EX1) 821 PTREGS_PTR(r29, PTREGS_OFFSET_EX1)
627 } 822 }
628 ld r29, r29 823 ld r29, r29
629 andi r29, r29, SPR_EX_CONTEXT_1_1__PL_MASK /* mask off ICS */ 824 IS_KERNEL_EX1(r29, r29)
630 { 825 {
631 beqzt r29, .Lresume_userspace 826 beqzt r29, .Lresume_userspace
632 PTREGS_PTR(r29, PTREGS_OFFSET_PC) 827 move r29, sp
828 }
829
830#ifdef CONFIG_PREEMPT
831 /* Returning to kernel space. Check if we need preemption. */
832 EXTRACT_THREAD_INFO(r29)
833 addli r28, r29, THREAD_INFO_FLAGS_OFFSET
834 {
835 ld r28, r28
836 addli r29, r29, THREAD_INFO_PREEMPT_COUNT_OFFSET
837 }
838 {
839 andi r28, r28, _TIF_NEED_RESCHED
840 ld4s r29, r29
633 } 841 }
842 beqzt r28, 1f
843 bnez r29, 1f
844 jal preempt_schedule_irq
845 FEEDBACK_REENTER(interrupt_return)
8461:
847#endif
634 848
635 /* If we're resuming to _cpu_idle_nap, bump PC forward by 8. */ 849 /* If we're resuming to _cpu_idle_nap, bump PC forward by 8. */
636 moveli r27, hw2_last(_cpu_idle_nap) 850 {
851 moveli r27, hw2_last(_cpu_idle_nap)
852 PTREGS_PTR(r29, PTREGS_OFFSET_PC)
853 }
637 { 854 {
638 ld r28, r29 855 ld r28, r29
639 shl16insli r27, r27, hw1(_cpu_idle_nap) 856 shl16insli r27, r27, hw1(_cpu_idle_nap)
@@ -728,7 +945,7 @@ STD_ENTRY(interrupt_return)
728 PTREGS_PTR(r32, PTREGS_OFFSET_FLAGS) 945 PTREGS_PTR(r32, PTREGS_OFFSET_FLAGS)
729 } 946 }
730 { 947 {
731 andi r0, r0, SPR_EX_CONTEXT_1_1__PL_MASK 948 IS_KERNEL_EX1(r0, r0)
732 ld r32, r32 949 ld r32, r32
733 } 950 }
734 bnez r0, 1f 951 bnez r0, 1f
@@ -799,7 +1016,7 @@ STD_ENTRY(interrupt_return)
799 pop_reg r21, sp, PTREGS_OFFSET_REG(31) - PTREGS_OFFSET_PC 1016 pop_reg r21, sp, PTREGS_OFFSET_REG(31) - PTREGS_OFFSET_PC
800 { 1017 {
801 mtspr SPR_EX_CONTEXT_K_1, lr 1018 mtspr SPR_EX_CONTEXT_K_1, lr
802 andi lr, lr, SPR_EX_CONTEXT_1_1__PL_MASK /* mask off ICS */ 1019 IS_KERNEL_EX1(lr, lr)
803 } 1020 }
804 { 1021 {
805 mtspr SPR_EX_CONTEXT_K_0, r21 1022 mtspr SPR_EX_CONTEXT_K_0, r21
@@ -1223,10 +1440,31 @@ STD_ENTRY(_sys_clone)
1223 j sys_clone 1440 j sys_clone
1224 STD_ENDPROC(_sys_clone) 1441 STD_ENDPROC(_sys_clone)
1225 1442
1226/* The single-step support may need to read all the registers. */ 1443 /*
1444 * Recover r3, r2, r1 and r0 here saved by unalign fast vector.
1445 * The vector area limit is 32 bundles, so we handle the reload here.
1446 * r0, r1, r2 are in thread_info from low to high memory in order.
1447 * r3 points to location the original r3 was saved.
1448 * We put this code in the __HEAD section so it can be reached
1449 * via a conditional branch from the fast path.
1450 */
1451 __HEAD
1452hand_unalign_slow:
1453 andi sp, sp, ~1
1454hand_unalign_slow_badsp:
1455 addi r3, r3, -(3 * 8)
1456 ld_add r0, r3, 8
1457 ld_add r1, r3, 8
1458 ld r2, r3
1459hand_unalign_slow_nonuser:
1460 mfspr r3, SPR_SYSTEM_SAVE_K_1
1461 __int_hand INT_UNALIGN_DATA, UNALIGN_DATA_SLOW, int_unalign
1462
1463/* The unaligned data support needs to read all the registers. */
1227int_unalign: 1464int_unalign:
1228 push_extra_callee_saves r0 1465 push_extra_callee_saves r0
1229 j do_trap 1466 j do_unaligned
1467ENDPROC(hand_unalign_slow)
1230 1468
1231/* Fill the return address stack with nonzero entries. */ 1469/* Fill the return address stack with nonzero entries. */
1232STD_ENTRY(fill_ra_stack) 1470STD_ENTRY(fill_ra_stack)
@@ -1240,8 +1478,15 @@ STD_ENTRY(fill_ra_stack)
12404: jrp r0 14784: jrp r0
1241 STD_ENDPROC(fill_ra_stack) 1479 STD_ENDPROC(fill_ra_stack)
1242 1480
1243/* Include .intrpt1 array of interrupt vectors */ 1481 .macro int_hand vecnum, vecname, c_routine, processing=handle_interrupt
1244 .section ".intrpt1", "ax" 1482 .org (\vecnum << 8)
1483 __int_hand \vecnum, \vecname, \c_routine, \processing
1484 .endm
1485
1486/* Include .intrpt array of interrupt vectors */
1487 .section ".intrpt", "ax"
1488 .global intrpt_start
1489intrpt_start:
1245 1490
1246#define op_handle_perf_interrupt bad_intr 1491#define op_handle_perf_interrupt bad_intr
1247#define op_handle_aux_perf_interrupt bad_intr 1492#define op_handle_aux_perf_interrupt bad_intr
@@ -1272,7 +1517,7 @@ STD_ENTRY(fill_ra_stack)
1272 int_hand INT_SWINT_1, SWINT_1, SYSCALL, handle_syscall 1517 int_hand INT_SWINT_1, SWINT_1, SYSCALL, handle_syscall
1273 int_hand INT_SWINT_0, SWINT_0, do_trap 1518 int_hand INT_SWINT_0, SWINT_0, do_trap
1274 int_hand INT_ILL_TRANS, ILL_TRANS, do_trap 1519 int_hand INT_ILL_TRANS, ILL_TRANS, do_trap
1275 int_hand INT_UNALIGN_DATA, UNALIGN_DATA, int_unalign 1520 int_hand_unalign_fast INT_UNALIGN_DATA, UNALIGN_DATA
1276 int_hand INT_DTLB_MISS, DTLB_MISS, do_page_fault 1521 int_hand INT_DTLB_MISS, DTLB_MISS, do_page_fault
1277 int_hand INT_DTLB_ACCESS, DTLB_ACCESS, do_page_fault 1522 int_hand INT_DTLB_ACCESS, DTLB_ACCESS, do_page_fault
1278 int_hand INT_IDN_FIREWALL, IDN_FIREWALL, do_hardwall_trap 1523 int_hand INT_IDN_FIREWALL, IDN_FIREWALL, do_hardwall_trap
diff --git a/arch/tile/kernel/irq.c b/arch/tile/kernel/irq.c
index 3ccf2cd7182e..0586fdb9352d 100644
--- a/arch/tile/kernel/irq.c
+++ b/arch/tile/kernel/irq.c
@@ -55,7 +55,8 @@ static DEFINE_PER_CPU(int, irq_depth);
55 55
56/* State for allocating IRQs on Gx. */ 56/* State for allocating IRQs on Gx. */
57#if CHIP_HAS_IPI() 57#if CHIP_HAS_IPI()
58static unsigned long available_irqs = ~(1UL << IRQ_RESCHEDULE); 58static unsigned long available_irqs = ((1UL << NR_IRQS) - 1) &
59 (~(1UL << IRQ_RESCHEDULE));
59static DEFINE_SPINLOCK(available_irqs_lock); 60static DEFINE_SPINLOCK(available_irqs_lock);
60#endif 61#endif
61 62
@@ -73,7 +74,8 @@ static DEFINE_SPINLOCK(available_irqs_lock);
73 74
74/* 75/*
75 * The interrupt handling path, implemented in terms of HV interrupt 76 * The interrupt handling path, implemented in terms of HV interrupt
76 * emulation on TILE64 and TILEPro, and IPI hardware on TILE-Gx. 77 * emulation on TILEPro, and IPI hardware on TILE-Gx.
78 * Entered with interrupts disabled.
77 */ 79 */
78void tile_dev_intr(struct pt_regs *regs, int intnum) 80void tile_dev_intr(struct pt_regs *regs, int intnum)
79{ 81{
@@ -233,7 +235,7 @@ void tile_irq_activate(unsigned int irq, int tile_irq_type)
233{ 235{
234 /* 236 /*
235 * We use handle_level_irq() by default because the pending 237 * We use handle_level_irq() by default because the pending
236 * interrupt vector (whether modeled by the HV on TILE64 and 238 * interrupt vector (whether modeled by the HV on
237 * TILEPro or implemented in hardware on TILE-Gx) has 239 * TILEPro or implemented in hardware on TILE-Gx) has
238 * level-style semantics for each bit. An interrupt fires 240 * level-style semantics for each bit. An interrupt fires
239 * whenever a bit is high, not just at edges. 241 * whenever a bit is high, not just at edges.
diff --git a/arch/tile/kernel/kgdb.c b/arch/tile/kernel/kgdb.c
new file mode 100644
index 000000000000..4cd88381a83e
--- /dev/null
+++ b/arch/tile/kernel/kgdb.c
@@ -0,0 +1,499 @@
1/*
2 * Copyright 2013 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-Gx KGDB support.
15 */
16
17#include <linux/ptrace.h>
18#include <linux/kgdb.h>
19#include <linux/kdebug.h>
20#include <linux/uaccess.h>
21#include <linux/module.h>
22#include <asm/cacheflush.h>
23
24static tile_bundle_bits singlestep_insn = TILEGX_BPT_BUNDLE | DIE_SSTEPBP;
25static unsigned long stepped_addr;
26static tile_bundle_bits stepped_instr;
27
28struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] = {
29 { "r0", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[0])},
30 { "r1", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[1])},
31 { "r2", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[2])},
32 { "r3", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[3])},
33 { "r4", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[4])},
34 { "r5", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[5])},
35 { "r6", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[6])},
36 { "r7", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[7])},
37 { "r8", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[8])},
38 { "r9", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[9])},
39 { "r10", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[10])},
40 { "r11", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[11])},
41 { "r12", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[12])},
42 { "r13", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[13])},
43 { "r14", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[14])},
44 { "r15", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[15])},
45 { "r16", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[16])},
46 { "r17", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[17])},
47 { "r18", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[18])},
48 { "r19", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[19])},
49 { "r20", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[20])},
50 { "r21", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[21])},
51 { "r22", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[22])},
52 { "r23", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[23])},
53 { "r24", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[24])},
54 { "r25", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[25])},
55 { "r26", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[26])},
56 { "r27", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[27])},
57 { "r28", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[28])},
58 { "r29", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[29])},
59 { "r30", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[30])},
60 { "r31", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[31])},
61 { "r32", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[32])},
62 { "r33", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[33])},
63 { "r34", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[34])},
64 { "r35", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[35])},
65 { "r36", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[36])},
66 { "r37", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[37])},
67 { "r38", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[38])},
68 { "r39", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[39])},
69 { "r40", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[40])},
70 { "r41", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[41])},
71 { "r42", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[42])},
72 { "r43", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[43])},
73 { "r44", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[44])},
74 { "r45", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[45])},
75 { "r46", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[46])},
76 { "r47", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[47])},
77 { "r48", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[48])},
78 { "r49", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[49])},
79 { "r50", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[50])},
80 { "r51", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[51])},
81 { "r52", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[52])},
82 { "tp", GDB_SIZEOF_REG, offsetof(struct pt_regs, tp)},
83 { "sp", GDB_SIZEOF_REG, offsetof(struct pt_regs, sp)},
84 { "lr", GDB_SIZEOF_REG, offsetof(struct pt_regs, lr)},
85 { "sn", GDB_SIZEOF_REG, -1},
86 { "idn0", GDB_SIZEOF_REG, -1},
87 { "idn1", GDB_SIZEOF_REG, -1},
88 { "udn0", GDB_SIZEOF_REG, -1},
89 { "udn1", GDB_SIZEOF_REG, -1},
90 { "udn2", GDB_SIZEOF_REG, -1},
91 { "udn3", GDB_SIZEOF_REG, -1},
92 { "zero", GDB_SIZEOF_REG, -1},
93 { "pc", GDB_SIZEOF_REG, offsetof(struct pt_regs, pc)},
94 { "faultnum", GDB_SIZEOF_REG, offsetof(struct pt_regs, faultnum)},
95};
96
97char *dbg_get_reg(int regno, void *mem, struct pt_regs *regs)
98{
99 if (regno >= DBG_MAX_REG_NUM || regno < 0)
100 return NULL;
101
102 if (dbg_reg_def[regno].offset != -1)
103 memcpy(mem, (void *)regs + dbg_reg_def[regno].offset,
104 dbg_reg_def[regno].size);
105 else
106 memset(mem, 0, dbg_reg_def[regno].size);
107 return dbg_reg_def[regno].name;
108}
109
110int dbg_set_reg(int regno, void *mem, struct pt_regs *regs)
111{
112 if (regno >= DBG_MAX_REG_NUM || regno < 0)
113 return -EINVAL;
114
115 if (dbg_reg_def[regno].offset != -1)
116 memcpy((void *)regs + dbg_reg_def[regno].offset, mem,
117 dbg_reg_def[regno].size);
118 return 0;
119}
120
121/*
122 * Similar to pt_regs_to_gdb_regs() except that process is sleeping and so
123 * we may not be able to get all the info.
124 */
125void
126sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *task)
127{
128 int reg;
129 struct pt_regs *thread_regs;
130 unsigned long *ptr = gdb_regs;
131
132 if (task == NULL)
133 return;
134
135 /* Initialize to zero. */
136 memset(gdb_regs, 0, NUMREGBYTES);
137
138 thread_regs = task_pt_regs(task);
139 for (reg = 0; reg <= TREG_LAST_GPR; reg++)
140 *(ptr++) = thread_regs->regs[reg];
141
142 gdb_regs[TILEGX_PC_REGNUM] = thread_regs->pc;
143 gdb_regs[TILEGX_FAULTNUM_REGNUM] = thread_regs->faultnum;
144}
145
146void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long pc)
147{
148 regs->pc = pc;
149}
150
151static void kgdb_call_nmi_hook(void *ignored)
152{
153 kgdb_nmicallback(raw_smp_processor_id(), NULL);
154}
155
156void kgdb_roundup_cpus(unsigned long flags)
157{
158 local_irq_enable();
159 smp_call_function(kgdb_call_nmi_hook, NULL, 0);
160 local_irq_disable();
161}
162
163/*
164 * Convert a kernel address to the writable kernel text mapping.
165 */
166static unsigned long writable_address(unsigned long addr)
167{
168 unsigned long ret = 0;
169
170 if (core_kernel_text(addr))
171 ret = addr - MEM_SV_START + PAGE_OFFSET;
172 else if (is_module_text_address(addr))
173 ret = addr;
174 else
175 pr_err("Unknown virtual address 0x%lx\n", addr);
176
177 return ret;
178}
179
180/*
181 * Calculate the new address for after a step.
182 */
183static unsigned long get_step_address(struct pt_regs *regs)
184{
185 int src_reg;
186 int jump_off;
187 int br_off;
188 unsigned long addr;
189 unsigned int opcode;
190 tile_bundle_bits bundle;
191
192 /* Move to the next instruction by default. */
193 addr = regs->pc + TILEGX_BUNDLE_SIZE_IN_BYTES;
194 bundle = *(unsigned long *)instruction_pointer(regs);
195
196 /* 0: X mode, Otherwise: Y mode. */
197 if (bundle & TILEGX_BUNDLE_MODE_MASK) {
198 if (get_Opcode_Y1(bundle) == RRR_1_OPCODE_Y1 &&
199 get_RRROpcodeExtension_Y1(bundle) ==
200 UNARY_RRR_1_OPCODE_Y1) {
201 opcode = get_UnaryOpcodeExtension_Y1(bundle);
202
203 switch (opcode) {
204 case JALR_UNARY_OPCODE_Y1:
205 case JALRP_UNARY_OPCODE_Y1:
206 case JR_UNARY_OPCODE_Y1:
207 case JRP_UNARY_OPCODE_Y1:
208 src_reg = get_SrcA_Y1(bundle);
209 dbg_get_reg(src_reg, &addr, regs);
210 break;
211 }
212 }
213 } else if (get_Opcode_X1(bundle) == RRR_0_OPCODE_X1) {
214 if (get_RRROpcodeExtension_X1(bundle) ==
215 UNARY_RRR_0_OPCODE_X1) {
216 opcode = get_UnaryOpcodeExtension_X1(bundle);
217
218 switch (opcode) {
219 case JALR_UNARY_OPCODE_X1:
220 case JALRP_UNARY_OPCODE_X1:
221 case JR_UNARY_OPCODE_X1:
222 case JRP_UNARY_OPCODE_X1:
223 src_reg = get_SrcA_X1(bundle);
224 dbg_get_reg(src_reg, &addr, regs);
225 break;
226 }
227 }
228 } else if (get_Opcode_X1(bundle) == JUMP_OPCODE_X1) {
229 opcode = get_JumpOpcodeExtension_X1(bundle);
230
231 switch (opcode) {
232 case JAL_JUMP_OPCODE_X1:
233 case J_JUMP_OPCODE_X1:
234 jump_off = sign_extend(get_JumpOff_X1(bundle), 27);
235 addr = regs->pc +
236 (jump_off << TILEGX_LOG2_BUNDLE_SIZE_IN_BYTES);
237 break;
238 }
239 } else if (get_Opcode_X1(bundle) == BRANCH_OPCODE_X1) {
240 br_off = 0;
241 opcode = get_BrType_X1(bundle);
242
243 switch (opcode) {
244 case BEQZT_BRANCH_OPCODE_X1:
245 case BEQZ_BRANCH_OPCODE_X1:
246 if (get_SrcA_X1(bundle) == 0)
247 br_off = get_BrOff_X1(bundle);
248 break;
249 case BGEZT_BRANCH_OPCODE_X1:
250 case BGEZ_BRANCH_OPCODE_X1:
251 if (get_SrcA_X1(bundle) >= 0)
252 br_off = get_BrOff_X1(bundle);
253 break;
254 case BGTZT_BRANCH_OPCODE_X1:
255 case BGTZ_BRANCH_OPCODE_X1:
256 if (get_SrcA_X1(bundle) > 0)
257 br_off = get_BrOff_X1(bundle);
258 break;
259 case BLBCT_BRANCH_OPCODE_X1:
260 case BLBC_BRANCH_OPCODE_X1:
261 if (!(get_SrcA_X1(bundle) & 1))
262 br_off = get_BrOff_X1(bundle);
263 break;
264 case BLBST_BRANCH_OPCODE_X1:
265 case BLBS_BRANCH_OPCODE_X1:
266 if (get_SrcA_X1(bundle) & 1)
267 br_off = get_BrOff_X1(bundle);
268 break;
269 case BLEZT_BRANCH_OPCODE_X1:
270 case BLEZ_BRANCH_OPCODE_X1:
271 if (get_SrcA_X1(bundle) <= 0)
272 br_off = get_BrOff_X1(bundle);
273 break;
274 case BLTZT_BRANCH_OPCODE_X1:
275 case BLTZ_BRANCH_OPCODE_X1:
276 if (get_SrcA_X1(bundle) < 0)
277 br_off = get_BrOff_X1(bundle);
278 break;
279 case BNEZT_BRANCH_OPCODE_X1:
280 case BNEZ_BRANCH_OPCODE_X1:
281 if (get_SrcA_X1(bundle) != 0)
282 br_off = get_BrOff_X1(bundle);
283 break;
284 }
285
286 if (br_off != 0) {
287 br_off = sign_extend(br_off, 17);
288 addr = regs->pc +
289 (br_off << TILEGX_LOG2_BUNDLE_SIZE_IN_BYTES);
290 }
291 }
292
293 return addr;
294}
295
296/*
297 * Replace the next instruction after the current instruction with a
298 * breakpoint instruction.
299 */
300static void do_single_step(struct pt_regs *regs)
301{
302 unsigned long addr_wr;
303
304 /* Determine where the target instruction will send us to. */
305 stepped_addr = get_step_address(regs);
306 probe_kernel_read((char *)&stepped_instr, (char *)stepped_addr,
307 BREAK_INSTR_SIZE);
308
309 addr_wr = writable_address(stepped_addr);
310 probe_kernel_write((char *)addr_wr, (char *)&singlestep_insn,
311 BREAK_INSTR_SIZE);
312 smp_wmb();
313 flush_icache_range(stepped_addr, stepped_addr + BREAK_INSTR_SIZE);
314}
315
316static void undo_single_step(struct pt_regs *regs)
317{
318 unsigned long addr_wr;
319
320 if (stepped_instr == 0)
321 return;
322
323 addr_wr = writable_address(stepped_addr);
324 probe_kernel_write((char *)addr_wr, (char *)&stepped_instr,
325 BREAK_INSTR_SIZE);
326 stepped_instr = 0;
327 smp_wmb();
328 flush_icache_range(stepped_addr, stepped_addr + BREAK_INSTR_SIZE);
329}
330
331/*
332 * Calls linux_debug_hook before the kernel dies. If KGDB is enabled,
333 * then try to fall into the debugger.
334 */
335static int
336kgdb_notify(struct notifier_block *self, unsigned long cmd, void *ptr)
337{
338 int ret;
339 unsigned long flags;
340 struct die_args *args = (struct die_args *)ptr;
341 struct pt_regs *regs = args->regs;
342
343#ifdef CONFIG_KPROBES
344 /*
345 * Return immediately if the kprobes fault notifier has set
346 * DIE_PAGE_FAULT.
347 */
348 if (cmd == DIE_PAGE_FAULT)
349 return NOTIFY_DONE;
350#endif /* CONFIG_KPROBES */
351
352 switch (cmd) {
353 case DIE_BREAK:
354 case DIE_COMPILED_BPT:
355 break;
356 case DIE_SSTEPBP:
357 local_irq_save(flags);
358 kgdb_handle_exception(0, SIGTRAP, 0, regs);
359 local_irq_restore(flags);
360 return NOTIFY_STOP;
361 default:
362 /* Userspace events, ignore. */
363 if (user_mode(regs))
364 return NOTIFY_DONE;
365 }
366
367 local_irq_save(flags);
368 ret = kgdb_handle_exception(args->trapnr, args->signr, args->err, regs);
369 local_irq_restore(flags);
370 if (ret)
371 return NOTIFY_DONE;
372
373 return NOTIFY_STOP;
374}
375
376static struct notifier_block kgdb_notifier = {
377 .notifier_call = kgdb_notify,
378};
379
380/*
381 * kgdb_arch_handle_exception - Handle architecture specific GDB packets.
382 * @vector: The error vector of the exception that happened.
383 * @signo: The signal number of the exception that happened.
384 * @err_code: The error code of the exception that happened.
385 * @remcom_in_buffer: The buffer of the packet we have read.
386 * @remcom_out_buffer: The buffer of %BUFMAX bytes to write a packet into.
387 * @regs: The &struct pt_regs of the current process.
388 *
389 * This function MUST handle the 'c' and 's' command packets,
390 * as well packets to set / remove a hardware breakpoint, if used.
391 * If there are additional packets which the hardware needs to handle,
392 * they are handled here. The code should return -1 if it wants to
393 * process more packets, and a %0 or %1 if it wants to exit from the
394 * kgdb callback.
395 */
396int kgdb_arch_handle_exception(int vector, int signo, int err_code,
397 char *remcom_in_buffer, char *remcom_out_buffer,
398 struct pt_regs *regs)
399{
400 char *ptr;
401 unsigned long address;
402
403 /* Undo any stepping we may have done. */
404 undo_single_step(regs);
405
406 switch (remcom_in_buffer[0]) {
407 case 'c':
408 case 's':
409 case 'D':
410 case 'k':
411 /*
412 * Try to read optional parameter, pc unchanged if no parm.
413 * If this was a compiled-in breakpoint, we need to move
414 * to the next instruction or we will just breakpoint
415 * over and over again.
416 */
417 ptr = &remcom_in_buffer[1];
418 if (kgdb_hex2long(&ptr, &address))
419 regs->pc = address;
420 else if (*(unsigned long *)regs->pc == compiled_bpt)
421 regs->pc += BREAK_INSTR_SIZE;
422
423 if (remcom_in_buffer[0] == 's') {
424 do_single_step(regs);
425 kgdb_single_step = 1;
426 atomic_set(&kgdb_cpu_doing_single_step,
427 raw_smp_processor_id());
428 } else
429 atomic_set(&kgdb_cpu_doing_single_step, -1);
430
431 return 0;
432 }
433
434 return -1; /* this means that we do not want to exit from the handler */
435}
436
437struct kgdb_arch arch_kgdb_ops;
438
439/*
440 * kgdb_arch_init - Perform any architecture specific initalization.
441 *
442 * This function will handle the initalization of any architecture
443 * specific callbacks.
444 */
445int kgdb_arch_init(void)
446{
447 tile_bundle_bits bundle = TILEGX_BPT_BUNDLE;
448
449 memcpy(arch_kgdb_ops.gdb_bpt_instr, &bundle, BREAK_INSTR_SIZE);
450 return register_die_notifier(&kgdb_notifier);
451}
452
453/*
454 * kgdb_arch_exit - Perform any architecture specific uninitalization.
455 *
456 * This function will handle the uninitalization of any architecture
457 * specific callbacks, for dynamic registration and unregistration.
458 */
459void kgdb_arch_exit(void)
460{
461 unregister_die_notifier(&kgdb_notifier);
462}
463
464int kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt)
465{
466 int err;
467 unsigned long addr_wr = writable_address(bpt->bpt_addr);
468
469 if (addr_wr == 0)
470 return -1;
471
472 err = probe_kernel_read(bpt->saved_instr, (char *)bpt->bpt_addr,
473 BREAK_INSTR_SIZE);
474 if (err)
475 return err;
476
477 err = probe_kernel_write((char *)addr_wr, arch_kgdb_ops.gdb_bpt_instr,
478 BREAK_INSTR_SIZE);
479 smp_wmb();
480 flush_icache_range((unsigned long)bpt->bpt_addr,
481 (unsigned long)bpt->bpt_addr + BREAK_INSTR_SIZE);
482 return err;
483}
484
485int kgdb_arch_remove_breakpoint(struct kgdb_bkpt *bpt)
486{
487 int err;
488 unsigned long addr_wr = writable_address(bpt->bpt_addr);
489
490 if (addr_wr == 0)
491 return -1;
492
493 err = probe_kernel_write((char *)addr_wr, (char *)bpt->saved_instr,
494 BREAK_INSTR_SIZE);
495 smp_wmb();
496 flush_icache_range((unsigned long)bpt->bpt_addr,
497 (unsigned long)bpt->bpt_addr + BREAK_INSTR_SIZE);
498 return err;
499}
diff --git a/arch/tile/kernel/kprobes.c b/arch/tile/kernel/kprobes.c
new file mode 100644
index 000000000000..27cdcacbe81d
--- /dev/null
+++ b/arch/tile/kernel/kprobes.c
@@ -0,0 +1,528 @@
1/*
2 * arch/tile/kernel/kprobes.c
3 * Kprobes on TILE-Gx
4 *
5 * Some portions copied from the MIPS version.
6 *
7 * Copyright (C) IBM Corporation, 2002, 2004
8 * Copyright 2006 Sony Corp.
9 * Copyright 2010 Cavium Networks
10 *
11 * Copyright 2012 Tilera Corporation. All Rights Reserved.
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation, version 2.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
20 * NON INFRINGEMENT. See the GNU General Public License for
21 * more details.
22 */
23
24#include <linux/kprobes.h>
25#include <linux/kdebug.h>
26#include <linux/module.h>
27#include <linux/slab.h>
28#include <linux/uaccess.h>
29#include <asm/cacheflush.h>
30
31#include <arch/opcode.h>
32
33DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
34DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
35
36tile_bundle_bits breakpoint_insn = TILEGX_BPT_BUNDLE;
37tile_bundle_bits breakpoint2_insn = TILEGX_BPT_BUNDLE | DIE_SSTEPBP;
38
39/*
40 * Check whether instruction is branch or jump, or if executing it
41 * has different results depending on where it is executed (e.g. lnk).
42 */
43static int __kprobes insn_has_control(kprobe_opcode_t insn)
44{
45 if (get_Mode(insn) != 0) { /* Y-format bundle */
46 if (get_Opcode_Y1(insn) != RRR_1_OPCODE_Y1 ||
47 get_RRROpcodeExtension_Y1(insn) != UNARY_RRR_1_OPCODE_Y1)
48 return 0;
49
50 switch (get_UnaryOpcodeExtension_Y1(insn)) {
51 case JALRP_UNARY_OPCODE_Y1:
52 case JALR_UNARY_OPCODE_Y1:
53 case JRP_UNARY_OPCODE_Y1:
54 case JR_UNARY_OPCODE_Y1:
55 case LNK_UNARY_OPCODE_Y1:
56 return 1;
57 default:
58 return 0;
59 }
60 }
61
62 switch (get_Opcode_X1(insn)) {
63 case BRANCH_OPCODE_X1: /* branch instructions */
64 case JUMP_OPCODE_X1: /* jump instructions: j and jal */
65 return 1;
66
67 case RRR_0_OPCODE_X1: /* other jump instructions */
68 if (get_RRROpcodeExtension_X1(insn) != UNARY_RRR_0_OPCODE_X1)
69 return 0;
70 switch (get_UnaryOpcodeExtension_X1(insn)) {
71 case JALRP_UNARY_OPCODE_X1:
72 case JALR_UNARY_OPCODE_X1:
73 case JRP_UNARY_OPCODE_X1:
74 case JR_UNARY_OPCODE_X1:
75 case LNK_UNARY_OPCODE_X1:
76 return 1;
77 default:
78 return 0;
79 }
80 default:
81 return 0;
82 }
83}
84
85int __kprobes arch_prepare_kprobe(struct kprobe *p)
86{
87 unsigned long addr = (unsigned long)p->addr;
88
89 if (addr & (sizeof(kprobe_opcode_t) - 1))
90 return -EINVAL;
91
92 if (insn_has_control(*p->addr)) {
93 pr_notice("Kprobes for control instructions are not "
94 "supported\n");
95 return -EINVAL;
96 }
97
98 /* insn: must be on special executable page on tile. */
99 p->ainsn.insn = get_insn_slot();
100 if (!p->ainsn.insn)
101 return -ENOMEM;
102
103 /*
104 * In the kprobe->ainsn.insn[] array we store the original
105 * instruction at index zero and a break trap instruction at
106 * index one.
107 */
108 memcpy(&p->ainsn.insn[0], p->addr, sizeof(kprobe_opcode_t));
109 p->ainsn.insn[1] = breakpoint2_insn;
110 p->opcode = *p->addr;
111
112 return 0;
113}
114
115void __kprobes arch_arm_kprobe(struct kprobe *p)
116{
117 unsigned long addr_wr;
118
119 /* Operate on writable kernel text mapping. */
120 addr_wr = (unsigned long)p->addr - MEM_SV_START + PAGE_OFFSET;
121
122 if (probe_kernel_write((void *)addr_wr, &breakpoint_insn,
123 sizeof(breakpoint_insn)))
124 pr_err("%s: failed to enable kprobe\n", __func__);
125
126 smp_wmb();
127 flush_insn_slot(p);
128}
129
130void __kprobes arch_disarm_kprobe(struct kprobe *kp)
131{
132 unsigned long addr_wr;
133
134 /* Operate on writable kernel text mapping. */
135 addr_wr = (unsigned long)kp->addr - MEM_SV_START + PAGE_OFFSET;
136
137 if (probe_kernel_write((void *)addr_wr, &kp->opcode,
138 sizeof(kp->opcode)))
139 pr_err("%s: failed to enable kprobe\n", __func__);
140
141 smp_wmb();
142 flush_insn_slot(kp);
143}
144
145void __kprobes arch_remove_kprobe(struct kprobe *p)
146{
147 if (p->ainsn.insn) {
148 free_insn_slot(p->ainsn.insn, 0);
149 p->ainsn.insn = NULL;
150 }
151}
152
153static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb)
154{
155 kcb->prev_kprobe.kp = kprobe_running();
156 kcb->prev_kprobe.status = kcb->kprobe_status;
157 kcb->prev_kprobe.saved_pc = kcb->kprobe_saved_pc;
158}
159
160static void __kprobes restore_previous_kprobe(struct kprobe_ctlblk *kcb)
161{
162 __this_cpu_write(current_kprobe, kcb->prev_kprobe.kp);
163 kcb->kprobe_status = kcb->prev_kprobe.status;
164 kcb->kprobe_saved_pc = kcb->prev_kprobe.saved_pc;
165}
166
167static void __kprobes set_current_kprobe(struct kprobe *p, struct pt_regs *regs,
168 struct kprobe_ctlblk *kcb)
169{
170 __this_cpu_write(current_kprobe, p);
171 kcb->kprobe_saved_pc = regs->pc;
172}
173
174static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
175{
176 /* Single step inline if the instruction is a break. */
177 if (p->opcode == breakpoint_insn ||
178 p->opcode == breakpoint2_insn)
179 regs->pc = (unsigned long)p->addr;
180 else
181 regs->pc = (unsigned long)&p->ainsn.insn[0];
182}
183
184static int __kprobes kprobe_handler(struct pt_regs *regs)
185{
186 struct kprobe *p;
187 int ret = 0;
188 kprobe_opcode_t *addr;
189 struct kprobe_ctlblk *kcb;
190
191 addr = (kprobe_opcode_t *)regs->pc;
192
193 /*
194 * We don't want to be preempted for the entire
195 * duration of kprobe processing.
196 */
197 preempt_disable();
198 kcb = get_kprobe_ctlblk();
199
200 /* Check we're not actually recursing. */
201 if (kprobe_running()) {
202 p = get_kprobe(addr);
203 if (p) {
204 if (kcb->kprobe_status == KPROBE_HIT_SS &&
205 p->ainsn.insn[0] == breakpoint_insn) {
206 goto no_kprobe;
207 }
208 /*
209 * We have reentered the kprobe_handler(), since
210 * another probe was hit while within the handler.
211 * We here save the original kprobes variables and
212 * just single step on the instruction of the new probe
213 * without calling any user handlers.
214 */
215 save_previous_kprobe(kcb);
216 set_current_kprobe(p, regs, kcb);
217 kprobes_inc_nmissed_count(p);
218 prepare_singlestep(p, regs);
219 kcb->kprobe_status = KPROBE_REENTER;
220 return 1;
221 } else {
222 if (*addr != breakpoint_insn) {
223 /*
224 * The breakpoint instruction was removed by
225 * another cpu right after we hit, no further
226 * handling of this interrupt is appropriate.
227 */
228 ret = 1;
229 goto no_kprobe;
230 }
231 p = __this_cpu_read(current_kprobe);
232 if (p->break_handler && p->break_handler(p, regs))
233 goto ss_probe;
234 }
235 goto no_kprobe;
236 }
237
238 p = get_kprobe(addr);
239 if (!p) {
240 if (*addr != breakpoint_insn) {
241 /*
242 * The breakpoint instruction was removed right
243 * after we hit it. Another cpu has removed
244 * either a probepoint or a debugger breakpoint
245 * at this address. In either case, no further
246 * handling of this interrupt is appropriate.
247 */
248 ret = 1;
249 }
250 /* Not one of ours: let kernel handle it. */
251 goto no_kprobe;
252 }
253
254 set_current_kprobe(p, regs, kcb);
255 kcb->kprobe_status = KPROBE_HIT_ACTIVE;
256
257 if (p->pre_handler && p->pre_handler(p, regs)) {
258 /* Handler has already set things up, so skip ss setup. */
259 return 1;
260 }
261
262ss_probe:
263 prepare_singlestep(p, regs);
264 kcb->kprobe_status = KPROBE_HIT_SS;
265 return 1;
266
267no_kprobe:
268 preempt_enable_no_resched();
269 return ret;
270}
271
272/*
273 * Called after single-stepping. p->addr is the address of the
274 * instruction that has been replaced by the breakpoint. To avoid the
275 * SMP problems that can occur when we temporarily put back the
276 * original opcode to single-step, we single-stepped a copy of the
277 * instruction. The address of this copy is p->ainsn.insn.
278 *
279 * This function prepares to return from the post-single-step
280 * breakpoint trap.
281 */
282static void __kprobes resume_execution(struct kprobe *p,
283 struct pt_regs *regs,
284 struct kprobe_ctlblk *kcb)
285{
286 unsigned long orig_pc = kcb->kprobe_saved_pc;
287 regs->pc = orig_pc + 8;
288}
289
290static inline int post_kprobe_handler(struct pt_regs *regs)
291{
292 struct kprobe *cur = kprobe_running();
293 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
294
295 if (!cur)
296 return 0;
297
298 if ((kcb->kprobe_status != KPROBE_REENTER) && cur->post_handler) {
299 kcb->kprobe_status = KPROBE_HIT_SSDONE;
300 cur->post_handler(cur, regs, 0);
301 }
302
303 resume_execution(cur, regs, kcb);
304
305 /* Restore back the original saved kprobes variables and continue. */
306 if (kcb->kprobe_status == KPROBE_REENTER) {
307 restore_previous_kprobe(kcb);
308 goto out;
309 }
310 reset_current_kprobe();
311out:
312 preempt_enable_no_resched();
313
314 return 1;
315}
316
317static inline int kprobe_fault_handler(struct pt_regs *regs, int trapnr)
318{
319 struct kprobe *cur = kprobe_running();
320 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
321
322 if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr))
323 return 1;
324
325 if (kcb->kprobe_status & KPROBE_HIT_SS) {
326 /*
327 * We are here because the instruction being single
328 * stepped caused a page fault. We reset the current
329 * kprobe and the ip points back to the probe address
330 * and allow the page fault handler to continue as a
331 * normal page fault.
332 */
333 resume_execution(cur, regs, kcb);
334 reset_current_kprobe();
335 preempt_enable_no_resched();
336 }
337 return 0;
338}
339
340/*
341 * Wrapper routine for handling exceptions.
342 */
343int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
344 unsigned long val, void *data)
345{
346 struct die_args *args = (struct die_args *)data;
347 int ret = NOTIFY_DONE;
348
349 switch (val) {
350 case DIE_BREAK:
351 if (kprobe_handler(args->regs))
352 ret = NOTIFY_STOP;
353 break;
354 case DIE_SSTEPBP:
355 if (post_kprobe_handler(args->regs))
356 ret = NOTIFY_STOP;
357 break;
358 case DIE_PAGE_FAULT:
359 /* kprobe_running() needs smp_processor_id(). */
360 preempt_disable();
361
362 if (kprobe_running()
363 && kprobe_fault_handler(args->regs, args->trapnr))
364 ret = NOTIFY_STOP;
365 preempt_enable();
366 break;
367 default:
368 break;
369 }
370 return ret;
371}
372
373int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
374{
375 struct jprobe *jp = container_of(p, struct jprobe, kp);
376 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
377
378 kcb->jprobe_saved_regs = *regs;
379 kcb->jprobe_saved_sp = regs->sp;
380
381 memcpy(kcb->jprobes_stack, (void *)kcb->jprobe_saved_sp,
382 MIN_JPROBES_STACK_SIZE(kcb->jprobe_saved_sp));
383
384 regs->pc = (unsigned long)(jp->entry);
385
386 return 1;
387}
388
389/* Defined in the inline asm below. */
390void jprobe_return_end(void);
391
392void __kprobes jprobe_return(void)
393{
394 asm volatile(
395 "bpt\n\t"
396 ".globl jprobe_return_end\n"
397 "jprobe_return_end:\n");
398}
399
400int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
401{
402 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
403
404 if (regs->pc >= (unsigned long)jprobe_return &&
405 regs->pc <= (unsigned long)jprobe_return_end) {
406 *regs = kcb->jprobe_saved_regs;
407 memcpy((void *)kcb->jprobe_saved_sp, kcb->jprobes_stack,
408 MIN_JPROBES_STACK_SIZE(kcb->jprobe_saved_sp));
409 preempt_enable_no_resched();
410
411 return 1;
412 }
413 return 0;
414}
415
416/*
417 * Function return probe trampoline:
418 * - init_kprobes() establishes a probepoint here
419 * - When the probed function returns, this probe causes the
420 * handlers to fire
421 */
422static void __used kretprobe_trampoline_holder(void)
423{
424 asm volatile(
425 "nop\n\t"
426 ".global kretprobe_trampoline\n"
427 "kretprobe_trampoline:\n\t"
428 "nop\n\t"
429 : : : "memory");
430}
431
432void kretprobe_trampoline(void);
433
434void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
435 struct pt_regs *regs)
436{
437 ri->ret_addr = (kprobe_opcode_t *) regs->lr;
438
439 /* Replace the return addr with trampoline addr */
440 regs->lr = (unsigned long)kretprobe_trampoline;
441}
442
443/*
444 * Called when the probe at kretprobe trampoline is hit.
445 */
446static int __kprobes trampoline_probe_handler(struct kprobe *p,
447 struct pt_regs *regs)
448{
449 struct kretprobe_instance *ri = NULL;
450 struct hlist_head *head, empty_rp;
451 struct hlist_node *tmp;
452 unsigned long flags, orig_ret_address = 0;
453 unsigned long trampoline_address = (unsigned long)kretprobe_trampoline;
454
455 INIT_HLIST_HEAD(&empty_rp);
456 kretprobe_hash_lock(current, &head, &flags);
457
458 /*
459 * It is possible to have multiple instances associated with a given
460 * task either because multiple functions in the call path have
461 * a return probe installed on them, and/or more than one return
462 * return probe was registered for a target function.
463 *
464 * We can handle this because:
465 * - instances are always inserted at the head of the list
466 * - when multiple return probes are registered for the same
467 * function, the first instance's ret_addr will point to the
468 * real return address, and all the rest will point to
469 * kretprobe_trampoline
470 */
471 hlist_for_each_entry_safe(ri, tmp, head, hlist) {
472 if (ri->task != current)
473 /* another task is sharing our hash bucket */
474 continue;
475
476 if (ri->rp && ri->rp->handler)
477 ri->rp->handler(ri, regs);
478
479 orig_ret_address = (unsigned long)ri->ret_addr;
480 recycle_rp_inst(ri, &empty_rp);
481
482 if (orig_ret_address != trampoline_address) {
483 /*
484 * This is the real return address. Any other
485 * instances associated with this task are for
486 * other calls deeper on the call stack
487 */
488 break;
489 }
490 }
491
492 kretprobe_assert(ri, orig_ret_address, trampoline_address);
493 instruction_pointer(regs) = orig_ret_address;
494
495 reset_current_kprobe();
496 kretprobe_hash_unlock(current, &flags);
497 preempt_enable_no_resched();
498
499 hlist_for_each_entry_safe(ri, tmp, &empty_rp, hlist) {
500 hlist_del(&ri->hlist);
501 kfree(ri);
502 }
503 /*
504 * By returning a non-zero value, we are telling
505 * kprobe_handler() that we don't want the post_handler
506 * to run (and have re-enabled preemption)
507 */
508 return 1;
509}
510
511int __kprobes arch_trampoline_kprobe(struct kprobe *p)
512{
513 if (p->addr == (kprobe_opcode_t *)kretprobe_trampoline)
514 return 1;
515
516 return 0;
517}
518
519static struct kprobe trampoline_p = {
520 .addr = (kprobe_opcode_t *)kretprobe_trampoline,
521 .pre_handler = trampoline_probe_handler
522};
523
524int __init arch_init_kprobes(void)
525{
526 register_kprobe(&trampoline_p);
527 return 0;
528}
diff --git a/arch/tile/kernel/mcount_64.S b/arch/tile/kernel/mcount_64.S
new file mode 100644
index 000000000000..70d7bb0c4d8f
--- /dev/null
+++ b/arch/tile/kernel/mcount_64.S
@@ -0,0 +1,224 @@
1/*
2 * Copyright 2012 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-Gx specific __mcount support
15 */
16
17#include <linux/linkage.h>
18#include <asm/ftrace.h>
19
20#define REGSIZE 8
21
22 .text
23 .global __mcount
24
25 .macro MCOUNT_SAVE_REGS
26 addli sp, sp, -REGSIZE
27 {
28 st sp, lr
29 addli r29, sp, - (12 * REGSIZE)
30 }
31 {
32 addli sp, sp, - (13 * REGSIZE)
33 st r29, sp
34 }
35 addli r29, r29, REGSIZE
36 { st r29, r0; addli r29, r29, REGSIZE }
37 { st r29, r1; addli r29, r29, REGSIZE }
38 { st r29, r2; addli r29, r29, REGSIZE }
39 { st r29, r3; addli r29, r29, REGSIZE }
40 { st r29, r4; addli r29, r29, REGSIZE }
41 { st r29, r5; addli r29, r29, REGSIZE }
42 { st r29, r6; addli r29, r29, REGSIZE }
43 { st r29, r7; addli r29, r29, REGSIZE }
44 { st r29, r8; addli r29, r29, REGSIZE }
45 { st r29, r9; addli r29, r29, REGSIZE }
46 { st r29, r10; addli r29, r29, REGSIZE }
47 .endm
48
49 .macro MCOUNT_RESTORE_REGS
50 addli r29, sp, (2 * REGSIZE)
51 { ld r0, r29; addli r29, r29, REGSIZE }
52 { ld r1, r29; addli r29, r29, REGSIZE }
53 { ld r2, r29; addli r29, r29, REGSIZE }
54 { ld r3, r29; addli r29, r29, REGSIZE }
55 { ld r4, r29; addli r29, r29, REGSIZE }
56 { ld r5, r29; addli r29, r29, REGSIZE }
57 { ld r6, r29; addli r29, r29, REGSIZE }
58 { ld r7, r29; addli r29, r29, REGSIZE }
59 { ld r8, r29; addli r29, r29, REGSIZE }
60 { ld r9, r29; addli r29, r29, REGSIZE }
61 { ld r10, r29; addli lr, sp, (13 * REGSIZE) }
62 { ld lr, lr; addli sp, sp, (14 * REGSIZE) }
63 .endm
64
65 .macro RETURN_BACK
66 { move r12, lr; move lr, r10 }
67 jrp r12
68 .endm
69
70#ifdef CONFIG_DYNAMIC_FTRACE
71
72 .align 64
73STD_ENTRY(__mcount)
74__mcount:
75 j ftrace_stub
76STD_ENDPROC(__mcount)
77
78 .align 64
79STD_ENTRY(ftrace_caller)
80 moveli r11, hw2_last(function_trace_stop)
81 { shl16insli r11, r11, hw1(function_trace_stop); move r12, lr }
82 { shl16insli r11, r11, hw0(function_trace_stop); move lr, r10 }
83 ld r11, r11
84 beqz r11, 1f
85 jrp r12
86
871:
88 { move r10, lr; move lr, r12 }
89 MCOUNT_SAVE_REGS
90
91 /* arg1: self return address */
92 /* arg2: parent's return address */
93 { move r0, lr; move r1, r10 }
94
95 .global ftrace_call
96ftrace_call:
97 /*
98 * a placeholder for the call to a real tracing function, i.e.
99 * ftrace_trace_function()
100 */
101 nop
102
103#ifdef CONFIG_FUNCTION_GRAPH_TRACER
104 .global ftrace_graph_call
105ftrace_graph_call:
106 /*
107 * a placeholder for the call to a real tracing function, i.e.
108 * ftrace_graph_caller()
109 */
110 nop
111#endif
112 MCOUNT_RESTORE_REGS
113 .global ftrace_stub
114ftrace_stub:
115 RETURN_BACK
116STD_ENDPROC(ftrace_caller)
117
118#else /* ! CONFIG_DYNAMIC_FTRACE */
119
120 .align 64
121STD_ENTRY(__mcount)
122 moveli r11, hw2_last(function_trace_stop)
123 { shl16insli r11, r11, hw1(function_trace_stop); move r12, lr }
124 { shl16insli r11, r11, hw0(function_trace_stop); move lr, r10 }
125 ld r11, r11
126 beqz r11, 1f
127 jrp r12
128
1291:
130 { move r10, lr; move lr, r12 }
131 {
132 moveli r11, hw2_last(ftrace_trace_function)
133 moveli r13, hw2_last(ftrace_stub)
134 }
135 {
136 shl16insli r11, r11, hw1(ftrace_trace_function)
137 shl16insli r13, r13, hw1(ftrace_stub)
138 }
139 {
140 shl16insli r11, r11, hw0(ftrace_trace_function)
141 shl16insli r13, r13, hw0(ftrace_stub)
142 }
143
144 ld r11, r11
145 sub r14, r13, r11
146 bnez r14, static_trace
147
148#ifdef CONFIG_FUNCTION_GRAPH_TRACER
149 moveli r15, hw2_last(ftrace_graph_return)
150 shl16insli r15, r15, hw1(ftrace_graph_return)
151 shl16insli r15, r15, hw0(ftrace_graph_return)
152 ld r15, r15
153 sub r15, r15, r13
154 bnez r15, ftrace_graph_caller
155
156 {
157 moveli r16, hw2_last(ftrace_graph_entry)
158 moveli r17, hw2_last(ftrace_graph_entry_stub)
159 }
160 {
161 shl16insli r16, r16, hw1(ftrace_graph_entry)
162 shl16insli r17, r17, hw1(ftrace_graph_entry_stub)
163 }
164 {
165 shl16insli r16, r16, hw0(ftrace_graph_entry)
166 shl16insli r17, r17, hw0(ftrace_graph_entry_stub)
167 }
168 ld r16, r16
169 sub r17, r16, r17
170 bnez r17, ftrace_graph_caller
171
172#endif
173 RETURN_BACK
174
175static_trace:
176 MCOUNT_SAVE_REGS
177
178 /* arg1: self return address */
179 /* arg2: parent's return address */
180 { move r0, lr; move r1, r10 }
181
182 /* call ftrace_trace_function() */
183 jalr r11
184
185 MCOUNT_RESTORE_REGS
186
187 .global ftrace_stub
188ftrace_stub:
189 RETURN_BACK
190STD_ENDPROC(__mcount)
191
192#endif /* ! CONFIG_DYNAMIC_FTRACE */
193
194#ifdef CONFIG_FUNCTION_GRAPH_TRACER
195
196STD_ENTRY(ftrace_graph_caller)
197ftrace_graph_caller:
198#ifndef CONFIG_DYNAMIC_FTRACE
199 MCOUNT_SAVE_REGS
200#endif
201
202 /* arg1: Get the location of the parent's return address */
203 addi r0, sp, 12 * REGSIZE
204 /* arg2: Get self return address */
205 move r1, lr
206
207 jal prepare_ftrace_return
208
209 MCOUNT_RESTORE_REGS
210 RETURN_BACK
211STD_ENDPROC(ftrace_graph_caller)
212
213 .global return_to_handler
214return_to_handler:
215 MCOUNT_SAVE_REGS
216
217 jal ftrace_return_to_handler
218 /* restore the real parent address */
219 move r11, r0
220
221 MCOUNT_RESTORE_REGS
222 jr r11
223
224#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
diff --git a/arch/tile/kernel/pci-dma.c b/arch/tile/kernel/pci-dma.c
index b9fe80ec1089..09b58703ac26 100644
--- a/arch/tile/kernel/pci-dma.c
+++ b/arch/tile/kernel/pci-dma.c
@@ -36,8 +36,9 @@ static void *tile_dma_alloc_coherent(struct device *dev, size_t size,
36 dma_addr_t *dma_handle, gfp_t gfp, 36 dma_addr_t *dma_handle, gfp_t gfp,
37 struct dma_attrs *attrs) 37 struct dma_attrs *attrs)
38{ 38{
39 u64 dma_mask = dev->coherent_dma_mask ?: DMA_BIT_MASK(32); 39 u64 dma_mask = (dev && dev->coherent_dma_mask) ?
40 int node = dev_to_node(dev); 40 dev->coherent_dma_mask : DMA_BIT_MASK(32);
41 int node = dev ? dev_to_node(dev) : 0;
41 int order = get_order(size); 42 int order = get_order(size);
42 struct page *pg; 43 struct page *pg;
43 dma_addr_t addr; 44 dma_addr_t addr;
@@ -256,7 +257,7 @@ static void tile_dma_unmap_page(struct device *dev, dma_addr_t dma_address,
256 BUG_ON(!valid_dma_direction(direction)); 257 BUG_ON(!valid_dma_direction(direction));
257 258
258 __dma_complete_page(pfn_to_page(PFN_DOWN(dma_address)), 259 __dma_complete_page(pfn_to_page(PFN_DOWN(dma_address)),
259 dma_address & PAGE_OFFSET, size, direction); 260 dma_address & (PAGE_SIZE - 1), size, direction);
260} 261}
261 262
262static void tile_dma_sync_single_for_cpu(struct device *dev, 263static void tile_dma_sync_single_for_cpu(struct device *dev,
@@ -357,7 +358,7 @@ static void *tile_pci_dma_alloc_coherent(struct device *dev, size_t size,
357 358
358 addr = page_to_phys(pg); 359 addr = page_to_phys(pg);
359 360
360 *dma_handle = phys_to_dma(dev, addr); 361 *dma_handle = addr + get_dma_offset(dev);
361 362
362 return page_address(pg); 363 return page_address(pg);
363} 364}
@@ -387,7 +388,7 @@ static int tile_pci_dma_map_sg(struct device *dev, struct scatterlist *sglist,
387 sg->dma_address = sg_phys(sg); 388 sg->dma_address = sg_phys(sg);
388 __dma_prep_pa_range(sg->dma_address, sg->length, direction); 389 __dma_prep_pa_range(sg->dma_address, sg->length, direction);
389 390
390 sg->dma_address = phys_to_dma(dev, sg->dma_address); 391 sg->dma_address = sg->dma_address + get_dma_offset(dev);
391#ifdef CONFIG_NEED_SG_DMA_LENGTH 392#ifdef CONFIG_NEED_SG_DMA_LENGTH
392 sg->dma_length = sg->length; 393 sg->dma_length = sg->length;
393#endif 394#endif
@@ -422,7 +423,7 @@ static dma_addr_t tile_pci_dma_map_page(struct device *dev, struct page *page,
422 BUG_ON(offset + size > PAGE_SIZE); 423 BUG_ON(offset + size > PAGE_SIZE);
423 __dma_prep_page(page, offset, size, direction); 424 __dma_prep_page(page, offset, size, direction);
424 425
425 return phys_to_dma(dev, page_to_pa(page) + offset); 426 return page_to_pa(page) + offset + get_dma_offset(dev);
426} 427}
427 428
428static void tile_pci_dma_unmap_page(struct device *dev, dma_addr_t dma_address, 429static void tile_pci_dma_unmap_page(struct device *dev, dma_addr_t dma_address,
@@ -432,10 +433,10 @@ static void tile_pci_dma_unmap_page(struct device *dev, dma_addr_t dma_address,
432{ 433{
433 BUG_ON(!valid_dma_direction(direction)); 434 BUG_ON(!valid_dma_direction(direction));
434 435
435 dma_address = dma_to_phys(dev, dma_address); 436 dma_address -= get_dma_offset(dev);
436 437
437 __dma_complete_page(pfn_to_page(PFN_DOWN(dma_address)), 438 __dma_complete_page(pfn_to_page(PFN_DOWN(dma_address)),
438 dma_address & PAGE_OFFSET, size, direction); 439 dma_address & (PAGE_SIZE - 1), size, direction);
439} 440}
440 441
441static void tile_pci_dma_sync_single_for_cpu(struct device *dev, 442static void tile_pci_dma_sync_single_for_cpu(struct device *dev,
@@ -445,7 +446,7 @@ static void tile_pci_dma_sync_single_for_cpu(struct device *dev,
445{ 446{
446 BUG_ON(!valid_dma_direction(direction)); 447 BUG_ON(!valid_dma_direction(direction));
447 448
448 dma_handle = dma_to_phys(dev, dma_handle); 449 dma_handle -= get_dma_offset(dev);
449 450
450 __dma_complete_pa_range(dma_handle, size, direction); 451 __dma_complete_pa_range(dma_handle, size, direction);
451} 452}
@@ -456,7 +457,7 @@ static void tile_pci_dma_sync_single_for_device(struct device *dev,
456 enum dma_data_direction 457 enum dma_data_direction
457 direction) 458 direction)
458{ 459{
459 dma_handle = dma_to_phys(dev, dma_handle); 460 dma_handle -= get_dma_offset(dev);
460 461
461 __dma_prep_pa_range(dma_handle, size, direction); 462 __dma_prep_pa_range(dma_handle, size, direction);
462} 463}
@@ -558,22 +559,47 @@ static struct dma_map_ops pci_swiotlb_dma_ops = {
558 .mapping_error = swiotlb_dma_mapping_error, 559 .mapping_error = swiotlb_dma_mapping_error,
559}; 560};
560 561
562static struct dma_map_ops pci_hybrid_dma_ops = {
563 .alloc = tile_swiotlb_alloc_coherent,
564 .free = tile_swiotlb_free_coherent,
565 .map_page = tile_pci_dma_map_page,
566 .unmap_page = tile_pci_dma_unmap_page,
567 .map_sg = tile_pci_dma_map_sg,
568 .unmap_sg = tile_pci_dma_unmap_sg,
569 .sync_single_for_cpu = tile_pci_dma_sync_single_for_cpu,
570 .sync_single_for_device = tile_pci_dma_sync_single_for_device,
571 .sync_sg_for_cpu = tile_pci_dma_sync_sg_for_cpu,
572 .sync_sg_for_device = tile_pci_dma_sync_sg_for_device,
573 .mapping_error = tile_pci_dma_mapping_error,
574 .dma_supported = tile_pci_dma_supported
575};
576
561struct dma_map_ops *gx_legacy_pci_dma_map_ops = &pci_swiotlb_dma_ops; 577struct dma_map_ops *gx_legacy_pci_dma_map_ops = &pci_swiotlb_dma_ops;
578struct dma_map_ops *gx_hybrid_pci_dma_map_ops = &pci_hybrid_dma_ops;
562#else 579#else
563struct dma_map_ops *gx_legacy_pci_dma_map_ops; 580struct dma_map_ops *gx_legacy_pci_dma_map_ops;
581struct dma_map_ops *gx_hybrid_pci_dma_map_ops;
564#endif 582#endif
565EXPORT_SYMBOL(gx_legacy_pci_dma_map_ops); 583EXPORT_SYMBOL(gx_legacy_pci_dma_map_ops);
584EXPORT_SYMBOL(gx_hybrid_pci_dma_map_ops);
566 585
567#ifdef CONFIG_ARCH_HAS_DMA_SET_COHERENT_MASK 586#ifdef CONFIG_ARCH_HAS_DMA_SET_COHERENT_MASK
568int dma_set_coherent_mask(struct device *dev, u64 mask) 587int dma_set_coherent_mask(struct device *dev, u64 mask)
569{ 588{
570 struct dma_map_ops *dma_ops = get_dma_ops(dev); 589 struct dma_map_ops *dma_ops = get_dma_ops(dev);
571 590
572 /* Handle legacy PCI devices with limited memory addressability. */ 591 /*
573 if (((dma_ops == gx_pci_dma_map_ops) || 592 * For PCI devices with 64-bit DMA addressing capability, promote
574 (dma_ops == gx_legacy_pci_dma_map_ops)) && 593 * the dma_ops to full capability for both streams and consistent
575 (mask <= DMA_BIT_MASK(32))) { 594 * memory access. For 32-bit capable devices, limit the consistent
576 if (mask > dev->archdata.max_direct_dma_addr) 595 * memory DMA range to max_direct_dma_addr.
596 */
597 if (dma_ops == gx_pci_dma_map_ops ||
598 dma_ops == gx_hybrid_pci_dma_map_ops ||
599 dma_ops == gx_legacy_pci_dma_map_ops) {
600 if (mask == DMA_BIT_MASK(64))
601 set_dma_ops(dev, gx_pci_dma_map_ops);
602 else if (mask > dev->archdata.max_direct_dma_addr)
577 mask = dev->archdata.max_direct_dma_addr; 603 mask = dev->archdata.max_direct_dma_addr;
578 } 604 }
579 605
@@ -584,3 +610,21 @@ int dma_set_coherent_mask(struct device *dev, u64 mask)
584} 610}
585EXPORT_SYMBOL(dma_set_coherent_mask); 611EXPORT_SYMBOL(dma_set_coherent_mask);
586#endif 612#endif
613
614#ifdef ARCH_HAS_DMA_GET_REQUIRED_MASK
615/*
616 * The generic dma_get_required_mask() uses the highest physical address
617 * (max_pfn) to provide the hint to the PCI drivers regarding 32-bit or
618 * 64-bit DMA configuration. Since TILEGx has I/O TLB/MMU, allowing the
619 * DMAs to use the full 64-bit PCI address space and not limited by
620 * the physical memory space, we always let the PCI devices use
621 * 64-bit DMA if they have that capability, by returning the 64-bit
622 * DMA mask here. The device driver has the option to use 32-bit DMA if
623 * the device is not capable of 64-bit DMA.
624 */
625u64 dma_get_required_mask(struct device *dev)
626{
627 return DMA_BIT_MASK(64);
628}
629EXPORT_SYMBOL_GPL(dma_get_required_mask);
630#endif
diff --git a/arch/tile/kernel/pci.c b/arch/tile/kernel/pci.c
index 67237d34c2e2..b7180e6e900d 100644
--- a/arch/tile/kernel/pci.c
+++ b/arch/tile/kernel/pci.c
@@ -20,7 +20,6 @@
20#include <linux/capability.h> 20#include <linux/capability.h>
21#include <linux/sched.h> 21#include <linux/sched.h>
22#include <linux/errno.h> 22#include <linux/errno.h>
23#include <linux/bootmem.h>
24#include <linux/irq.h> 23#include <linux/irq.h>
25#include <linux/io.h> 24#include <linux/io.h>
26#include <linux/uaccess.h> 25#include <linux/uaccess.h>
@@ -52,6 +51,8 @@
52 * 51 *
53 */ 52 */
54 53
54static int pci_probe = 1;
55
55/* 56/*
56 * This flag tells if the platform is TILEmpower that needs 57 * This flag tells if the platform is TILEmpower that needs
57 * special configuration for the PLX switch chip. 58 * special configuration for the PLX switch chip.
@@ -144,6 +145,11 @@ int __init tile_pci_init(void)
144{ 145{
145 int i; 146 int i;
146 147
148 if (!pci_probe) {
149 pr_info("PCI: disabled by boot argument\n");
150 return 0;
151 }
152
147 pr_info("PCI: Searching for controllers...\n"); 153 pr_info("PCI: Searching for controllers...\n");
148 154
149 /* Re-init number of PCIe controllers to support hot-plug feature. */ 155 /* Re-init number of PCIe controllers to support hot-plug feature. */
@@ -192,7 +198,6 @@ int __init tile_pci_init(void)
192 controller->hv_cfg_fd[0] = hv_cfg_fd0; 198 controller->hv_cfg_fd[0] = hv_cfg_fd0;
193 controller->hv_cfg_fd[1] = hv_cfg_fd1; 199 controller->hv_cfg_fd[1] = hv_cfg_fd1;
194 controller->hv_mem_fd = hv_mem_fd; 200 controller->hv_mem_fd = hv_mem_fd;
195 controller->first_busno = 0;
196 controller->last_busno = 0xff; 201 controller->last_busno = 0xff;
197 controller->ops = &tile_cfg_ops; 202 controller->ops = &tile_cfg_ops;
198 203
@@ -283,7 +288,7 @@ int __init pcibios_init(void)
283 * known to require at least 20ms here, but we use a more 288 * known to require at least 20ms here, but we use a more
284 * conservative value. 289 * conservative value.
285 */ 290 */
286 mdelay(250); 291 msleep(250);
287 292
288 /* Scan all of the recorded PCI controllers. */ 293 /* Scan all of the recorded PCI controllers. */
289 for (i = 0; i < TILE_NUM_PCIE; i++) { 294 for (i = 0; i < TILE_NUM_PCIE; i++) {
@@ -304,18 +309,10 @@ int __init pcibios_init(void)
304 309
305 pr_info("PCI: initializing controller #%d\n", i); 310 pr_info("PCI: initializing controller #%d\n", i);
306 311
307 /*
308 * This comes from the generic Linux PCI driver.
309 *
310 * It reads the PCI tree for this bus into the Linux
311 * data structures.
312 *
313 * This is inlined in linux/pci.h and calls into
314 * pci_scan_bus_parented() in probe.c.
315 */
316 pci_add_resource(&resources, &ioport_resource); 312 pci_add_resource(&resources, &ioport_resource);
317 pci_add_resource(&resources, &iomem_resource); 313 pci_add_resource(&resources, &iomem_resource);
318 bus = pci_scan_root_bus(NULL, 0, controller->ops, controller, &resources); 314 bus = pci_scan_root_bus(NULL, 0, controller->ops,
315 controller, &resources);
319 controller->root_bus = bus; 316 controller->root_bus = bus;
320 controller->last_busno = bus->busn_res.end; 317 controller->last_busno = bus->busn_res.end;
321 } 318 }
@@ -388,6 +385,16 @@ void pcibios_set_master(struct pci_dev *dev)
388 /* No special bus mastering setup handling. */ 385 /* No special bus mastering setup handling. */
389} 386}
390 387
388/* Process any "pci=" kernel boot arguments. */
389char *__init pcibios_setup(char *str)
390{
391 if (!strcmp(str, "off")) {
392 pci_probe = 0;
393 return NULL;
394 }
395 return str;
396}
397
391/* 398/*
392 * Enable memory and/or address decoding, as appropriate, for the 399 * Enable memory and/or address decoding, as appropriate, for the
393 * device described by the 'dev' struct. 400 * device described by the 'dev' struct.
diff --git a/arch/tile/kernel/pci_gx.c b/arch/tile/kernel/pci_gx.c
index 6640e7bbeaa2..a97a6452b812 100644
--- a/arch/tile/kernel/pci_gx.c
+++ b/arch/tile/kernel/pci_gx.c
@@ -69,19 +69,32 @@ static int pcie_rc[TILEGX_NUM_TRIO][TILEGX_TRIO_PCIES];
69 * a HW PCIe link-training bug. The exact delay is specified with 69 * a HW PCIe link-training bug. The exact delay is specified with
70 * a kernel boot argument in the form of "pcie_rc_delay=T,P,S", 70 * a kernel boot argument in the form of "pcie_rc_delay=T,P,S",
71 * where T is the TRIO instance number, P is the port number and S is 71 * where T is the TRIO instance number, P is the port number and S is
72 * the delay in seconds. If the delay is not provided, the value 72 * the delay in seconds. If the argument is specified, but the delay is
73 * will be DEFAULT_RC_DELAY. 73 * not provided, the value will be DEFAULT_RC_DELAY.
74 */ 74 */
75static int rc_delay[TILEGX_NUM_TRIO][TILEGX_TRIO_PCIES]; 75static int rc_delay[TILEGX_NUM_TRIO][TILEGX_TRIO_PCIES];
76 76
77/* Default number of seconds that the PCIe RC port probe can be delayed. */ 77/* Default number of seconds that the PCIe RC port probe can be delayed. */
78#define DEFAULT_RC_DELAY 10 78#define DEFAULT_RC_DELAY 10
79 79
80/* Max number of seconds that the PCIe RC port probe can be delayed. */ 80/* The PCI I/O space size in each PCI domain. */
81#define MAX_RC_DELAY 20 81#define IO_SPACE_SIZE 0x10000
82
83/* Provide shorter versions of some very long constant names. */
84#define AUTO_CONFIG_RC \
85 TRIO_PCIE_INTFC_PORT_CONFIG__STRAP_STATE_VAL_AUTO_CONFIG_RC
86#define AUTO_CONFIG_RC_G1 \
87 TRIO_PCIE_INTFC_PORT_CONFIG__STRAP_STATE_VAL_AUTO_CONFIG_RC_G1
88#define AUTO_CONFIG_EP \
89 TRIO_PCIE_INTFC_PORT_CONFIG__STRAP_STATE_VAL_AUTO_CONFIG_ENDPOINT
90#define AUTO_CONFIG_EP_G1 \
91 TRIO_PCIE_INTFC_PORT_CONFIG__STRAP_STATE_VAL_AUTO_CONFIG_ENDPOINT_G1
82 92
83/* Array of the PCIe ports configuration info obtained from the BIB. */ 93/* Array of the PCIe ports configuration info obtained from the BIB. */
84struct pcie_port_property pcie_ports[TILEGX_NUM_TRIO][TILEGX_TRIO_PCIES]; 94struct pcie_trio_ports_property pcie_ports[TILEGX_NUM_TRIO];
95
96/* Number of configured TRIO instances. */
97int num_trio_shims;
85 98
86/* All drivers share the TRIO contexts defined here. */ 99/* All drivers share the TRIO contexts defined here. */
87gxio_trio_context_t trio_contexts[TILEGX_NUM_TRIO]; 100gxio_trio_context_t trio_contexts[TILEGX_NUM_TRIO];
@@ -89,24 +102,21 @@ gxio_trio_context_t trio_contexts[TILEGX_NUM_TRIO];
89/* Pointer to an array of PCIe RC controllers. */ 102/* Pointer to an array of PCIe RC controllers. */
90struct pci_controller pci_controllers[TILEGX_NUM_TRIO * TILEGX_TRIO_PCIES]; 103struct pci_controller pci_controllers[TILEGX_NUM_TRIO * TILEGX_TRIO_PCIES];
91int num_rc_controllers; 104int num_rc_controllers;
92static int num_ep_controllers;
93 105
94static struct pci_ops tile_cfg_ops; 106static struct pci_ops tile_cfg_ops;
95 107
96/* Mask of CPUs that should receive PCIe interrupts. */ 108/* Mask of CPUs that should receive PCIe interrupts. */
97static struct cpumask intr_cpus_map; 109static struct cpumask intr_cpus_map;
98 110
99/* 111/* We don't need to worry about the alignment of resources. */
100 * We don't need to worry about the alignment of resources.
101 */
102resource_size_t pcibios_align_resource(void *data, const struct resource *res, 112resource_size_t pcibios_align_resource(void *data, const struct resource *res,
103 resource_size_t size, resource_size_t align) 113 resource_size_t size,
114 resource_size_t align)
104{ 115{
105 return res->start; 116 return res->start;
106} 117}
107EXPORT_SYMBOL(pcibios_align_resource); 118EXPORT_SYMBOL(pcibios_align_resource);
108 119
109
110/* 120/*
111 * Pick a CPU to receive and handle the PCIe interrupts, based on the IRQ #. 121 * Pick a CPU to receive and handle the PCIe interrupts, based on the IRQ #.
112 * For now, we simply send interrupts to non-dataplane CPUs. 122 * For now, we simply send interrupts to non-dataplane CPUs.
@@ -134,24 +144,19 @@ static int tile_irq_cpu(int irq)
134 return cpu; 144 return cpu;
135} 145}
136 146
137/* 147/* Open a file descriptor to the TRIO shim. */
138 * Open a file descriptor to the TRIO shim.
139 */
140static int tile_pcie_open(int trio_index) 148static int tile_pcie_open(int trio_index)
141{ 149{
142 gxio_trio_context_t *context = &trio_contexts[trio_index]; 150 gxio_trio_context_t *context = &trio_contexts[trio_index];
143 int ret; 151 int ret;
152 int mac;
144 153
145 /* 154 /* This opens a file descriptor to the TRIO shim. */
146 * This opens a file descriptor to the TRIO shim.
147 */
148 ret = gxio_trio_init(context, trio_index); 155 ret = gxio_trio_init(context, trio_index);
149 if (ret < 0) 156 if (ret < 0)
150 return ret; 157 goto gxio_trio_init_failure;
151 158
152 /* 159 /* Allocate an ASID for the kernel. */
153 * Allocate an ASID for the kernel.
154 */
155 ret = gxio_trio_alloc_asids(context, 1, 0, 0); 160 ret = gxio_trio_alloc_asids(context, 1, 0, 0);
156 if (ret < 0) { 161 if (ret < 0) {
157 pr_err("PCI: ASID alloc failure on TRIO %d, give up\n", 162 pr_err("PCI: ASID alloc failure on TRIO %d, give up\n",
@@ -189,31 +194,97 @@ static int tile_pcie_open(int trio_index)
189 } 194 }
190#endif 195#endif
191 196
197 /* Get the properties of the PCIe ports on this TRIO instance. */
198 ret = gxio_trio_get_port_property(context, &pcie_ports[trio_index]);
199 if (ret < 0) {
200 pr_err("PCI: PCIE_GET_PORT_PROPERTY failure, error %d,"
201 " on TRIO %d\n", ret, trio_index);
202 goto get_port_property_failure;
203 }
204
205 context->mmio_base_mac =
206 iorpc_ioremap(context->fd, 0, HV_TRIO_CONFIG_IOREMAP_SIZE);
207 if (context->mmio_base_mac == NULL) {
208 pr_err("PCI: TRIO config space mapping failure, error %d,"
209 " on TRIO %d\n", ret, trio_index);
210 ret = -ENOMEM;
211
212 goto trio_mmio_mapping_failure;
213 }
214
215 /* Check the port strap state which will override the BIB setting. */
216 for (mac = 0; mac < TILEGX_TRIO_PCIES; mac++) {
217 TRIO_PCIE_INTFC_PORT_CONFIG_t port_config;
218 unsigned int reg_offset;
219
220 /* Ignore ports that are not specified in the BIB. */
221 if (!pcie_ports[trio_index].ports[mac].allow_rc &&
222 !pcie_ports[trio_index].ports[mac].allow_ep)
223 continue;
224
225 reg_offset =
226 (TRIO_PCIE_INTFC_PORT_CONFIG <<
227 TRIO_CFG_REGION_ADDR__REG_SHIFT) |
228 (TRIO_CFG_REGION_ADDR__INTFC_VAL_MAC_INTERFACE <<
229 TRIO_CFG_REGION_ADDR__INTFC_SHIFT) |
230 (mac << TRIO_CFG_REGION_ADDR__MAC_SEL_SHIFT);
231
232 port_config.word =
233 __gxio_mmio_read(context->mmio_base_mac + reg_offset);
234
235 if (port_config.strap_state != AUTO_CONFIG_RC &&
236 port_config.strap_state != AUTO_CONFIG_RC_G1) {
237 /*
238 * If this is really intended to be an EP port, record
239 * it so that the endpoint driver will know about it.
240 */
241 if (port_config.strap_state == AUTO_CONFIG_EP ||
242 port_config.strap_state == AUTO_CONFIG_EP_G1)
243 pcie_ports[trio_index].ports[mac].allow_ep = 1;
244 }
245 }
246
192 return ret; 247 return ret;
193 248
249trio_mmio_mapping_failure:
250get_port_property_failure:
194asid_alloc_failure: 251asid_alloc_failure:
195#ifdef USE_SHARED_PCIE_CONFIG_REGION 252#ifdef USE_SHARED_PCIE_CONFIG_REGION
196pio_alloc_failure: 253pio_alloc_failure:
197#endif 254#endif
198 hv_dev_close(context->fd); 255 hv_dev_close(context->fd);
256gxio_trio_init_failure:
257 context->fd = -1;
199 258
200 return ret; 259 return ret;
201} 260}
202 261
203static void 262static int __init tile_trio_init(void)
204tilegx_legacy_irq_ack(struct irq_data *d) 263{
264 int i;
265
266 /* We loop over all the TRIO shims. */
267 for (i = 0; i < TILEGX_NUM_TRIO; i++) {
268 if (tile_pcie_open(i) < 0)
269 continue;
270 num_trio_shims++;
271 }
272
273 return 0;
274}
275postcore_initcall(tile_trio_init);
276
277static void tilegx_legacy_irq_ack(struct irq_data *d)
205{ 278{
206 __insn_mtspr(SPR_IPI_EVENT_RESET_K, 1UL << d->irq); 279 __insn_mtspr(SPR_IPI_EVENT_RESET_K, 1UL << d->irq);
207} 280}
208 281
209static void 282static void tilegx_legacy_irq_mask(struct irq_data *d)
210tilegx_legacy_irq_mask(struct irq_data *d)
211{ 283{
212 __insn_mtspr(SPR_IPI_MASK_SET_K, 1UL << d->irq); 284 __insn_mtspr(SPR_IPI_MASK_SET_K, 1UL << d->irq);
213} 285}
214 286
215static void 287static void tilegx_legacy_irq_unmask(struct irq_data *d)
216tilegx_legacy_irq_unmask(struct irq_data *d)
217{ 288{
218 __insn_mtspr(SPR_IPI_MASK_RESET_K, 1UL << d->irq); 289 __insn_mtspr(SPR_IPI_MASK_RESET_K, 1UL << d->irq);
219} 290}
@@ -234,8 +305,7 @@ static struct irq_chip tilegx_legacy_irq_chip = {
234 * to Linux which just calls handle_level_irq() after clearing the 305 * to Linux which just calls handle_level_irq() after clearing the
235 * MAC INTx Assert status bit associated with this interrupt. 306 * MAC INTx Assert status bit associated with this interrupt.
236 */ 307 */
237static void 308static void trio_handle_level_irq(unsigned int irq, struct irq_desc *desc)
238trio_handle_level_irq(unsigned int irq, struct irq_desc *desc)
239{ 309{
240 struct pci_controller *controller = irq_desc_get_handler_data(desc); 310 struct pci_controller *controller = irq_desc_get_handler_data(desc);
241 gxio_trio_context_t *trio_context = controller->trio; 311 gxio_trio_context_t *trio_context = controller->trio;
@@ -301,9 +371,7 @@ static int tile_init_irqs(struct pci_controller *controller)
301 goto free_irqs; 371 goto free_irqs;
302 } 372 }
303 373
304 /* 374 /* Register the IRQ handler with the kernel. */
305 * Register the IRQ handler with the kernel.
306 */
307 irq_set_chip_and_handler(irq, &tilegx_legacy_irq_chip, 375 irq_set_chip_and_handler(irq, &tilegx_legacy_irq_chip,
308 trio_handle_level_irq); 376 trio_handle_level_irq);
309 irq_set_chip_data(irq, (void *)(uint64_t)i); 377 irq_set_chip_data(irq, (void *)(uint64_t)i);
@@ -320,14 +388,39 @@ free_irqs:
320} 388}
321 389
322/* 390/*
391 * Return 1 if the port is strapped to operate in RC mode.
392 */
393static int
394strapped_for_rc(gxio_trio_context_t *trio_context, int mac)
395{
396 TRIO_PCIE_INTFC_PORT_CONFIG_t port_config;
397 unsigned int reg_offset;
398
399 /* Check the port configuration. */
400 reg_offset =
401 (TRIO_PCIE_INTFC_PORT_CONFIG <<
402 TRIO_CFG_REGION_ADDR__REG_SHIFT) |
403 (TRIO_CFG_REGION_ADDR__INTFC_VAL_MAC_INTERFACE <<
404 TRIO_CFG_REGION_ADDR__INTFC_SHIFT) |
405 (mac << TRIO_CFG_REGION_ADDR__MAC_SEL_SHIFT);
406 port_config.word =
407 __gxio_mmio_read(trio_context->mmio_base_mac + reg_offset);
408
409 if (port_config.strap_state == AUTO_CONFIG_RC ||
410 port_config.strap_state == AUTO_CONFIG_RC_G1)
411 return 1;
412 else
413 return 0;
414}
415
416/*
323 * Find valid controllers and fill in pci_controller structs for each 417 * Find valid controllers and fill in pci_controller structs for each
324 * of them. 418 * of them.
325 * 419 *
326 * Returns the number of controllers discovered. 420 * Return the number of controllers discovered.
327 */ 421 */
328int __init tile_pci_init(void) 422int __init tile_pci_init(void)
329{ 423{
330 int num_trio_shims = 0;
331 int ctl_index = 0; 424 int ctl_index = 0;
332 int i, j; 425 int i, j;
333 426
@@ -338,64 +431,62 @@ int __init tile_pci_init(void)
338 431
339 pr_info("PCI: Searching for controllers...\n"); 432 pr_info("PCI: Searching for controllers...\n");
340 433
341 /*
342 * We loop over all the TRIO shims.
343 */
344 for (i = 0; i < TILEGX_NUM_TRIO; i++) {
345 int ret;
346
347 ret = tile_pcie_open(i);
348 if (ret < 0)
349 continue;
350
351 num_trio_shims++;
352 }
353
354 if (num_trio_shims == 0 || sim_is_simulator()) 434 if (num_trio_shims == 0 || sim_is_simulator())
355 return 0; 435 return 0;
356 436
357 /* 437 /*
358 * Now determine which PCIe ports are configured to operate in RC mode. 438 * Now determine which PCIe ports are configured to operate in RC
359 * We look at the Board Information Block first and then see if there 439 * mode. There is a differece in the port configuration capability
360 * are any overriding configuration by the HW strapping pin. 440 * between the Gx36 and Gx72 devices.
441 *
442 * The Gx36 has configuration capability for each of the 3 PCIe
443 * interfaces (disable, auto endpoint, auto RC, etc.).
444 * On the Gx72, you can only select one of the 3 PCIe interfaces per
445 * TRIO to train automatically. Further, the allowable training modes
446 * are reduced to four options (auto endpoint, auto RC, stream x1,
447 * stream x4).
448 *
449 * For Gx36 ports, it must be allowed to be in RC mode by the
450 * Board Information Block, and the hardware strapping pins must be
451 * set to RC mode.
452 *
453 * For Gx72 ports, the port will operate in RC mode if either of the
454 * following is true:
455 * 1. It is allowed to be in RC mode by the Board Information Block,
456 * and the BIB doesn't allow the EP mode.
457 * 2. It is allowed to be in either the RC or the EP mode by the BIB,
458 * and the hardware strapping pin is set to RC mode.
361 */ 459 */
362 for (i = 0; i < TILEGX_NUM_TRIO; i++) { 460 for (i = 0; i < TILEGX_NUM_TRIO; i++) {
363 gxio_trio_context_t *context = &trio_contexts[i]; 461 gxio_trio_context_t *context = &trio_contexts[i];
364 int ret;
365 462
366 if (context->fd < 0) 463 if (context->fd < 0)
367 continue; 464 continue;
368 465
369 ret = hv_dev_pread(context->fd, 0,
370 (HV_VirtAddr)&pcie_ports[i][0],
371 sizeof(struct pcie_port_property) * TILEGX_TRIO_PCIES,
372 GXIO_TRIO_OP_GET_PORT_PROPERTY);
373 if (ret < 0) {
374 pr_err("PCI: PCIE_GET_PORT_PROPERTY failure, error %d,"
375 " on TRIO %d\n", ret, i);
376 continue;
377 }
378
379 for (j = 0; j < TILEGX_TRIO_PCIES; j++) { 466 for (j = 0; j < TILEGX_TRIO_PCIES; j++) {
380 if (pcie_ports[i][j].allow_rc) { 467 int is_rc = 0;
468
469 if (pcie_ports[i].is_gx72 &&
470 pcie_ports[i].ports[j].allow_rc) {
471 if (!pcie_ports[i].ports[j].allow_ep ||
472 strapped_for_rc(context, j))
473 is_rc = 1;
474 } else if (pcie_ports[i].ports[j].allow_rc &&
475 strapped_for_rc(context, j)) {
476 is_rc = 1;
477 }
478 if (is_rc) {
381 pcie_rc[i][j] = 1; 479 pcie_rc[i][j] = 1;
382 num_rc_controllers++; 480 num_rc_controllers++;
383 } 481 }
384 else if (pcie_ports[i][j].allow_ep) {
385 num_ep_controllers++;
386 }
387 } 482 }
388 } 483 }
389 484
390 /* 485 /* Return if no PCIe ports are configured to operate in RC mode. */
391 * Return if no PCIe ports are configured to operate in RC mode.
392 */
393 if (num_rc_controllers == 0) 486 if (num_rc_controllers == 0)
394 return 0; 487 return 0;
395 488
396 /* 489 /* Set the TRIO pointer and MAC index for each PCIe RC port. */
397 * Set the TRIO pointer and MAC index for each PCIe RC port.
398 */
399 for (i = 0; i < TILEGX_NUM_TRIO; i++) { 490 for (i = 0; i < TILEGX_NUM_TRIO; i++) {
400 for (j = 0; j < TILEGX_TRIO_PCIES; j++) { 491 for (j = 0; j < TILEGX_TRIO_PCIES; j++) {
401 if (pcie_rc[i][j]) { 492 if (pcie_rc[i][j]) {
@@ -411,26 +502,32 @@ int __init tile_pci_init(void)
411 } 502 }
412 503
413out: 504out:
414 /* 505 /* Configure each PCIe RC port. */
415 * Configure each PCIe RC port.
416 */
417 for (i = 0; i < num_rc_controllers; i++) { 506 for (i = 0; i < num_rc_controllers; i++) {
418 /*
419 * Configure the PCIe MAC to run in RC mode.
420 */
421 507
508 /* Configure the PCIe MAC to run in RC mode. */
422 struct pci_controller *controller = &pci_controllers[i]; 509 struct pci_controller *controller = &pci_controllers[i];
423 510
424 controller->index = i; 511 controller->index = i;
425 controller->ops = &tile_cfg_ops; 512 controller->ops = &tile_cfg_ops;
426 513
514 controller->io_space.start = PCIBIOS_MIN_IO +
515 (i * IO_SPACE_SIZE);
516 controller->io_space.end = controller->io_space.start +
517 IO_SPACE_SIZE - 1;
518 BUG_ON(controller->io_space.end > IO_SPACE_LIMIT);
519 controller->io_space.flags = IORESOURCE_IO;
520 snprintf(controller->io_space_name,
521 sizeof(controller->io_space_name),
522 "PCI I/O domain %d", i);
523 controller->io_space.name = controller->io_space_name;
524
427 /* 525 /*
428 * The PCI memory resource is located above the PA space. 526 * The PCI memory resource is located above the PA space.
429 * For every host bridge, the BAR window or the MMIO aperture 527 * For every host bridge, the BAR window or the MMIO aperture
430 * is in range [3GB, 4GB - 1] of a 4GB space beyond the 528 * is in range [3GB, 4GB - 1] of a 4GB space beyond the
431 * PA space. 529 * PA space.
432 */ 530 */
433
434 controller->mem_offset = TILE_PCI_MEM_START + 531 controller->mem_offset = TILE_PCI_MEM_START +
435 (i * TILE_PCI_BAR_WINDOW_TOP); 532 (i * TILE_PCI_BAR_WINDOW_TOP);
436 controller->mem_space.start = controller->mem_offset + 533 controller->mem_space.start = controller->mem_offset +
@@ -458,7 +555,6 @@ static int tile_map_irq(const struct pci_dev *dev, u8 device, u8 pin)
458 return controller->irq_intx_table[pin - 1]; 555 return controller->irq_intx_table[pin - 1];
459} 556}
460 557
461
462static void fixup_read_and_payload_sizes(struct pci_controller *controller) 558static void fixup_read_and_payload_sizes(struct pci_controller *controller)
463{ 559{
464 gxio_trio_context_t *trio_context = controller->trio; 560 gxio_trio_context_t *trio_context = controller->trio;
@@ -472,9 +568,7 @@ static void fixup_read_and_payload_sizes(struct pci_controller *controller)
472 568
473 mac = controller->mac; 569 mac = controller->mac;
474 570
475 /* 571 /* Set our max read request size to be 4KB. */
476 * Set our max read request size to be 4KB.
477 */
478 reg_offset = 572 reg_offset =
479 (TRIO_PCIE_RC_DEVICE_CONTROL << 573 (TRIO_PCIE_RC_DEVICE_CONTROL <<
480 TRIO_CFG_REGION_ADDR__REG_SHIFT) | 574 TRIO_CFG_REGION_ADDR__REG_SHIFT) |
@@ -483,10 +577,10 @@ static void fixup_read_and_payload_sizes(struct pci_controller *controller)
483 (mac << TRIO_CFG_REGION_ADDR__MAC_SEL_SHIFT); 577 (mac << TRIO_CFG_REGION_ADDR__MAC_SEL_SHIFT);
484 578
485 dev_control.word = __gxio_mmio_read32(trio_context->mmio_base_mac + 579 dev_control.word = __gxio_mmio_read32(trio_context->mmio_base_mac +
486 reg_offset); 580 reg_offset);
487 dev_control.max_read_req_sz = 5; 581 dev_control.max_read_req_sz = 5;
488 __gxio_mmio_write32(trio_context->mmio_base_mac + reg_offset, 582 __gxio_mmio_write32(trio_context->mmio_base_mac + reg_offset,
489 dev_control.word); 583 dev_control.word);
490 584
491 /* 585 /*
492 * Set the max payload size supported by this Gx PCIe MAC. 586 * Set the max payload size supported by this Gx PCIe MAC.
@@ -502,10 +596,10 @@ static void fixup_read_and_payload_sizes(struct pci_controller *controller)
502 (mac << TRIO_CFG_REGION_ADDR__MAC_SEL_SHIFT); 596 (mac << TRIO_CFG_REGION_ADDR__MAC_SEL_SHIFT);
503 597
504 rc_dev_cap.word = __gxio_mmio_read32(trio_context->mmio_base_mac + 598 rc_dev_cap.word = __gxio_mmio_read32(trio_context->mmio_base_mac +
505 reg_offset); 599 reg_offset);
506 rc_dev_cap.mps_sup = 1; 600 rc_dev_cap.mps_sup = 1;
507 __gxio_mmio_write32(trio_context->mmio_base_mac + reg_offset, 601 __gxio_mmio_write32(trio_context->mmio_base_mac + reg_offset,
508 rc_dev_cap.word); 602 rc_dev_cap.word);
509 603
510 /* Configure PCI Express MPS setting. */ 604 /* Configure PCI Express MPS setting. */
511 list_for_each_entry(child, &root_bus->children, node) 605 list_for_each_entry(child, &root_bus->children, node)
@@ -528,7 +622,7 @@ static void fixup_read_and_payload_sizes(struct pci_controller *controller)
528 dev_control.max_payload_size, 622 dev_control.max_payload_size,
529 dev_control.max_read_req_sz, 623 dev_control.max_read_req_sz,
530 mac); 624 mac);
531 if (err < 0) { 625 if (err < 0) {
532 pr_err("PCI: PCIE_CONFIGURE_MAC_MPS_MRS failure, " 626 pr_err("PCI: PCIE_CONFIGURE_MAC_MPS_MRS failure, "
533 "MAC %d on TRIO %d\n", 627 "MAC %d on TRIO %d\n",
534 mac, controller->trio_index); 628 mac, controller->trio_index);
@@ -565,21 +659,14 @@ static int setup_pcie_rc_delay(char *str)
565 if (!isdigit(*str)) 659 if (!isdigit(*str))
566 return -EINVAL; 660 return -EINVAL;
567 delay = simple_strtoul(str, (char **)&str, 10); 661 delay = simple_strtoul(str, (char **)&str, 10);
568 if (delay > MAX_RC_DELAY)
569 return -EINVAL;
570 } 662 }
571 663
572 rc_delay[trio_index][mac] = delay ? : DEFAULT_RC_DELAY; 664 rc_delay[trio_index][mac] = delay ? : DEFAULT_RC_DELAY;
573 pr_info("Delaying PCIe RC link training for %u sec"
574 " on MAC %lu on TRIO %lu\n", rc_delay[trio_index][mac],
575 mac, trio_index);
576 return 0; 665 return 0;
577} 666}
578early_param("pcie_rc_delay", setup_pcie_rc_delay); 667early_param("pcie_rc_delay", setup_pcie_rc_delay);
579 668
580/* 669/* PCI initialization entry point, called by subsys_initcall. */
581 * PCI initialization entry point, called by subsys_initcall.
582 */
583int __init pcibios_init(void) 670int __init pcibios_init(void)
584{ 671{
585 resource_size_t offset; 672 resource_size_t offset;
@@ -589,35 +676,10 @@ int __init pcibios_init(void)
589 676
590 tile_pci_init(); 677 tile_pci_init();
591 678
592 if (num_rc_controllers == 0 && num_ep_controllers == 0) 679 if (num_rc_controllers == 0)
593 return 0; 680 return 0;
594 681
595 /* 682 /*
596 * We loop over all the TRIO shims and set up the MMIO mappings.
597 */
598 for (i = 0; i < TILEGX_NUM_TRIO; i++) {
599 gxio_trio_context_t *context = &trio_contexts[i];
600
601 if (context->fd < 0)
602 continue;
603
604 /*
605 * Map in the MMIO space for the MAC.
606 */
607 offset = 0;
608 context->mmio_base_mac =
609 iorpc_ioremap(context->fd, offset,
610 HV_TRIO_CONFIG_IOREMAP_SIZE);
611 if (context->mmio_base_mac == NULL) {
612 pr_err("PCI: MAC map failure on TRIO %d\n", i);
613
614 hv_dev_close(context->fd);
615 context->fd = -1;
616 continue;
617 }
618 }
619
620 /*
621 * Delay a bit in case devices aren't ready. Some devices are 683 * Delay a bit in case devices aren't ready. Some devices are
622 * known to require at least 20ms here, but we use a more 684 * known to require at least 20ms here, but we use a more
623 * conservative value. 685 * conservative value.
@@ -628,7 +690,6 @@ int __init pcibios_init(void)
628 for (next_busno = 0, i = 0; i < num_rc_controllers; i++) { 690 for (next_busno = 0, i = 0; i < num_rc_controllers; i++) {
629 struct pci_controller *controller = &pci_controllers[i]; 691 struct pci_controller *controller = &pci_controllers[i];
630 gxio_trio_context_t *trio_context = controller->trio; 692 gxio_trio_context_t *trio_context = controller->trio;
631 TRIO_PCIE_INTFC_PORT_CONFIG_t port_config;
632 TRIO_PCIE_INTFC_PORT_STATUS_t port_status; 693 TRIO_PCIE_INTFC_PORT_STATUS_t port_status;
633 TRIO_PCIE_INTFC_TX_FIFO_CTL_t tx_fifo_ctl; 694 TRIO_PCIE_INTFC_TX_FIFO_CTL_t tx_fifo_ctl;
634 struct pci_bus *bus; 695 struct pci_bus *bus;
@@ -645,75 +706,64 @@ int __init pcibios_init(void)
645 mac = controller->mac; 706 mac = controller->mac;
646 707
647 /* 708 /*
648 * Check the port strap state which will override the BIB 709 * Check for PCIe link-up status to decide if we need
649 * setting. 710 * to force the link to come up.
650 */ 711 */
651
652 reg_offset = 712 reg_offset =
653 (TRIO_PCIE_INTFC_PORT_CONFIG << 713 (TRIO_PCIE_INTFC_PORT_STATUS <<
654 TRIO_CFG_REGION_ADDR__REG_SHIFT) | 714 TRIO_CFG_REGION_ADDR__REG_SHIFT) |
655 (TRIO_CFG_REGION_ADDR__INTFC_VAL_MAC_INTERFACE << 715 (TRIO_CFG_REGION_ADDR__INTFC_VAL_MAC_INTERFACE <<
656 TRIO_CFG_REGION_ADDR__INTFC_SHIFT ) | 716 TRIO_CFG_REGION_ADDR__INTFC_SHIFT) |
657 (mac << TRIO_CFG_REGION_ADDR__MAC_SEL_SHIFT); 717 (mac << TRIO_CFG_REGION_ADDR__MAC_SEL_SHIFT);
658 718
659 port_config.word = 719 port_status.word =
660 __gxio_mmio_read(trio_context->mmio_base_mac + 720 __gxio_mmio_read(trio_context->mmio_base_mac +
661 reg_offset); 721 reg_offset);
662 722 if (!port_status.dl_up) {
663 if ((port_config.strap_state != 723 if (rc_delay[trio_index][mac]) {
664 TRIO_PCIE_INTFC_PORT_CONFIG__STRAP_STATE_VAL_AUTO_CONFIG_RC) && 724 pr_info("Delaying PCIe RC TRIO init %d sec"
665 (port_config.strap_state != 725 " on MAC %d on TRIO %d\n",
666 TRIO_PCIE_INTFC_PORT_CONFIG__STRAP_STATE_VAL_AUTO_CONFIG_RC_G1)) { 726 rc_delay[trio_index][mac], mac,
667 /* 727 trio_index);
668 * If this is really intended to be an EP port, 728 msleep(rc_delay[trio_index][mac] * 1000);
669 * record it so that the endpoint driver will know about it. 729 }
670 */ 730 ret = gxio_trio_force_rc_link_up(trio_context, mac);
671 if (port_config.strap_state == 731 if (ret < 0)
672 TRIO_PCIE_INTFC_PORT_CONFIG__STRAP_STATE_VAL_AUTO_CONFIG_ENDPOINT || 732 pr_err("PCI: PCIE_FORCE_LINK_UP failure, "
673 port_config.strap_state == 733 "MAC %d on TRIO %d\n", mac, trio_index);
674 TRIO_PCIE_INTFC_PORT_CONFIG__STRAP_STATE_VAL_AUTO_CONFIG_ENDPOINT_G1)
675 pcie_ports[trio_index][mac].allow_ep = 1;
676
677 continue;
678 } 734 }
679 735
680 /*
681 * Delay the RC link training if needed.
682 */
683 if (rc_delay[trio_index][mac])
684 msleep(rc_delay[trio_index][mac] * 1000);
685
686 ret = gxio_trio_force_rc_link_up(trio_context, mac);
687 if (ret < 0)
688 pr_err("PCI: PCIE_FORCE_LINK_UP failure, "
689 "MAC %d on TRIO %d\n", mac, trio_index);
690
691 pr_info("PCI: Found PCI controller #%d on TRIO %d MAC %d\n", i, 736 pr_info("PCI: Found PCI controller #%d on TRIO %d MAC %d\n", i,
692 trio_index, controller->mac); 737 trio_index, controller->mac);
693 738
694 /* 739 /* Delay the bus probe if needed. */
695 * Wait a bit here because some EP devices take longer 740 if (rc_delay[trio_index][mac]) {
696 * to come up. 741 pr_info("Delaying PCIe RC bus enumerating %d sec"
697 */ 742 " on MAC %d on TRIO %d\n",
698 msleep(1000); 743 rc_delay[trio_index][mac], mac,
699 744 trio_index);
700 /* 745 msleep(rc_delay[trio_index][mac] * 1000);
701 * Check for PCIe link-up status. 746 } else {
702 */ 747 /*
703 748 * Wait a bit here because some EP devices
704 reg_offset = 749 * take longer to come up.
705 (TRIO_PCIE_INTFC_PORT_STATUS << 750 */
706 TRIO_CFG_REGION_ADDR__REG_SHIFT) | 751 msleep(1000);
707 (TRIO_CFG_REGION_ADDR__INTFC_VAL_MAC_INTERFACE << 752 }
708 TRIO_CFG_REGION_ADDR__INTFC_SHIFT ) |
709 (mac << TRIO_CFG_REGION_ADDR__MAC_SEL_SHIFT);
710 753
754 /* Check for PCIe link-up status again. */
711 port_status.word = 755 port_status.word =
712 __gxio_mmio_read(trio_context->mmio_base_mac + 756 __gxio_mmio_read(trio_context->mmio_base_mac +
713 reg_offset); 757 reg_offset);
714 if (!port_status.dl_up) { 758 if (!port_status.dl_up) {
715 pr_err("PCI: link is down, MAC %d on TRIO %d\n", 759 if (pcie_ports[trio_index].ports[mac].removable) {
716 mac, trio_index); 760 pr_info("PCI: link is down, MAC %d on TRIO %d\n",
761 mac, trio_index);
762 pr_info("This is expected if no PCIe card"
763 " is connected to this link\n");
764 } else
765 pr_err("PCI: link is down, MAC %d on TRIO %d\n",
766 mac, trio_index);
717 continue; 767 continue;
718 } 768 }
719 769
@@ -739,7 +789,6 @@ int __init pcibios_init(void)
739 * Change the device ID so that Linux bus crawl doesn't confuse 789 * Change the device ID so that Linux bus crawl doesn't confuse
740 * the internal bridge with any Tilera endpoints. 790 * the internal bridge with any Tilera endpoints.
741 */ 791 */
742
743 reg_offset = 792 reg_offset =
744 (TRIO_PCIE_RC_DEVICE_ID_VEN_ID << 793 (TRIO_PCIE_RC_DEVICE_ID_VEN_ID <<
745 TRIO_CFG_REGION_ADDR__REG_SHIFT) | 794 TRIO_CFG_REGION_ADDR__REG_SHIFT) |
@@ -752,10 +801,7 @@ int __init pcibios_init(void)
752 TRIO_PCIE_RC_DEVICE_ID_VEN_ID__DEV_ID_SHIFT) | 801 TRIO_PCIE_RC_DEVICE_ID_VEN_ID__DEV_ID_SHIFT) |
753 TILERA_VENDOR_ID); 802 TILERA_VENDOR_ID);
754 803
755 /* 804 /* Set the internal P2P bridge class code. */
756 * Set the internal P2P bridge class code.
757 */
758
759 reg_offset = 805 reg_offset =
760 (TRIO_PCIE_RC_REVISION_ID << 806 (TRIO_PCIE_RC_REVISION_ID <<
761 TRIO_CFG_REGION_ADDR__REG_SHIFT) | 807 TRIO_CFG_REGION_ADDR__REG_SHIFT) |
@@ -766,26 +812,22 @@ int __init pcibios_init(void)
766 class_code_revision = 812 class_code_revision =
767 __gxio_mmio_read32(trio_context->mmio_base_mac + 813 __gxio_mmio_read32(trio_context->mmio_base_mac +
768 reg_offset); 814 reg_offset);
769 class_code_revision = (class_code_revision & 0xff ) | 815 class_code_revision = (class_code_revision & 0xff) |
770 (PCI_CLASS_BRIDGE_PCI << 16); 816 (PCI_CLASS_BRIDGE_PCI << 16);
771 817
772 __gxio_mmio_write32(trio_context->mmio_base_mac + 818 __gxio_mmio_write32(trio_context->mmio_base_mac +
773 reg_offset, class_code_revision); 819 reg_offset, class_code_revision);
774 820
775#ifdef USE_SHARED_PCIE_CONFIG_REGION 821#ifdef USE_SHARED_PCIE_CONFIG_REGION
776 822
777 /* 823 /* Map in the MMIO space for the PIO region. */
778 * Map in the MMIO space for the PIO region.
779 */
780 offset = HV_TRIO_PIO_OFFSET(trio_context->pio_cfg_index) | 824 offset = HV_TRIO_PIO_OFFSET(trio_context->pio_cfg_index) |
781 (((unsigned long long)mac) << 825 (((unsigned long long)mac) <<
782 TRIO_TILE_PIO_REGION_SETUP_CFG_ADDR__MAC_SHIFT); 826 TRIO_TILE_PIO_REGION_SETUP_CFG_ADDR__MAC_SHIFT);
783 827
784#else 828#else
785 829
786 /* 830 /* Alloc a PIO region for PCI config access per MAC. */
787 * Alloc a PIO region for PCI config access per MAC.
788 */
789 ret = gxio_trio_alloc_pio_regions(trio_context, 1, 0, 0); 831 ret = gxio_trio_alloc_pio_regions(trio_context, 1, 0, 0);
790 if (ret < 0) { 832 if (ret < 0) {
791 pr_err("PCI: PCI CFG PIO alloc failure for mac %d " 833 pr_err("PCI: PCI CFG PIO alloc failure for mac %d "
@@ -796,9 +838,7 @@ int __init pcibios_init(void)
796 838
797 trio_context->pio_cfg_index[mac] = ret; 839 trio_context->pio_cfg_index[mac] = ret;
798 840
799 /* 841 /* For PIO CFG, the bus_address_hi parameter is 0. */
800 * For PIO CFG, the bus_address_hi parameter is 0.
801 */
802 ret = gxio_trio_init_pio_region_aux(trio_context, 842 ret = gxio_trio_init_pio_region_aux(trio_context,
803 trio_context->pio_cfg_index[mac], 843 trio_context->pio_cfg_index[mac],
804 mac, 0, HV_TRIO_PIO_FLAG_CONFIG_SPACE); 844 mac, 0, HV_TRIO_PIO_FLAG_CONFIG_SPACE);
@@ -815,9 +855,15 @@ int __init pcibios_init(void)
815 855
816#endif 856#endif
817 857
858 /*
859 * To save VMALLOC space, we take advantage of the fact that
860 * bit 29 in the PIO CFG address format is reserved 0. With
861 * TRIO_TILE_PIO_REGION_SETUP_CFG_ADDR__MAC_SHIFT being 30,
862 * this cuts VMALLOC space usage from 1GB to 512MB per mac.
863 */
818 trio_context->mmio_base_pio_cfg[mac] = 864 trio_context->mmio_base_pio_cfg[mac] =
819 iorpc_ioremap(trio_context->fd, offset, 865 iorpc_ioremap(trio_context->fd, offset, (1UL <<
820 (1 << TRIO_TILE_PIO_REGION_SETUP_CFG_ADDR__MAC_SHIFT)); 866 (TRIO_TILE_PIO_REGION_SETUP_CFG_ADDR__MAC_SHIFT - 1)));
821 if (trio_context->mmio_base_pio_cfg[mac] == NULL) { 867 if (trio_context->mmio_base_pio_cfg[mac] == NULL) {
822 pr_err("PCI: PIO map failure for mac %d on TRIO %d\n", 868 pr_err("PCI: PIO map failure for mac %d on TRIO %d\n",
823 mac, trio_index); 869 mac, trio_index);
@@ -825,9 +871,7 @@ int __init pcibios_init(void)
825 continue; 871 continue;
826 } 872 }
827 873
828 /* 874 /* Initialize the PCIe interrupts. */
829 * Initialize the PCIe interrupts.
830 */
831 if (tile_init_irqs(controller)) { 875 if (tile_init_irqs(controller)) {
832 pr_err("PCI: IRQs init failure for mac %d on TRIO %d\n", 876 pr_err("PCI: IRQs init failure for mac %d on TRIO %d\n",
833 mac, trio_index); 877 mac, trio_index);
@@ -838,17 +882,16 @@ int __init pcibios_init(void)
838 /* 882 /*
839 * The PCI memory resource is located above the PA space. 883 * The PCI memory resource is located above the PA space.
840 * The memory range for the PCI root bus should not overlap 884 * The memory range for the PCI root bus should not overlap
841 * with the physical RAM 885 * with the physical RAM.
842 */ 886 */
843 pci_add_resource_offset(&resources, &controller->mem_space, 887 pci_add_resource_offset(&resources, &controller->mem_space,
844 controller->mem_offset); 888 controller->mem_offset);
845 889 pci_add_resource(&resources, &controller->io_space);
846 controller->first_busno = next_busno; 890 controller->first_busno = next_busno;
847 bus = pci_scan_root_bus(NULL, next_busno, controller->ops, 891 bus = pci_scan_root_bus(NULL, next_busno, controller->ops,
848 controller, &resources); 892 controller, &resources);
849 controller->root_bus = bus; 893 controller->root_bus = bus;
850 next_busno = bus->busn_res.end + 1; 894 next_busno = bus->busn_res.end + 1;
851
852 } 895 }
853 896
854 /* Do machine dependent PCI interrupt routing */ 897 /* Do machine dependent PCI interrupt routing */
@@ -860,7 +903,6 @@ int __init pcibios_init(void)
860 * It allocates all of the resources (I/O memory, etc) 903 * It allocates all of the resources (I/O memory, etc)
861 * associated with the devices read in above. 904 * associated with the devices read in above.
862 */ 905 */
863
864 pci_assign_unassigned_resources(); 906 pci_assign_unassigned_resources();
865 907
866 /* Record the I/O resources in the PCI controller structure. */ 908 /* Record the I/O resources in the PCI controller structure. */
@@ -868,9 +910,6 @@ int __init pcibios_init(void)
868 struct pci_controller *controller = &pci_controllers[i]; 910 struct pci_controller *controller = &pci_controllers[i];
869 gxio_trio_context_t *trio_context = controller->trio; 911 gxio_trio_context_t *trio_context = controller->trio;
870 struct pci_bus *root_bus = pci_controllers[i].root_bus; 912 struct pci_bus *root_bus = pci_controllers[i].root_bus;
871 struct pci_bus *next_bus;
872 uint32_t bus_address_hi;
873 struct pci_dev *dev;
874 int ret; 913 int ret;
875 int j; 914 int j;
876 915
@@ -884,43 +923,12 @@ int __init pcibios_init(void)
884 /* Configure the max_payload_size values for this domain. */ 923 /* Configure the max_payload_size values for this domain. */
885 fixup_read_and_payload_sizes(controller); 924 fixup_read_and_payload_sizes(controller);
886 925
887 list_for_each_entry(dev, &root_bus->devices, bus_list) { 926 /* Alloc a PIO region for PCI memory access for each RC port. */
888 /* Find the PCI host controller, ie. the 1st bridge. */
889 if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI &&
890 (PCI_SLOT(dev->devfn) == 0)) {
891 next_bus = dev->subordinate;
892 pci_controllers[i].mem_resources[0] =
893 *next_bus->resource[0];
894 pci_controllers[i].mem_resources[1] =
895 *next_bus->resource[1];
896 pci_controllers[i].mem_resources[2] =
897 *next_bus->resource[2];
898
899 break;
900 }
901 }
902
903 if (pci_controllers[i].mem_resources[1].flags & IORESOURCE_MEM)
904 bus_address_hi =
905 pci_controllers[i].mem_resources[1].start >> 32;
906 else if (pci_controllers[i].mem_resources[2].flags & IORESOURCE_PREFETCH)
907 bus_address_hi =
908 pci_controllers[i].mem_resources[2].start >> 32;
909 else {
910 /* This is unlikely. */
911 pr_err("PCI: no memory resources on TRIO %d mac %d\n",
912 controller->trio_index, controller->mac);
913 continue;
914 }
915
916 /*
917 * Alloc a PIO region for PCI memory access for each RC port.
918 */
919 ret = gxio_trio_alloc_pio_regions(trio_context, 1, 0, 0); 927 ret = gxio_trio_alloc_pio_regions(trio_context, 1, 0, 0);
920 if (ret < 0) { 928 if (ret < 0) {
921 pr_err("PCI: MEM PIO alloc failure on TRIO %d mac %d, " 929 pr_err("PCI: MEM PIO alloc failure on TRIO %d mac %d, "
922 "give up\n", controller->trio_index, 930 "give up\n", controller->trio_index,
923 controller->mac); 931 controller->mac);
924 932
925 continue; 933 continue;
926 } 934 }
@@ -938,12 +946,45 @@ int __init pcibios_init(void)
938 0); 946 0);
939 if (ret < 0) { 947 if (ret < 0) {
940 pr_err("PCI: MEM PIO init failure on TRIO %d mac %d, " 948 pr_err("PCI: MEM PIO init failure on TRIO %d mac %d, "
941 "give up\n", controller->trio_index, 949 "give up\n", controller->trio_index,
942 controller->mac); 950 controller->mac);
943 951
944 continue; 952 continue;
945 } 953 }
946 954
955#ifdef CONFIG_TILE_PCI_IO
956 /*
957 * Alloc a PIO region for PCI I/O space access for each RC port.
958 */
959 ret = gxio_trio_alloc_pio_regions(trio_context, 1, 0, 0);
960 if (ret < 0) {
961 pr_err("PCI: I/O PIO alloc failure on TRIO %d mac %d, "
962 "give up\n", controller->trio_index,
963 controller->mac);
964
965 continue;
966 }
967
968 controller->pio_io_index = ret;
969
970 /*
971 * For PIO IO, the bus_address_hi parameter is hard-coded 0
972 * because PCI I/O address space is 32-bit.
973 */
974 ret = gxio_trio_init_pio_region_aux(trio_context,
975 controller->pio_io_index,
976 controller->mac,
977 0,
978 HV_TRIO_PIO_FLAG_IO_SPACE);
979 if (ret < 0) {
980 pr_err("PCI: I/O PIO init failure on TRIO %d mac %d, "
981 "give up\n", controller->trio_index,
982 controller->mac);
983
984 continue;
985 }
986#endif
987
947 /* 988 /*
948 * Configure a Mem-Map region for each memory controller so 989 * Configure a Mem-Map region for each memory controller so
949 * that Linux can map all of its PA space to the PCI bus. 990 * that Linux can map all of its PA space to the PCI bus.
@@ -958,9 +999,9 @@ int __init pcibios_init(void)
958 0); 999 0);
959 if (ret < 0) { 1000 if (ret < 0) {
960 pr_err("PCI: Mem-Map alloc failure on TRIO %d " 1001 pr_err("PCI: Mem-Map alloc failure on TRIO %d "
961 "mac %d for MC %d, give up\n", 1002 "mac %d for MC %d, give up\n",
962 controller->trio_index, 1003 controller->trio_index,
963 controller->mac, j); 1004 controller->mac, j);
964 1005
965 goto alloc_mem_map_failed; 1006 goto alloc_mem_map_failed;
966 } 1007 }
@@ -991,9 +1032,9 @@ int __init pcibios_init(void)
991 GXIO_TRIO_ORDER_MODE_UNORDERED); 1032 GXIO_TRIO_ORDER_MODE_UNORDERED);
992 if (ret < 0) { 1033 if (ret < 0) {
993 pr_err("PCI: Mem-Map init failure on TRIO %d " 1034 pr_err("PCI: Mem-Map init failure on TRIO %d "
994 "mac %d for MC %d, give up\n", 1035 "mac %d for MC %d, give up\n",
995 controller->trio_index, 1036 controller->trio_index,
996 controller->mac, j); 1037 controller->mac, j);
997 1038
998 goto alloc_mem_map_failed; 1039 goto alloc_mem_map_failed;
999 } 1040 }
@@ -1002,23 +1043,19 @@ int __init pcibios_init(void)
1002alloc_mem_map_failed: 1043alloc_mem_map_failed:
1003 break; 1044 break;
1004 } 1045 }
1005
1006 } 1046 }
1007 1047
1008 return 0; 1048 return 0;
1009} 1049}
1010subsys_initcall(pcibios_init); 1050subsys_initcall(pcibios_init);
1011 1051
1012/* Note: to be deleted after Linux 3.6 merge. */ 1052/* No bus fixups needed. */
1013void pcibios_fixup_bus(struct pci_bus *bus) 1053void pcibios_fixup_bus(struct pci_bus *bus)
1014{ 1054{
1015} 1055}
1016 1056
1017/* 1057/* Process any "pci=" kernel boot arguments. */
1018 * This can be called from the generic PCI layer, but doesn't need to 1058char *__init pcibios_setup(char *str)
1019 * do anything.
1020 */
1021char *pcibios_setup(char *str)
1022{ 1059{
1023 if (!strcmp(str, "off")) { 1060 if (!strcmp(str, "off")) {
1024 pci_probe = 0; 1061 pci_probe = 0;
@@ -1029,8 +1066,7 @@ char *pcibios_setup(char *str)
1029 1066
1030/* 1067/*
1031 * Enable memory address decoding, as appropriate, for the 1068 * Enable memory address decoding, as appropriate, for the
1032 * device described by the 'dev' struct. The I/O decoding 1069 * device described by the 'dev' struct.
1033 * is disabled, though the TILE-Gx supports I/O addressing.
1034 * 1070 *
1035 * This is called from the generic PCI layer, and can be called 1071 * This is called from the generic PCI layer, and can be called
1036 * for bridges or endpoints. 1072 * for bridges or endpoints.
@@ -1040,13 +1076,24 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
1040 return pci_enable_resources(dev, mask); 1076 return pci_enable_resources(dev, mask);
1041} 1077}
1042 1078
1043/* Called for each device after PCI setup is done. */ 1079/*
1080 * Called for each device after PCI setup is done.
1081 * We initialize the PCI device capabilities conservatively, assuming that
1082 * all devices can only address the 32-bit DMA space. The exception here is
1083 * that the device dma_offset is set to the value that matches the 64-bit
1084 * capable devices. This is OK because dma_offset is not used by legacy
1085 * dma_ops, nor by the hybrid dma_ops's streaming DMAs, which are 64-bit ops.
1086 * This implementation matches the kernel design of setting PCI devices'
1087 * coherent_dma_mask to 0xffffffffull by default, allowing the device drivers
1088 * to skip calling pci_set_consistent_dma_mask(DMA_BIT_MASK(32)).
1089 */
1044static void pcibios_fixup_final(struct pci_dev *pdev) 1090static void pcibios_fixup_final(struct pci_dev *pdev)
1045{ 1091{
1046 set_dma_ops(&pdev->dev, gx_pci_dma_map_ops); 1092 set_dma_ops(&pdev->dev, gx_legacy_pci_dma_map_ops);
1047 set_dma_offset(&pdev->dev, TILE_PCI_MEM_MAP_BASE_OFFSET); 1093 set_dma_offset(&pdev->dev, TILE_PCI_MEM_MAP_BASE_OFFSET);
1048 pdev->dev.archdata.max_direct_dma_addr = 1094 pdev->dev.archdata.max_direct_dma_addr =
1049 TILE_PCI_MAX_DIRECT_DMA_ADDRESS; 1095 TILE_PCI_MAX_DIRECT_DMA_ADDRESS;
1096 pdev->dev.coherent_dma_mask = TILE_PCI_MAX_DIRECT_DMA_ADDRESS;
1050} 1097}
1051DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, pcibios_fixup_final); 1098DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, pcibios_fixup_final);
1052 1099
@@ -1060,19 +1107,15 @@ void __iomem *ioremap(resource_size_t phys_addr, unsigned long size)
1060 resource_size_t start; 1107 resource_size_t start;
1061 resource_size_t end; 1108 resource_size_t end;
1062 int trio_fd; 1109 int trio_fd;
1063 int i, j; 1110 int i;
1064 1111
1065 start = phys_addr; 1112 start = phys_addr;
1066 end = phys_addr + size - 1; 1113 end = phys_addr + size - 1;
1067 1114
1068 /* 1115 /*
1069 * In the following, each PCI controller's mem_resources[1] 1116 * By searching phys_addr in each controller's mem_space, we can
1070 * represents its (non-prefetchable) PCI memory resource and
1071 * mem_resources[2] refers to its prefetchable PCI memory resource.
1072 * By searching phys_addr in each controller's mem_resources[], we can
1073 * determine the controller that should accept the PCI memory access. 1117 * determine the controller that should accept the PCI memory access.
1074 */ 1118 */
1075
1076 for (i = 0; i < num_rc_controllers; i++) { 1119 for (i = 0; i < num_rc_controllers; i++) {
1077 /* 1120 /*
1078 * Skip controllers that are not properly initialized or 1121 * Skip controllers that are not properly initialized or
@@ -1081,25 +1124,18 @@ void __iomem *ioremap(resource_size_t phys_addr, unsigned long size)
1081 if (pci_controllers[i].root_bus == NULL) 1124 if (pci_controllers[i].root_bus == NULL)
1082 continue; 1125 continue;
1083 1126
1084 for (j = 1; j < 3; j++) { 1127 bar_start = pci_controllers[i].mem_space.start;
1085 bar_start = 1128 bar_end = pci_controllers[i].mem_space.end;
1086 pci_controllers[i].mem_resources[j].start;
1087 bar_end =
1088 pci_controllers[i].mem_resources[j].end;
1089
1090 if ((start >= bar_start) && (end <= bar_end)) {
1091 1129
1092 controller = &pci_controllers[i]; 1130 if ((start >= bar_start) && (end <= bar_end)) {
1093 1131 controller = &pci_controllers[i];
1094 goto got_it; 1132 break;
1095 }
1096 } 1133 }
1097 } 1134 }
1098 1135
1099 if (controller == NULL) 1136 if (controller == NULL)
1100 return NULL; 1137 return NULL;
1101 1138
1102got_it:
1103 trio_fd = controller->trio->fd; 1139 trio_fd = controller->trio->fd;
1104 1140
1105 /* Convert the resource start to the bus address offset. */ 1141 /* Convert the resource start to the bus address offset. */
@@ -1107,14 +1143,71 @@ got_it:
1107 1143
1108 offset = HV_TRIO_PIO_OFFSET(controller->pio_mem_index) + start; 1144 offset = HV_TRIO_PIO_OFFSET(controller->pio_mem_index) + start;
1109 1145
1110 /* 1146 /* We need to keep the PCI bus address's in-page offset in the VA. */
1111 * We need to keep the PCI bus address's in-page offset in the VA.
1112 */
1113 return iorpc_ioremap(trio_fd, offset, size) + 1147 return iorpc_ioremap(trio_fd, offset, size) +
1114 (phys_addr & (PAGE_SIZE - 1)); 1148 (start & (PAGE_SIZE - 1));
1115} 1149}
1116EXPORT_SYMBOL(ioremap); 1150EXPORT_SYMBOL(ioremap);
1117 1151
1152#ifdef CONFIG_TILE_PCI_IO
1153/* Map a PCI I/O address into VA space. */
1154void __iomem *ioport_map(unsigned long port, unsigned int size)
1155{
1156 struct pci_controller *controller = NULL;
1157 resource_size_t bar_start;
1158 resource_size_t bar_end;
1159 resource_size_t offset;
1160 resource_size_t start;
1161 resource_size_t end;
1162 int trio_fd;
1163 int i;
1164
1165 start = port;
1166 end = port + size - 1;
1167
1168 /*
1169 * By searching the port in each controller's io_space, we can
1170 * determine the controller that should accept the PCI I/O access.
1171 */
1172 for (i = 0; i < num_rc_controllers; i++) {
1173 /*
1174 * Skip controllers that are not properly initialized or
1175 * have down links.
1176 */
1177 if (pci_controllers[i].root_bus == NULL)
1178 continue;
1179
1180 bar_start = pci_controllers[i].io_space.start;
1181 bar_end = pci_controllers[i].io_space.end;
1182
1183 if ((start >= bar_start) && (end <= bar_end)) {
1184 controller = &pci_controllers[i];
1185 break;
1186 }
1187 }
1188
1189 if (controller == NULL)
1190 return NULL;
1191
1192 trio_fd = controller->trio->fd;
1193
1194 /* Convert the resource start to the bus address offset. */
1195 port -= controller->io_space.start;
1196
1197 offset = HV_TRIO_PIO_OFFSET(controller->pio_io_index) + port;
1198
1199 /* We need to keep the PCI bus address's in-page offset in the VA. */
1200 return iorpc_ioremap(trio_fd, offset, size) + (port & (PAGE_SIZE - 1));
1201}
1202EXPORT_SYMBOL(ioport_map);
1203
1204void ioport_unmap(void __iomem *addr)
1205{
1206 iounmap(addr);
1207}
1208EXPORT_SYMBOL(ioport_unmap);
1209#endif
1210
1118void pci_iounmap(struct pci_dev *dev, void __iomem *addr) 1211void pci_iounmap(struct pci_dev *dev, void __iomem *addr)
1119{ 1212{
1120 iounmap(addr); 1213 iounmap(addr);
@@ -1136,7 +1229,6 @@ EXPORT_SYMBOL(pci_iounmap);
1136 * offset is in bytes, from the start of config space for the 1229 * offset is in bytes, from the start of config space for the
1137 * specified bus & device. 1230 * specified bus & device.
1138 */ 1231 */
1139
1140static int tile_cfg_read(struct pci_bus *bus, unsigned int devfn, int offset, 1232static int tile_cfg_read(struct pci_bus *bus, unsigned int devfn, int offset,
1141 int size, u32 *val) 1233 int size, u32 *val)
1142{ 1234{
@@ -1186,7 +1278,6 @@ static int tile_cfg_read(struct pci_bus *bus, unsigned int devfn, int offset,
1186 * Accesses to the directly attached device have to be 1278 * Accesses to the directly attached device have to be
1187 * sent as type-0 configs. 1279 * sent as type-0 configs.
1188 */ 1280 */
1189
1190 if (busnum == (controller->first_busno + 1)) { 1281 if (busnum == (controller->first_busno + 1)) {
1191 /* 1282 /*
1192 * There is only one device off of our built-in P2P bridge. 1283 * There is only one device off of our built-in P2P bridge.
@@ -1208,9 +1299,8 @@ static int tile_cfg_read(struct pci_bus *bus, unsigned int devfn, int offset,
1208 * Note that we don't set the mac field in cfg_addr because the 1299 * Note that we don't set the mac field in cfg_addr because the
1209 * mapping is per port. 1300 * mapping is per port.
1210 */ 1301 */
1211
1212 mmio_addr = trio_context->mmio_base_pio_cfg[controller->mac] + 1302 mmio_addr = trio_context->mmio_base_pio_cfg[controller->mac] +
1213 cfg_addr.word; 1303 cfg_addr.word;
1214 1304
1215valid_device: 1305valid_device:
1216 1306
@@ -1314,7 +1404,6 @@ static int tile_cfg_write(struct pci_bus *bus, unsigned int devfn, int offset,
1314 * Accesses to the directly attached device have to be 1404 * Accesses to the directly attached device have to be
1315 * sent as type-0 configs. 1405 * sent as type-0 configs.
1316 */ 1406 */
1317
1318 if (busnum == (controller->first_busno + 1)) { 1407 if (busnum == (controller->first_busno + 1)) {
1319 /* 1408 /*
1320 * There is only one device off of our built-in P2P bridge. 1409 * There is only one device off of our built-in P2P bridge.
@@ -1336,7 +1425,6 @@ static int tile_cfg_write(struct pci_bus *bus, unsigned int devfn, int offset,
1336 * Note that we don't set the mac field in cfg_addr because the 1425 * Note that we don't set the mac field in cfg_addr because the
1337 * mapping is per port. 1426 * mapping is per port.
1338 */ 1427 */
1339
1340 mmio_addr = trio_context->mmio_base_pio_cfg[controller->mac] + 1428 mmio_addr = trio_context->mmio_base_pio_cfg[controller->mac] +
1341 cfg_addr.word; 1429 cfg_addr.word;
1342 1430
@@ -1374,11 +1462,8 @@ static struct pci_ops tile_cfg_ops = {
1374}; 1462};
1375 1463
1376 1464
1377/* 1465/* MSI support starts here. */
1378 * MSI support starts here. 1466static unsigned int tilegx_msi_startup(struct irq_data *d)
1379 */
1380static unsigned int
1381tilegx_msi_startup(struct irq_data *d)
1382{ 1467{
1383 if (d->msi_desc) 1468 if (d->msi_desc)
1384 unmask_msi_irq(d); 1469 unmask_msi_irq(d);
@@ -1386,21 +1471,18 @@ tilegx_msi_startup(struct irq_data *d)
1386 return 0; 1471 return 0;
1387} 1472}
1388 1473
1389static void 1474static void tilegx_msi_ack(struct irq_data *d)
1390tilegx_msi_ack(struct irq_data *d)
1391{ 1475{
1392 __insn_mtspr(SPR_IPI_EVENT_RESET_K, 1UL << d->irq); 1476 __insn_mtspr(SPR_IPI_EVENT_RESET_K, 1UL << d->irq);
1393} 1477}
1394 1478
1395static void 1479static void tilegx_msi_mask(struct irq_data *d)
1396tilegx_msi_mask(struct irq_data *d)
1397{ 1480{
1398 mask_msi_irq(d); 1481 mask_msi_irq(d);
1399 __insn_mtspr(SPR_IPI_MASK_SET_K, 1UL << d->irq); 1482 __insn_mtspr(SPR_IPI_MASK_SET_K, 1UL << d->irq);
1400} 1483}
1401 1484
1402static void 1485static void tilegx_msi_unmask(struct irq_data *d)
1403tilegx_msi_unmask(struct irq_data *d)
1404{ 1486{
1405 __insn_mtspr(SPR_IPI_MASK_RESET_K, 1UL << d->irq); 1487 __insn_mtspr(SPR_IPI_MASK_RESET_K, 1UL << d->irq);
1406 unmask_msi_irq(d); 1488 unmask_msi_irq(d);
@@ -1457,32 +1539,55 @@ int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
1457 trio_context = controller->trio; 1539 trio_context = controller->trio;
1458 1540
1459 /* 1541 /*
1460 * Allocate the Mem-Map that will accept the MSI write and 1542 * Allocate a scatter-queue that will accept the MSI write and
1461 * trigger the TILE-side interrupts. 1543 * trigger the TILE-side interrupts. We use the scatter-queue regions
1544 * before the mem map regions, because the latter are needed by more
1545 * applications.
1462 */ 1546 */
1463 mem_map = gxio_trio_alloc_memory_maps(trio_context, 1, 0, 0); 1547 mem_map = gxio_trio_alloc_scatter_queues(trio_context, 1, 0, 0);
1464 if (mem_map < 0) { 1548 if (mem_map >= 0) {
1465 dev_printk(KERN_INFO, &pdev->dev, 1549 TRIO_MAP_SQ_DOORBELL_FMT_t doorbell_template = {{
1466 "%s Mem-Map alloc failure. " 1550 .pop = 0,
1467 "Failed to initialize MSI interrupts. " 1551 .doorbell = 1,
1468 "Falling back to legacy interrupts.\n", 1552 }};
1469 desc->msi_attrib.is_msix ? "MSI-X" : "MSI"); 1553
1554 mem_map += TRIO_NUM_MAP_MEM_REGIONS;
1555 mem_map_base = MEM_MAP_INTR_REGIONS_BASE +
1556 mem_map * MEM_MAP_INTR_REGION_SIZE;
1557 mem_map_limit = mem_map_base + MEM_MAP_INTR_REGION_SIZE - 1;
1558
1559 msi_addr = mem_map_base + MEM_MAP_INTR_REGION_SIZE - 8;
1560 msg.data = (unsigned int)doorbell_template.word;
1561 } else {
1562 /* SQ regions are out, allocate from map mem regions. */
1563 mem_map = gxio_trio_alloc_memory_maps(trio_context, 1, 0, 0);
1564 if (mem_map < 0) {
1565 dev_printk(KERN_INFO, &pdev->dev,
1566 "%s Mem-Map alloc failure. "
1567 "Failed to initialize MSI interrupts. "
1568 "Falling back to legacy interrupts.\n",
1569 desc->msi_attrib.is_msix ? "MSI-X" : "MSI");
1570 ret = -ENOMEM;
1571 goto msi_mem_map_alloc_failure;
1572 }
1470 1573
1471 ret = -ENOMEM; 1574 mem_map_base = MEM_MAP_INTR_REGIONS_BASE +
1472 goto msi_mem_map_alloc_failure; 1575 mem_map * MEM_MAP_INTR_REGION_SIZE;
1576 mem_map_limit = mem_map_base + MEM_MAP_INTR_REGION_SIZE - 1;
1577
1578 msi_addr = mem_map_base + TRIO_MAP_MEM_REG_INT3 -
1579 TRIO_MAP_MEM_REG_INT0;
1580
1581 msg.data = mem_map;
1473 } 1582 }
1474 1583
1475 /* We try to distribute different IRQs to different tiles. */ 1584 /* We try to distribute different IRQs to different tiles. */
1476 cpu = tile_irq_cpu(irq); 1585 cpu = tile_irq_cpu(irq);
1477 1586
1478 /* 1587 /*
1479 * Now call up to the HV to configure the Mem-Map interrupt and 1588 * Now call up to the HV to configure the MSI interrupt and
1480 * set up the IPI binding. 1589 * set up the IPI binding.
1481 */ 1590 */
1482 mem_map_base = MEM_MAP_INTR_REGIONS_BASE +
1483 mem_map * MEM_MAP_INTR_REGION_SIZE;
1484 mem_map_limit = mem_map_base + MEM_MAP_INTR_REGION_SIZE - 1;
1485
1486 ret = gxio_trio_config_msi_intr(trio_context, cpu_x(cpu), cpu_y(cpu), 1591 ret = gxio_trio_config_msi_intr(trio_context, cpu_x(cpu), cpu_y(cpu),
1487 KERNEL_PL, irq, controller->mac, 1592 KERNEL_PL, irq, controller->mac,
1488 mem_map, mem_map_base, mem_map_limit, 1593 mem_map, mem_map_base, mem_map_limit,
@@ -1495,13 +1600,9 @@ int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
1495 1600
1496 irq_set_msi_desc(irq, desc); 1601 irq_set_msi_desc(irq, desc);
1497 1602
1498 msi_addr = mem_map_base + TRIO_MAP_MEM_REG_INT3 - TRIO_MAP_MEM_REG_INT0;
1499
1500 msg.address_hi = msi_addr >> 32; 1603 msg.address_hi = msi_addr >> 32;
1501 msg.address_lo = msi_addr & 0xffffffff; 1604 msg.address_lo = msi_addr & 0xffffffff;
1502 1605
1503 msg.data = mem_map;
1504
1505 write_msi_msg(irq, &msg); 1606 write_msi_msg(irq, &msg);
1506 irq_set_chip_and_handler(irq, &tilegx_msi_chip, handle_level_irq); 1607 irq_set_chip_and_handler(irq, &tilegx_msi_chip, handle_level_irq);
1507 irq_set_handler_data(irq, controller); 1608 irq_set_handler_data(irq, controller);
diff --git a/arch/tile/kernel/proc.c b/arch/tile/kernel/proc.c
index dafc447b5125..681100c59fda 100644
--- a/arch/tile/kernel/proc.c
+++ b/arch/tile/kernel/proc.c
@@ -113,7 +113,6 @@ arch_initcall(proc_tile_init);
113 * Support /proc/sys/tile directory 113 * Support /proc/sys/tile directory
114 */ 114 */
115 115
116#ifndef __tilegx__ /* FIXME: GX: no support for unaligned access yet */
117static ctl_table unaligned_subtable[] = { 116static ctl_table unaligned_subtable[] = {
118 { 117 {
119 .procname = "enabled", 118 .procname = "enabled",
@@ -160,4 +159,3 @@ static int __init proc_sys_tile_init(void)
160} 159}
161 160
162arch_initcall(proc_sys_tile_init); 161arch_initcall(proc_sys_tile_init);
163#endif
diff --git a/arch/tile/kernel/process.c b/arch/tile/kernel/process.c
index 8ac304484f98..16ed58948757 100644
--- a/arch/tile/kernel/process.c
+++ b/arch/tile/kernel/process.c
@@ -33,6 +33,7 @@
33#include <asm/syscalls.h> 33#include <asm/syscalls.h>
34#include <asm/traps.h> 34#include <asm/traps.h>
35#include <asm/setup.h> 35#include <asm/setup.h>
36#include <asm/uaccess.h>
36#ifdef CONFIG_HARDWALL 37#ifdef CONFIG_HARDWALL
37#include <asm/hardwall.h> 38#include <asm/hardwall.h>
38#endif 39#endif
@@ -74,19 +75,6 @@ void arch_release_thread_info(struct thread_info *info)
74{ 75{
75 struct single_step_state *step_state = info->step_state; 76 struct single_step_state *step_state = info->step_state;
76 77
77#ifdef CONFIG_HARDWALL
78 /*
79 * We free a thread_info from the context of the task that has
80 * been scheduled next, so the original task is already dead.
81 * Calling deactivate here just frees up the data structures.
82 * If the task we're freeing held the last reference to a
83 * hardwall fd, it would have been released prior to this point
84 * anyway via exit_files(), and the hardwall_task.info pointers
85 * would be NULL by now.
86 */
87 hardwall_deactivate_all(info->task);
88#endif
89
90 if (step_state) { 78 if (step_state) {
91 79
92 /* 80 /*
@@ -160,6 +148,14 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
160 */ 148 */
161 task_thread_info(p)->step_state = NULL; 149 task_thread_info(p)->step_state = NULL;
162 150
151#ifdef __tilegx__
152 /*
153 * Do not clone unalign jit fixup from the parent; each thread
154 * must allocate its own on demand.
155 */
156 task_thread_info(p)->unalign_jit_base = NULL;
157#endif
158
163 /* 159 /*
164 * Copy the registers onto the kernel stack so the 160 * Copy the registers onto the kernel stack so the
165 * return-from-interrupt code will reload it into registers. 161 * return-from-interrupt code will reload it into registers.
@@ -191,16 +187,8 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
191 memset(&p->thread.dma_async_tlb, 0, sizeof(struct async_tlb)); 187 memset(&p->thread.dma_async_tlb, 0, sizeof(struct async_tlb));
192#endif 188#endif
193 189
194#if CHIP_HAS_SN_PROC()
195 /* Likewise, the new thread is not running static processor code. */
196 p->thread.sn_proc_running = 0;
197 memset(&p->thread.sn_async_tlb, 0, sizeof(struct async_tlb));
198#endif
199
200#if CHIP_HAS_PROC_STATUS_SPR()
201 /* New thread has its miscellaneous processor state bits clear. */ 190 /* New thread has its miscellaneous processor state bits clear. */
202 p->thread.proc_status = 0; 191 p->thread.proc_status = 0;
203#endif
204 192
205#ifdef CONFIG_HARDWALL 193#ifdef CONFIG_HARDWALL
206 /* New thread does not own any networks. */ 194 /* New thread does not own any networks. */
@@ -218,19 +206,32 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
218 return 0; 206 return 0;
219} 207}
220 208
209int set_unalign_ctl(struct task_struct *tsk, unsigned int val)
210{
211 task_thread_info(tsk)->align_ctl = val;
212 return 0;
213}
214
215int get_unalign_ctl(struct task_struct *tsk, unsigned long adr)
216{
217 return put_user(task_thread_info(tsk)->align_ctl,
218 (unsigned int __user *)adr);
219}
220
221static struct task_struct corrupt_current = { .comm = "<corrupt>" };
222
221/* 223/*
222 * Return "current" if it looks plausible, or else a pointer to a dummy. 224 * Return "current" if it looks plausible, or else a pointer to a dummy.
223 * This can be helpful if we are just trying to emit a clean panic. 225 * This can be helpful if we are just trying to emit a clean panic.
224 */ 226 */
225struct task_struct *validate_current(void) 227struct task_struct *validate_current(void)
226{ 228{
227 static struct task_struct corrupt = { .comm = "<corrupt>" };
228 struct task_struct *tsk = current; 229 struct task_struct *tsk = current;
229 if (unlikely((unsigned long)tsk < PAGE_OFFSET || 230 if (unlikely((unsigned long)tsk < PAGE_OFFSET ||
230 (high_memory && (void *)tsk > high_memory) || 231 (high_memory && (void *)tsk > high_memory) ||
231 ((unsigned long)tsk & (__alignof__(*tsk) - 1)) != 0)) { 232 ((unsigned long)tsk & (__alignof__(*tsk) - 1)) != 0)) {
232 pr_err("Corrupt 'current' %p (sp %#lx)\n", tsk, stack_pointer); 233 pr_err("Corrupt 'current' %p (sp %#lx)\n", tsk, stack_pointer);
233 tsk = &corrupt; 234 tsk = &corrupt_current;
234 } 235 }
235 return tsk; 236 return tsk;
236} 237}
@@ -369,15 +370,11 @@ static void save_arch_state(struct thread_struct *t)
369 t->system_save[2] = __insn_mfspr(SPR_SYSTEM_SAVE_0_2); 370 t->system_save[2] = __insn_mfspr(SPR_SYSTEM_SAVE_0_2);
370 t->system_save[3] = __insn_mfspr(SPR_SYSTEM_SAVE_0_3); 371 t->system_save[3] = __insn_mfspr(SPR_SYSTEM_SAVE_0_3);
371 t->intctrl_0 = __insn_mfspr(SPR_INTCTRL_0_STATUS); 372 t->intctrl_0 = __insn_mfspr(SPR_INTCTRL_0_STATUS);
372#if CHIP_HAS_PROC_STATUS_SPR()
373 t->proc_status = __insn_mfspr(SPR_PROC_STATUS); 373 t->proc_status = __insn_mfspr(SPR_PROC_STATUS);
374#endif
375#if !CHIP_HAS_FIXED_INTVEC_BASE() 374#if !CHIP_HAS_FIXED_INTVEC_BASE()
376 t->interrupt_vector_base = __insn_mfspr(SPR_INTERRUPT_VECTOR_BASE_0); 375 t->interrupt_vector_base = __insn_mfspr(SPR_INTERRUPT_VECTOR_BASE_0);
377#endif 376#endif
378#if CHIP_HAS_TILE_RTF_HWM()
379 t->tile_rtf_hwm = __insn_mfspr(SPR_TILE_RTF_HWM); 377 t->tile_rtf_hwm = __insn_mfspr(SPR_TILE_RTF_HWM);
380#endif
381#if CHIP_HAS_DSTREAM_PF() 378#if CHIP_HAS_DSTREAM_PF()
382 t->dstream_pf = __insn_mfspr(SPR_DSTREAM_PF); 379 t->dstream_pf = __insn_mfspr(SPR_DSTREAM_PF);
383#endif 380#endif
@@ -398,15 +395,11 @@ static void restore_arch_state(const struct thread_struct *t)
398 __insn_mtspr(SPR_SYSTEM_SAVE_0_2, t->system_save[2]); 395 __insn_mtspr(SPR_SYSTEM_SAVE_0_2, t->system_save[2]);
399 __insn_mtspr(SPR_SYSTEM_SAVE_0_3, t->system_save[3]); 396 __insn_mtspr(SPR_SYSTEM_SAVE_0_3, t->system_save[3]);
400 __insn_mtspr(SPR_INTCTRL_0_STATUS, t->intctrl_0); 397 __insn_mtspr(SPR_INTCTRL_0_STATUS, t->intctrl_0);
401#if CHIP_HAS_PROC_STATUS_SPR()
402 __insn_mtspr(SPR_PROC_STATUS, t->proc_status); 398 __insn_mtspr(SPR_PROC_STATUS, t->proc_status);
403#endif
404#if !CHIP_HAS_FIXED_INTVEC_BASE() 399#if !CHIP_HAS_FIXED_INTVEC_BASE()
405 __insn_mtspr(SPR_INTERRUPT_VECTOR_BASE_0, t->interrupt_vector_base); 400 __insn_mtspr(SPR_INTERRUPT_VECTOR_BASE_0, t->interrupt_vector_base);
406#endif 401#endif
407#if CHIP_HAS_TILE_RTF_HWM()
408 __insn_mtspr(SPR_TILE_RTF_HWM, t->tile_rtf_hwm); 402 __insn_mtspr(SPR_TILE_RTF_HWM, t->tile_rtf_hwm);
409#endif
410#if CHIP_HAS_DSTREAM_PF() 403#if CHIP_HAS_DSTREAM_PF()
411 __insn_mtspr(SPR_DSTREAM_PF, t->dstream_pf); 404 __insn_mtspr(SPR_DSTREAM_PF, t->dstream_pf);
412#endif 405#endif
@@ -415,26 +408,11 @@ static void restore_arch_state(const struct thread_struct *t)
415 408
416void _prepare_arch_switch(struct task_struct *next) 409void _prepare_arch_switch(struct task_struct *next)
417{ 410{
418#if CHIP_HAS_SN_PROC()
419 int snctl;
420#endif
421#if CHIP_HAS_TILE_DMA() 411#if CHIP_HAS_TILE_DMA()
422 struct tile_dma_state *dma = &current->thread.tile_dma_state; 412 struct tile_dma_state *dma = &current->thread.tile_dma_state;
423 if (dma->enabled) 413 if (dma->enabled)
424 save_tile_dma_state(dma); 414 save_tile_dma_state(dma);
425#endif 415#endif
426#if CHIP_HAS_SN_PROC()
427 /*
428 * Suspend the static network processor if it was running.
429 * We do not suspend the fabric itself, just like we don't
430 * try to suspend the UDN.
431 */
432 snctl = __insn_mfspr(SPR_SNCTL);
433 current->thread.sn_proc_running =
434 (snctl & SPR_SNCTL__FRZPROC_MASK) == 0;
435 if (current->thread.sn_proc_running)
436 __insn_mtspr(SPR_SNCTL, snctl | SPR_SNCTL__FRZPROC_MASK);
437#endif
438} 416}
439 417
440 418
@@ -462,17 +440,6 @@ struct task_struct *__sched _switch_to(struct task_struct *prev,
462 /* Restore other arch state. */ 440 /* Restore other arch state. */
463 restore_arch_state(&next->thread); 441 restore_arch_state(&next->thread);
464 442
465#if CHIP_HAS_SN_PROC()
466 /*
467 * Restart static network processor in the new process
468 * if it was running before.
469 */
470 if (next->thread.sn_proc_running) {
471 int snctl = __insn_mfspr(SPR_SNCTL);
472 __insn_mtspr(SPR_SNCTL, snctl & ~SPR_SNCTL__FRZPROC_MASK);
473 }
474#endif
475
476#ifdef CONFIG_HARDWALL 443#ifdef CONFIG_HARDWALL
477 /* Enable or disable access to the network registers appropriately. */ 444 /* Enable or disable access to the network registers appropriately. */
478 hardwall_switch_tasks(prev, next); 445 hardwall_switch_tasks(prev, next);
@@ -514,7 +481,7 @@ int do_work_pending(struct pt_regs *regs, u32 thread_info_flags)
514 schedule(); 481 schedule();
515 return 1; 482 return 1;
516 } 483 }
517#if CHIP_HAS_TILE_DMA() || CHIP_HAS_SN_PROC() 484#if CHIP_HAS_TILE_DMA()
518 if (thread_info_flags & _TIF_ASYNC_TLB) { 485 if (thread_info_flags & _TIF_ASYNC_TLB) {
519 do_async_page_fault(regs); 486 do_async_page_fault(regs);
520 return 1; 487 return 1;
@@ -564,7 +531,15 @@ void flush_thread(void)
564 */ 531 */
565void exit_thread(void) 532void exit_thread(void)
566{ 533{
567 /* Nothing */ 534#ifdef CONFIG_HARDWALL
535 /*
536 * Remove the task from the list of tasks that are associated
537 * with any live hardwalls. (If the task that is exiting held
538 * the last reference to a hardwall fd, it would already have
539 * been released and deactivated at this point.)
540 */
541 hardwall_deactivate_all(current);
542#endif
568} 543}
569 544
570void show_regs(struct pt_regs *regs) 545void show_regs(struct pt_regs *regs)
@@ -573,23 +548,24 @@ void show_regs(struct pt_regs *regs)
573 int i; 548 int i;
574 549
575 pr_err("\n"); 550 pr_err("\n");
576 show_regs_print_info(KERN_ERR); 551 if (tsk != &corrupt_current)
552 show_regs_print_info(KERN_ERR);
577#ifdef __tilegx__ 553#ifdef __tilegx__
578 for (i = 0; i < 51; i += 3) 554 for (i = 0; i < 17; i++)
579 pr_err(" r%-2d: "REGFMT" r%-2d: "REGFMT" r%-2d: "REGFMT"\n", 555 pr_err(" r%-2d: "REGFMT" r%-2d: "REGFMT" r%-2d: "REGFMT"\n",
580 i, regs->regs[i], i+1, regs->regs[i+1], 556 i, regs->regs[i], i+18, regs->regs[i+18],
581 i+2, regs->regs[i+2]); 557 i+36, regs->regs[i+36]);
582 pr_err(" r51: "REGFMT" r52: "REGFMT" tp : "REGFMT"\n", 558 pr_err(" r17: "REGFMT" r35: "REGFMT" tp : "REGFMT"\n",
583 regs->regs[51], regs->regs[52], regs->tp); 559 regs->regs[17], regs->regs[35], regs->tp);
584 pr_err(" sp : "REGFMT" lr : "REGFMT"\n", regs->sp, regs->lr); 560 pr_err(" sp : "REGFMT" lr : "REGFMT"\n", regs->sp, regs->lr);
585#else 561#else
586 for (i = 0; i < 52; i += 4) 562 for (i = 0; i < 13; i++)
587 pr_err(" r%-2d: "REGFMT" r%-2d: "REGFMT 563 pr_err(" r%-2d: "REGFMT" r%-2d: "REGFMT
588 " r%-2d: "REGFMT" r%-2d: "REGFMT"\n", 564 " r%-2d: "REGFMT" r%-2d: "REGFMT"\n",
589 i, regs->regs[i], i+1, regs->regs[i+1], 565 i, regs->regs[i], i+14, regs->regs[i+14],
590 i+2, regs->regs[i+2], i+3, regs->regs[i+3]); 566 i+27, regs->regs[i+27], i+40, regs->regs[i+40]);
591 pr_err(" r52: "REGFMT" tp : "REGFMT" sp : "REGFMT" lr : "REGFMT"\n", 567 pr_err(" r13: "REGFMT" tp : "REGFMT" sp : "REGFMT" lr : "REGFMT"\n",
592 regs->regs[52], regs->tp, regs->sp, regs->lr); 568 regs->regs[13], regs->tp, regs->sp, regs->lr);
593#endif 569#endif
594 pr_err(" pc : "REGFMT" ex1: %ld faultnum: %ld\n", 570 pr_err(" pc : "REGFMT" ex1: %ld faultnum: %ld\n",
595 regs->pc, regs->ex1, regs->faultnum); 571 regs->pc, regs->ex1, regs->faultnum);
diff --git a/arch/tile/kernel/ptrace.c b/arch/tile/kernel/ptrace.c
index 0f83ed4602b2..de98c6ddf136 100644
--- a/arch/tile/kernel/ptrace.c
+++ b/arch/tile/kernel/ptrace.c
@@ -265,6 +265,21 @@ int do_syscall_trace_enter(struct pt_regs *regs)
265 265
266void do_syscall_trace_exit(struct pt_regs *regs) 266void do_syscall_trace_exit(struct pt_regs *regs)
267{ 267{
268 long errno;
269
270 /*
271 * The standard tile calling convention returns the value (or negative
272 * errno) in r0, and zero (or positive errno) in r1.
273 * It saves a couple of cycles on the hot path to do this work in
274 * registers only as we return, rather than updating the in-memory
275 * struct ptregs.
276 */
277 errno = (long) regs->regs[0];
278 if (errno < 0 && errno > -4096)
279 regs->regs[1] = -errno;
280 else
281 regs->regs[1] = 0;
282
268 if (test_thread_flag(TIF_SYSCALL_TRACE)) 283 if (test_thread_flag(TIF_SYSCALL_TRACE))
269 tracehook_report_syscall_exit(regs, 0); 284 tracehook_report_syscall_exit(regs, 0);
270 285
@@ -272,7 +287,7 @@ void do_syscall_trace_exit(struct pt_regs *regs)
272 trace_sys_exit(regs, regs->regs[0]); 287 trace_sys_exit(regs, regs->regs[0]);
273} 288}
274 289
275void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code) 290void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs)
276{ 291{
277 struct siginfo info; 292 struct siginfo info;
278 293
@@ -288,5 +303,5 @@ void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code)
288/* Handle synthetic interrupt delivered only by the simulator. */ 303/* Handle synthetic interrupt delivered only by the simulator. */
289void __kprobes do_breakpoint(struct pt_regs* regs, int fault_num) 304void __kprobes do_breakpoint(struct pt_regs* regs, int fault_num)
290{ 305{
291 send_sigtrap(current, regs, fault_num); 306 send_sigtrap(current, regs);
292} 307}
diff --git a/arch/tile/kernel/reboot.c b/arch/tile/kernel/reboot.c
index d1b5c913ae72..6c5d2c070a12 100644
--- a/arch/tile/kernel/reboot.c
+++ b/arch/tile/kernel/reboot.c
@@ -27,7 +27,6 @@
27 27
28void machine_halt(void) 28void machine_halt(void)
29{ 29{
30 warn_early_printk();
31 arch_local_irq_disable_all(); 30 arch_local_irq_disable_all();
32 smp_send_stop(); 31 smp_send_stop();
33 hv_halt(); 32 hv_halt();
@@ -35,7 +34,6 @@ void machine_halt(void)
35 34
36void machine_power_off(void) 35void machine_power_off(void)
37{ 36{
38 warn_early_printk();
39 arch_local_irq_disable_all(); 37 arch_local_irq_disable_all();
40 smp_send_stop(); 38 smp_send_stop();
41 hv_power_off(); 39 hv_power_off();
diff --git a/arch/tile/kernel/regs_32.S b/arch/tile/kernel/regs_32.S
index c12280c2d904..542cae17a93a 100644
--- a/arch/tile/kernel/regs_32.S
+++ b/arch/tile/kernel/regs_32.S
@@ -20,7 +20,7 @@
20#include <asm/switch_to.h> 20#include <asm/switch_to.h>
21 21
22/* 22/*
23 * See <asm/system.h>; called with prev and next task_struct pointers. 23 * See <asm/switch_to.h>; called with prev and next task_struct pointers.
24 * "prev" is returned in r0 for _switch_to and also for ret_from_fork. 24 * "prev" is returned in r0 for _switch_to and also for ret_from_fork.
25 * 25 *
26 * We want to save pc/sp in "prev", and get the new pc/sp from "next". 26 * We want to save pc/sp in "prev", and get the new pc/sp from "next".
@@ -39,7 +39,7 @@
39 */ 39 */
40 40
41#if CALLEE_SAVED_REGS_COUNT != 24 41#if CALLEE_SAVED_REGS_COUNT != 24
42# error Mismatch between <asm/system.h> and kernel/entry.S 42# error Mismatch between <asm/switch_to.h> and kernel/entry.S
43#endif 43#endif
44#define FRAME_SIZE ((2 + CALLEE_SAVED_REGS_COUNT) * 4) 44#define FRAME_SIZE ((2 + CALLEE_SAVED_REGS_COUNT) * 4)
45 45
diff --git a/arch/tile/kernel/regs_64.S b/arch/tile/kernel/regs_64.S
index 0829fd01fa30..bbffcc6f340f 100644
--- a/arch/tile/kernel/regs_64.S
+++ b/arch/tile/kernel/regs_64.S
@@ -20,7 +20,7 @@
20#include <asm/switch_to.h> 20#include <asm/switch_to.h>
21 21
22/* 22/*
23 * See <asm/system.h>; called with prev and next task_struct pointers. 23 * See <asm/switch_to.h>; called with prev and next task_struct pointers.
24 * "prev" is returned in r0 for _switch_to and also for ret_from_fork. 24 * "prev" is returned in r0 for _switch_to and also for ret_from_fork.
25 * 25 *
26 * We want to save pc/sp in "prev", and get the new pc/sp from "next". 26 * We want to save pc/sp in "prev", and get the new pc/sp from "next".
@@ -39,7 +39,7 @@
39 */ 39 */
40 40
41#if CALLEE_SAVED_REGS_COUNT != 24 41#if CALLEE_SAVED_REGS_COUNT != 24
42# error Mismatch between <asm/system.h> and kernel/entry.S 42# error Mismatch between <asm/switch_to.h> and kernel/entry.S
43#endif 43#endif
44#define FRAME_SIZE ((2 + CALLEE_SAVED_REGS_COUNT) * 8) 44#define FRAME_SIZE ((2 + CALLEE_SAVED_REGS_COUNT) * 8)
45 45
diff --git a/arch/tile/kernel/relocate_kernel_32.S b/arch/tile/kernel/relocate_kernel_32.S
index 010b418515f8..e44fbcf8cbd5 100644
--- a/arch/tile/kernel/relocate_kernel_32.S
+++ b/arch/tile/kernel/relocate_kernel_32.S
@@ -20,15 +20,6 @@
20#include <asm/page.h> 20#include <asm/page.h>
21#include <hv/hypervisor.h> 21#include <hv/hypervisor.h>
22 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 23#undef RELOCATE_NEW_KERNEL_VERBOSE
33 24
34STD_ENTRY(relocate_new_kernel) 25STD_ENTRY(relocate_new_kernel)
@@ -43,8 +34,8 @@ STD_ENTRY(relocate_new_kernel)
43 addi sp, sp, -8 34 addi sp, sp, -8
44 /* we now have a stack (whether we need one or not) */ 35 /* we now have a stack (whether we need one or not) */
45 36
46 moveli r40, lo16(___hv_console_putc) 37 moveli r40, lo16(hv_console_putc)
47 auli r40, r40, ha16(___hv_console_putc) 38 auli r40, r40, ha16(hv_console_putc)
48 39
49#ifdef RELOCATE_NEW_KERNEL_VERBOSE 40#ifdef RELOCATE_NEW_KERNEL_VERBOSE
50 moveli r0, 'r' 41 moveli r0, 'r'
@@ -86,7 +77,6 @@ STD_ENTRY(relocate_new_kernel)
86 move r30, sp 77 move r30, sp
87 addi sp, sp, -8 78 addi sp, sp, -8
88 79
89#if CHIP_HAS_CBOX_HOME_MAP()
90 /* 80 /*
91 * On TILEPro, we need to flush all tiles' caches, since we may 81 * On TILEPro, we need to flush all tiles' caches, since we may
92 * have been doing hash-for-home caching there. Note that we 82 * have been doing hash-for-home caching there. Note that we
@@ -114,15 +104,14 @@ STD_ENTRY(relocate_new_kernel)
114 } 104 }
115 { 105 {
116 move r8, zero /* asids */ 106 move r8, zero /* asids */
117 moveli r20, lo16(___hv_flush_remote) 107 moveli r20, lo16(hv_flush_remote)
118 } 108 }
119 { 109 {
120 move r9, zero /* asidcount */ 110 move r9, zero /* asidcount */
121 auli r20, r20, ha16(___hv_flush_remote) 111 auli r20, r20, ha16(hv_flush_remote)
122 } 112 }
123 113
124 jalr r20 114 jalr r20
125#endif
126 115
127 /* r33 is destination pointer, default to zero */ 116 /* r33 is destination pointer, default to zero */
128 117
@@ -175,8 +164,8 @@ STD_ENTRY(relocate_new_kernel)
175 move r0, r32 164 move r0, r32
176 moveli r1, 0 /* arg to hv_reexec is 64 bits */ 165 moveli r1, 0 /* arg to hv_reexec is 64 bits */
177 166
178 moveli r41, lo16(___hv_reexec) 167 moveli r41, lo16(hv_reexec)
179 auli r41, r41, ha16(___hv_reexec) 168 auli r41, r41, ha16(hv_reexec)
180 169
181 jalr r41 170 jalr r41
182 171
@@ -267,8 +256,8 @@ STD_ENTRY(relocate_new_kernel)
267 moveli r0, '\n' 256 moveli r0, '\n'
268 jalr r40 257 jalr r40
269.Lhalt: 258.Lhalt:
270 moveli r41, lo16(___hv_halt) 259 moveli r41, lo16(hv_halt)
271 auli r41, r41, ha16(___hv_halt) 260 auli r41, r41, ha16(hv_halt)
272 261
273 jalr r41 262 jalr r41
274 STD_ENDPROC(relocate_new_kernel) 263 STD_ENDPROC(relocate_new_kernel)
diff --git a/arch/tile/kernel/relocate_kernel_64.S b/arch/tile/kernel/relocate_kernel_64.S
index 1c09a4f5a4ea..d9d8cf6176e8 100644
--- a/arch/tile/kernel/relocate_kernel_64.S
+++ b/arch/tile/kernel/relocate_kernel_64.S
@@ -34,11 +34,11 @@ STD_ENTRY(relocate_new_kernel)
34 addi sp, sp, -8 34 addi sp, sp, -8
35 /* we now have a stack (whether we need one or not) */ 35 /* we now have a stack (whether we need one or not) */
36 36
37#ifdef RELOCATE_NEW_KERNEL_VERBOSE
37 moveli r40, hw2_last(hv_console_putc) 38 moveli r40, hw2_last(hv_console_putc)
38 shl16insli r40, r40, hw1(hv_console_putc) 39 shl16insli r40, r40, hw1(hv_console_putc)
39 shl16insli r40, r40, hw0(hv_console_putc) 40 shl16insli r40, r40, hw0(hv_console_putc)
40 41
41#ifdef RELOCATE_NEW_KERNEL_VERBOSE
42 moveli r0, 'r' 42 moveli r0, 'r'
43 jalr r40 43 jalr r40
44 44
@@ -78,7 +78,6 @@ STD_ENTRY(relocate_new_kernel)
78 move r30, sp 78 move r30, sp
79 addi sp, sp, -16 79 addi sp, sp, -16
80 80
81#if CHIP_HAS_CBOX_HOME_MAP()
82 /* 81 /*
83 * On TILE-GX, we need to flush all tiles' caches, since we may 82 * On TILE-GX, we need to flush all tiles' caches, since we may
84 * have been doing hash-for-home caching there. Note that we 83 * have been doing hash-for-home caching there. Note that we
@@ -116,7 +115,6 @@ STD_ENTRY(relocate_new_kernel)
116 shl16insli r20, r20, hw0(hv_flush_remote) 115 shl16insli r20, r20, hw0(hv_flush_remote)
117 116
118 jalr r20 117 jalr r20
119#endif
120 118
121 /* r33 is destination pointer, default to zero */ 119 /* r33 is destination pointer, default to zero */
122 120
@@ -176,10 +174,12 @@ STD_ENTRY(relocate_new_kernel)
176 174
177 /* we should not get here */ 175 /* we should not get here */
178 176
177#ifdef RELOCATE_NEW_KERNEL_VERBOSE
179 moveli r0, '?' 178 moveli r0, '?'
180 jalr r40 179 jalr r40
181 moveli r0, '\n' 180 moveli r0, '\n'
182 jalr r40 181 jalr r40
182#endif
183 183
184 j .Lhalt 184 j .Lhalt
185 185
@@ -237,7 +237,9 @@ STD_ENTRY(relocate_new_kernel)
237 j .Lloop 237 j .Lloop
238 238
239 239
240.Lerr: moveli r0, 'e' 240.Lerr:
241#ifdef RELOCATE_NEW_KERNEL_VERBOSE
242 moveli r0, 'e'
241 jalr r40 243 jalr r40
242 moveli r0, 'r' 244 moveli r0, 'r'
243 jalr r40 245 jalr r40
@@ -245,6 +247,7 @@ STD_ENTRY(relocate_new_kernel)
245 jalr r40 247 jalr r40
246 moveli r0, '\n' 248 moveli r0, '\n'
247 jalr r40 249 jalr r40
250#endif
248.Lhalt: 251.Lhalt:
249 moveli r41, hw2_last(hv_halt) 252 moveli r41, hw2_last(hv_halt)
250 shl16insli r41, r41, hw1(hv_halt) 253 shl16insli r41, r41, hw1(hv_halt)
diff --git a/arch/tile/kernel/setup.c b/arch/tile/kernel/setup.c
index eceb8344280f..4c34caea9dd3 100644
--- a/arch/tile/kernel/setup.c
+++ b/arch/tile/kernel/setup.c
@@ -154,6 +154,65 @@ static int __init setup_maxnodemem(char *str)
154} 154}
155early_param("maxnodemem", setup_maxnodemem); 155early_param("maxnodemem", setup_maxnodemem);
156 156
157struct memmap_entry {
158 u64 addr; /* start of memory segment */
159 u64 size; /* size of memory segment */
160};
161static struct memmap_entry memmap_map[64];
162static int memmap_nr;
163
164static void add_memmap_region(u64 addr, u64 size)
165{
166 if (memmap_nr >= ARRAY_SIZE(memmap_map)) {
167 pr_err("Ooops! Too many entries in the memory map!\n");
168 return;
169 }
170 memmap_map[memmap_nr].addr = addr;
171 memmap_map[memmap_nr].size = size;
172 memmap_nr++;
173}
174
175static int __init setup_memmap(char *p)
176{
177 char *oldp;
178 u64 start_at, mem_size;
179
180 if (!p)
181 return -EINVAL;
182
183 if (!strncmp(p, "exactmap", 8)) {
184 pr_err("\"memmap=exactmap\" not valid on tile\n");
185 return 0;
186 }
187
188 oldp = p;
189 mem_size = memparse(p, &p);
190 if (p == oldp)
191 return -EINVAL;
192
193 if (*p == '@') {
194 pr_err("\"memmap=nn@ss\" (force RAM) invalid on tile\n");
195 } else if (*p == '#') {
196 pr_err("\"memmap=nn#ss\" (force ACPI data) invalid on tile\n");
197 } else if (*p == '$') {
198 start_at = memparse(p+1, &p);
199 add_memmap_region(start_at, mem_size);
200 } else {
201 if (mem_size == 0)
202 return -EINVAL;
203 maxmem_pfn = (mem_size >> HPAGE_SHIFT) <<
204 (HPAGE_SHIFT - PAGE_SHIFT);
205 }
206 return *p == '\0' ? 0 : -EINVAL;
207}
208early_param("memmap", setup_memmap);
209
210static int __init setup_mem(char *str)
211{
212 return setup_maxmem(str);
213}
214early_param("mem", setup_mem); /* compatibility with x86 */
215
157static int __init setup_isolnodes(char *str) 216static int __init setup_isolnodes(char *str)
158{ 217{
159 char buf[MAX_NUMNODES * 5]; 218 char buf[MAX_NUMNODES * 5];
@@ -209,7 +268,7 @@ early_param("vmalloc", parse_vmalloc);
209/* 268/*
210 * Determine for each controller where its lowmem is mapped and how much of 269 * Determine for each controller where its lowmem is mapped and how much of
211 * it is mapped there. On controller zero, the first few megabytes are 270 * it is mapped there. On controller zero, the first few megabytes are
212 * already mapped in as code at MEM_SV_INTRPT, so in principle we could 271 * already mapped in as code at MEM_SV_START, so in principle we could
213 * start our data mappings higher up, but for now we don't bother, to avoid 272 * start our data mappings higher up, but for now we don't bother, to avoid
214 * additional confusion. 273 * additional confusion.
215 * 274 *
@@ -614,11 +673,12 @@ static void __init setup_bootmem_allocator_node(int i)
614 /* 673 /*
615 * Throw away any memory aliased by the PCI region. 674 * Throw away any memory aliased by the PCI region.
616 */ 675 */
617 if (pci_reserve_start_pfn < end && pci_reserve_end_pfn > start) 676 if (pci_reserve_start_pfn < end && pci_reserve_end_pfn > start) {
618 reserve_bootmem(PFN_PHYS(pci_reserve_start_pfn), 677 start = max(pci_reserve_start_pfn, start);
619 PFN_PHYS(pci_reserve_end_pfn - 678 end = min(pci_reserve_end_pfn, end);
620 pci_reserve_start_pfn), 679 reserve_bootmem(PFN_PHYS(start), PFN_PHYS(end - start),
621 BOOTMEM_EXCLUSIVE); 680 BOOTMEM_EXCLUSIVE);
681 }
622#endif 682#endif
623} 683}
624 684
@@ -628,6 +688,31 @@ static void __init setup_bootmem_allocator(void)
628 for (i = 0; i < MAX_NUMNODES; ++i) 688 for (i = 0; i < MAX_NUMNODES; ++i)
629 setup_bootmem_allocator_node(i); 689 setup_bootmem_allocator_node(i);
630 690
691 /* Reserve any memory excluded by "memmap" arguments. */
692 for (i = 0; i < memmap_nr; ++i) {
693 struct memmap_entry *m = &memmap_map[i];
694 reserve_bootmem(m->addr, m->size, 0);
695 }
696
697#ifdef CONFIG_BLK_DEV_INITRD
698 if (initrd_start) {
699 /* Make sure the initrd memory region is not modified. */
700 if (reserve_bootmem(initrd_start, initrd_end - initrd_start,
701 BOOTMEM_EXCLUSIVE)) {
702 pr_crit("The initrd memory region has been polluted. Disabling it.\n");
703 initrd_start = 0;
704 initrd_end = 0;
705 } else {
706 /*
707 * Translate initrd_start & initrd_end from PA to VA for
708 * future access.
709 */
710 initrd_start += PAGE_OFFSET;
711 initrd_end += PAGE_OFFSET;
712 }
713 }
714#endif
715
631#ifdef CONFIG_KEXEC 716#ifdef CONFIG_KEXEC
632 if (crashk_res.start != crashk_res.end) 717 if (crashk_res.start != crashk_res.end)
633 reserve_bootmem(crashk_res.start, resource_size(&crashk_res), 0); 718 reserve_bootmem(crashk_res.start, resource_size(&crashk_res), 0);
@@ -961,9 +1046,6 @@ void setup_cpu(int boot)
961 arch_local_irq_unmask(INT_DMATLB_MISS); 1046 arch_local_irq_unmask(INT_DMATLB_MISS);
962 arch_local_irq_unmask(INT_DMATLB_ACCESS); 1047 arch_local_irq_unmask(INT_DMATLB_ACCESS);
963#endif 1048#endif
964#if CHIP_HAS_SN_PROC()
965 arch_local_irq_unmask(INT_SNITLB_MISS);
966#endif
967#ifdef __tilegx__ 1049#ifdef __tilegx__
968 arch_local_irq_unmask(INT_SINGLE_STEP_K); 1050 arch_local_irq_unmask(INT_SINGLE_STEP_K);
969#endif 1051#endif
@@ -978,10 +1060,6 @@ void setup_cpu(int boot)
978 /* Static network is not restricted. */ 1060 /* Static network is not restricted. */
979 __insn_mtspr(SPR_MPL_SN_ACCESS_SET_0, 1); 1061 __insn_mtspr(SPR_MPL_SN_ACCESS_SET_0, 1);
980#endif 1062#endif
981#if CHIP_HAS_SN_PROC()
982 __insn_mtspr(SPR_MPL_SN_NOTIFY_SET_0, 1);
983 __insn_mtspr(SPR_MPL_SN_CPL_SET_0, 1);
984#endif
985 1063
986 /* 1064 /*
987 * Set the MPL for interrupt control 0 & 1 to the corresponding 1065 * Set the MPL for interrupt control 0 & 1 to the corresponding
@@ -1029,6 +1107,10 @@ static void __init load_hv_initrd(void)
1029 int fd, rc; 1107 int fd, rc;
1030 void *initrd; 1108 void *initrd;
1031 1109
1110 /* If initrd has already been set, skip initramfs file in hvfs. */
1111 if (initrd_start)
1112 return;
1113
1032 fd = hv_fs_findfile((HV_VirtAddr) initramfs_file); 1114 fd = hv_fs_findfile((HV_VirtAddr) initramfs_file);
1033 if (fd == HV_ENOENT) { 1115 if (fd == HV_ENOENT) {
1034 if (set_initramfs_file) { 1116 if (set_initramfs_file) {
@@ -1067,6 +1149,25 @@ void __init free_initrd_mem(unsigned long begin, unsigned long end)
1067 free_bootmem(__pa(begin), end - begin); 1149 free_bootmem(__pa(begin), end - begin);
1068} 1150}
1069 1151
1152static int __init setup_initrd(char *str)
1153{
1154 char *endp;
1155 unsigned long initrd_size;
1156
1157 initrd_size = str ? simple_strtoul(str, &endp, 0) : 0;
1158 if (initrd_size == 0 || *endp != '@')
1159 return -EINVAL;
1160
1161 initrd_start = simple_strtoul(endp+1, &endp, 0);
1162 if (initrd_start == 0)
1163 return -EINVAL;
1164
1165 initrd_end = initrd_start + initrd_size;
1166
1167 return 0;
1168}
1169early_param("initrd", setup_initrd);
1170
1070#else 1171#else
1071static inline void load_hv_initrd(void) {} 1172static inline void load_hv_initrd(void) {}
1072#endif /* CONFIG_BLK_DEV_INITRD */ 1173#endif /* CONFIG_BLK_DEV_INITRD */
@@ -1134,7 +1235,7 @@ static void __init validate_va(void)
1134#ifndef __tilegx__ /* FIXME: GX: probably some validation relevant here */ 1235#ifndef __tilegx__ /* FIXME: GX: probably some validation relevant here */
1135 /* 1236 /*
1136 * Similarly, make sure we're only using allowed VAs. 1237 * Similarly, make sure we're only using allowed VAs.
1137 * We assume we can contiguously use MEM_USER_INTRPT .. MEM_HV_INTRPT, 1238 * We assume we can contiguously use MEM_USER_INTRPT .. MEM_HV_START,
1138 * and 0 .. KERNEL_HIGH_VADDR. 1239 * and 0 .. KERNEL_HIGH_VADDR.
1139 * In addition, make sure we CAN'T use the end of memory, since 1240 * In addition, make sure we CAN'T use the end of memory, since
1140 * we use the last chunk of each pgd for the pgd_list. 1241 * we use the last chunk of each pgd for the pgd_list.
@@ -1149,7 +1250,7 @@ static void __init validate_va(void)
1149 if (range.size == 0) 1250 if (range.size == 0)
1150 break; 1251 break;
1151 if (range.start <= MEM_USER_INTRPT && 1252 if (range.start <= MEM_USER_INTRPT &&
1152 range.start + range.size >= MEM_HV_INTRPT) 1253 range.start + range.size >= MEM_HV_START)
1153 user_kernel_ok = 1; 1254 user_kernel_ok = 1;
1154 if (range.start == 0) 1255 if (range.start == 0)
1155 max_va = range.size; 1256 max_va = range.size;
@@ -1183,7 +1284,6 @@ static void __init validate_va(void)
1183struct cpumask __write_once cpu_lotar_map; 1284struct cpumask __write_once cpu_lotar_map;
1184EXPORT_SYMBOL(cpu_lotar_map); 1285EXPORT_SYMBOL(cpu_lotar_map);
1185 1286
1186#if CHIP_HAS_CBOX_HOME_MAP()
1187/* 1287/*
1188 * hash_for_home_map lists all the tiles that hash-for-home data 1288 * hash_for_home_map lists all the tiles that hash-for-home data
1189 * will be cached on. Note that this may includes tiles that are not 1289 * will be cached on. Note that this may includes tiles that are not
@@ -1193,7 +1293,6 @@ EXPORT_SYMBOL(cpu_lotar_map);
1193 */ 1293 */
1194struct cpumask hash_for_home_map; 1294struct cpumask hash_for_home_map;
1195EXPORT_SYMBOL(hash_for_home_map); 1295EXPORT_SYMBOL(hash_for_home_map);
1196#endif
1197 1296
1198/* 1297/*
1199 * cpu_cacheable_map lists all the cpus whose caches the hypervisor can 1298 * cpu_cacheable_map lists all the cpus whose caches the hypervisor can
@@ -1286,7 +1385,6 @@ static void __init setup_cpu_maps(void)
1286 cpu_lotar_map = *cpu_possible_mask; 1385 cpu_lotar_map = *cpu_possible_mask;
1287 } 1386 }
1288 1387
1289#if CHIP_HAS_CBOX_HOME_MAP()
1290 /* Retrieve set of CPUs used for hash-for-home caching */ 1388 /* Retrieve set of CPUs used for hash-for-home caching */
1291 rc = hv_inquire_tiles(HV_INQ_TILES_HFH_CACHE, 1389 rc = hv_inquire_tiles(HV_INQ_TILES_HFH_CACHE,
1292 (HV_VirtAddr) hash_for_home_map.bits, 1390 (HV_VirtAddr) hash_for_home_map.bits,
@@ -1294,9 +1392,6 @@ static void __init setup_cpu_maps(void)
1294 if (rc < 0) 1392 if (rc < 0)
1295 early_panic("hv_inquire_tiles(HFH_CACHE) failed: rc %d\n", rc); 1393 early_panic("hv_inquire_tiles(HFH_CACHE) failed: rc %d\n", rc);
1296 cpumask_or(&cpu_cacheable_map, cpu_possible_mask, &hash_for_home_map); 1394 cpumask_or(&cpu_cacheable_map, cpu_possible_mask, &hash_for_home_map);
1297#else
1298 cpu_cacheable_map = *cpu_possible_mask;
1299#endif
1300} 1395}
1301 1396
1302 1397
@@ -1492,7 +1587,7 @@ void __init setup_per_cpu_areas(void)
1492 1587
1493 /* Update the vmalloc mapping and page home. */ 1588 /* Update the vmalloc mapping and page home. */
1494 unsigned long addr = (unsigned long)ptr + i; 1589 unsigned long addr = (unsigned long)ptr + i;
1495 pte_t *ptep = virt_to_pte(NULL, addr); 1590 pte_t *ptep = virt_to_kpte(addr);
1496 pte_t pte = *ptep; 1591 pte_t pte = *ptep;
1497 BUG_ON(pfn != pte_pfn(pte)); 1592 BUG_ON(pfn != pte_pfn(pte));
1498 pte = hv_pte_set_mode(pte, HV_PTE_MODE_CACHE_TILE_L3); 1593 pte = hv_pte_set_mode(pte, HV_PTE_MODE_CACHE_TILE_L3);
@@ -1501,12 +1596,12 @@ void __init setup_per_cpu_areas(void)
1501 1596
1502 /* Update the lowmem mapping for consistency. */ 1597 /* Update the lowmem mapping for consistency. */
1503 lowmem_va = (unsigned long)pfn_to_kaddr(pfn); 1598 lowmem_va = (unsigned long)pfn_to_kaddr(pfn);
1504 ptep = virt_to_pte(NULL, lowmem_va); 1599 ptep = virt_to_kpte(lowmem_va);
1505 if (pte_huge(*ptep)) { 1600 if (pte_huge(*ptep)) {
1506 printk(KERN_DEBUG "early shatter of huge page" 1601 printk(KERN_DEBUG "early shatter of huge page"
1507 " at %#lx\n", lowmem_va); 1602 " at %#lx\n", lowmem_va);
1508 shatter_pmd((pmd_t *)ptep); 1603 shatter_pmd((pmd_t *)ptep);
1509 ptep = virt_to_pte(NULL, lowmem_va); 1604 ptep = virt_to_kpte(lowmem_va);
1510 BUG_ON(pte_huge(*ptep)); 1605 BUG_ON(pte_huge(*ptep));
1511 } 1606 }
1512 BUG_ON(pfn != pte_pfn(*ptep)); 1607 BUG_ON(pfn != pte_pfn(*ptep));
@@ -1548,6 +1643,8 @@ insert_non_bus_resource(void)
1548{ 1643{
1549 struct resource *res = 1644 struct resource *res =
1550 kzalloc(sizeof(struct resource), GFP_ATOMIC); 1645 kzalloc(sizeof(struct resource), GFP_ATOMIC);
1646 if (!res)
1647 return NULL;
1551 res->name = "Non-Bus Physical Address Space"; 1648 res->name = "Non-Bus Physical Address Space";
1552 res->start = (1ULL << 32); 1649 res->start = (1ULL << 32);
1553 res->end = -1LL; 1650 res->end = -1LL;
@@ -1561,11 +1658,13 @@ insert_non_bus_resource(void)
1561#endif 1658#endif
1562 1659
1563static struct resource* __init 1660static struct resource* __init
1564insert_ram_resource(u64 start_pfn, u64 end_pfn) 1661insert_ram_resource(u64 start_pfn, u64 end_pfn, bool reserved)
1565{ 1662{
1566 struct resource *res = 1663 struct resource *res =
1567 kzalloc(sizeof(struct resource), GFP_ATOMIC); 1664 kzalloc(sizeof(struct resource), GFP_ATOMIC);
1568 res->name = "System RAM"; 1665 if (!res)
1666 return NULL;
1667 res->name = reserved ? "Reserved" : "System RAM";
1569 res->start = start_pfn << PAGE_SHIFT; 1668 res->start = start_pfn << PAGE_SHIFT;
1570 res->end = (end_pfn << PAGE_SHIFT) - 1; 1669 res->end = (end_pfn << PAGE_SHIFT) - 1;
1571 res->flags = IORESOURCE_BUSY | IORESOURCE_MEM; 1670 res->flags = IORESOURCE_BUSY | IORESOURCE_MEM;
@@ -1585,7 +1684,7 @@ insert_ram_resource(u64 start_pfn, u64 end_pfn)
1585static int __init request_standard_resources(void) 1684static int __init request_standard_resources(void)
1586{ 1685{
1587 int i; 1686 int i;
1588 enum { CODE_DELTA = MEM_SV_INTRPT - PAGE_OFFSET }; 1687 enum { CODE_DELTA = MEM_SV_START - PAGE_OFFSET };
1589 1688
1590#if defined(CONFIG_PCI) && !defined(__tilegx__) 1689#if defined(CONFIG_PCI) && !defined(__tilegx__)
1591 insert_non_bus_resource(); 1690 insert_non_bus_resource();
@@ -1600,11 +1699,11 @@ static int __init request_standard_resources(void)
1600 end_pfn > pci_reserve_start_pfn) { 1699 end_pfn > pci_reserve_start_pfn) {
1601 if (end_pfn > pci_reserve_end_pfn) 1700 if (end_pfn > pci_reserve_end_pfn)
1602 insert_ram_resource(pci_reserve_end_pfn, 1701 insert_ram_resource(pci_reserve_end_pfn,
1603 end_pfn); 1702 end_pfn, 0);
1604 end_pfn = pci_reserve_start_pfn; 1703 end_pfn = pci_reserve_start_pfn;
1605 } 1704 }
1606#endif 1705#endif
1607 insert_ram_resource(start_pfn, end_pfn); 1706 insert_ram_resource(start_pfn, end_pfn, 0);
1608 } 1707 }
1609 1708
1610 code_resource.start = __pa(_text - CODE_DELTA); 1709 code_resource.start = __pa(_text - CODE_DELTA);
@@ -1615,6 +1714,13 @@ static int __init request_standard_resources(void)
1615 insert_resource(&iomem_resource, &code_resource); 1714 insert_resource(&iomem_resource, &code_resource);
1616 insert_resource(&iomem_resource, &data_resource); 1715 insert_resource(&iomem_resource, &data_resource);
1617 1716
1717 /* Mark any "memmap" regions busy for the resource manager. */
1718 for (i = 0; i < memmap_nr; ++i) {
1719 struct memmap_entry *m = &memmap_map[i];
1720 insert_ram_resource(PFN_DOWN(m->addr),
1721 PFN_UP(m->addr + m->size - 1), 1);
1722 }
1723
1618#ifdef CONFIG_KEXEC 1724#ifdef CONFIG_KEXEC
1619 insert_resource(&iomem_resource, &crashk_res); 1725 insert_resource(&iomem_resource, &crashk_res);
1620#endif 1726#endif
diff --git a/arch/tile/kernel/signal.c b/arch/tile/kernel/signal.c
index 9531845bf661..2d1dbf38a9ab 100644
--- a/arch/tile/kernel/signal.c
+++ b/arch/tile/kernel/signal.c
@@ -33,6 +33,7 @@
33#include <asm/ucontext.h> 33#include <asm/ucontext.h>
34#include <asm/sigframe.h> 34#include <asm/sigframe.h>
35#include <asm/syscalls.h> 35#include <asm/syscalls.h>
36#include <asm/vdso.h>
36#include <arch/interrupts.h> 37#include <arch/interrupts.h>
37 38
38#define DEBUG_SIG 0 39#define DEBUG_SIG 0
@@ -190,7 +191,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
190 if (err) 191 if (err)
191 goto give_sigsegv; 192 goto give_sigsegv;
192 193
193 restorer = VDSO_BASE; 194 restorer = VDSO_SYM(&__vdso_rt_sigreturn);
194 if (ka->sa.sa_flags & SA_RESTORER) 195 if (ka->sa.sa_flags & SA_RESTORER)
195 restorer = (unsigned long) ka->sa.sa_restorer; 196 restorer = (unsigned long) ka->sa.sa_restorer;
196 197
diff --git a/arch/tile/kernel/single_step.c b/arch/tile/kernel/single_step.c
index 27742e87e255..de07fa7d1315 100644
--- a/arch/tile/kernel/single_step.c
+++ b/arch/tile/kernel/single_step.c
@@ -12,41 +12,30 @@
12 * more details. 12 * more details.
13 * 13 *
14 * A code-rewriter that enables instruction single-stepping. 14 * A code-rewriter that enables instruction single-stepping.
15 * Derived from iLib's single-stepping code.
16 */ 15 */
17 16
18#ifndef __tilegx__ /* Hardware support for single step unavailable. */ 17#include <linux/smp.h>
19 18#include <linux/ptrace.h>
20/* These functions are only used on the TILE platform */
21#include <linux/slab.h> 19#include <linux/slab.h>
22#include <linux/thread_info.h> 20#include <linux/thread_info.h>
23#include <linux/uaccess.h> 21#include <linux/uaccess.h>
24#include <linux/mman.h> 22#include <linux/mman.h>
25#include <linux/types.h> 23#include <linux/types.h>
26#include <linux/err.h> 24#include <linux/err.h>
25#include <linux/prctl.h>
27#include <asm/cacheflush.h> 26#include <asm/cacheflush.h>
27#include <asm/traps.h>
28#include <asm/uaccess.h>
28#include <asm/unaligned.h> 29#include <asm/unaligned.h>
29#include <arch/abi.h> 30#include <arch/abi.h>
31#include <arch/spr_def.h>
30#include <arch/opcode.h> 32#include <arch/opcode.h>
31 33
32#define signExtend17(val) sign_extend((val), 17)
33#define TILE_X1_MASK (0xffffffffULL << 31)
34
35int unaligned_printk;
36 34
37static int __init setup_unaligned_printk(char *str) 35#ifndef __tilegx__ /* Hardware support for single step unavailable. */
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 36
49unsigned int unaligned_fixup_count; 37#define signExtend17(val) sign_extend((val), 17)
38#define TILE_X1_MASK (0xffffffffULL << 31)
50 39
51enum mem_op { 40enum mem_op {
52 MEMOP_NONE, 41 MEMOP_NONE,
@@ -56,12 +45,13 @@ enum mem_op {
56 MEMOP_STORE_POSTINCR 45 MEMOP_STORE_POSTINCR
57}; 46};
58 47
59static inline tile_bundle_bits set_BrOff_X1(tile_bundle_bits n, s32 offset) 48static inline tilepro_bundle_bits set_BrOff_X1(tilepro_bundle_bits n,
49 s32 offset)
60{ 50{
61 tile_bundle_bits result; 51 tilepro_bundle_bits result;
62 52
63 /* mask out the old offset */ 53 /* mask out the old offset */
64 tile_bundle_bits mask = create_BrOff_X1(-1); 54 tilepro_bundle_bits mask = create_BrOff_X1(-1);
65 result = n & (~mask); 55 result = n & (~mask);
66 56
67 /* or in the new offset */ 57 /* or in the new offset */
@@ -70,10 +60,11 @@ static inline tile_bundle_bits set_BrOff_X1(tile_bundle_bits n, s32 offset)
70 return result; 60 return result;
71} 61}
72 62
73static inline tile_bundle_bits move_X1(tile_bundle_bits n, int dest, int src) 63static inline tilepro_bundle_bits move_X1(tilepro_bundle_bits n, int dest,
64 int src)
74{ 65{
75 tile_bundle_bits result; 66 tilepro_bundle_bits result;
76 tile_bundle_bits op; 67 tilepro_bundle_bits op;
77 68
78 result = n & (~TILE_X1_MASK); 69 result = n & (~TILE_X1_MASK);
79 70
@@ -87,13 +78,13 @@ static inline tile_bundle_bits move_X1(tile_bundle_bits n, int dest, int src)
87 return result; 78 return result;
88} 79}
89 80
90static inline tile_bundle_bits nop_X1(tile_bundle_bits n) 81static inline tilepro_bundle_bits nop_X1(tilepro_bundle_bits n)
91{ 82{
92 return move_X1(n, TREG_ZERO, TREG_ZERO); 83 return move_X1(n, TREG_ZERO, TREG_ZERO);
93} 84}
94 85
95static inline tile_bundle_bits addi_X1( 86static inline tilepro_bundle_bits addi_X1(
96 tile_bundle_bits n, int dest, int src, int imm) 87 tilepro_bundle_bits n, int dest, int src, int imm)
97{ 88{
98 n &= ~TILE_X1_MASK; 89 n &= ~TILE_X1_MASK;
99 90
@@ -107,15 +98,26 @@ static inline tile_bundle_bits addi_X1(
107 return n; 98 return n;
108} 99}
109 100
110static tile_bundle_bits rewrite_load_store_unaligned( 101static tilepro_bundle_bits rewrite_load_store_unaligned(
111 struct single_step_state *state, 102 struct single_step_state *state,
112 tile_bundle_bits bundle, 103 tilepro_bundle_bits bundle,
113 struct pt_regs *regs, 104 struct pt_regs *regs,
114 enum mem_op mem_op, 105 enum mem_op mem_op,
115 int size, int sign_ext) 106 int size, int sign_ext)
116{ 107{
117 unsigned char __user *addr; 108 unsigned char __user *addr;
118 int val_reg, addr_reg, err, val; 109 int val_reg, addr_reg, err, val;
110 int align_ctl;
111
112 align_ctl = unaligned_fixup;
113 switch (task_thread_info(current)->align_ctl) {
114 case PR_UNALIGN_NOPRINT:
115 align_ctl = 1;
116 break;
117 case PR_UNALIGN_SIGBUS:
118 align_ctl = 0;
119 break;
120 }
119 121
120 /* Get address and value registers */ 122 /* Get address and value registers */
121 if (bundle & TILEPRO_BUNDLE_Y_ENCODING_MASK) { 123 if (bundle & TILEPRO_BUNDLE_Y_ENCODING_MASK) {
@@ -160,7 +162,7 @@ static tile_bundle_bits rewrite_load_store_unaligned(
160 * tilepro hardware would be doing, if it could provide us with the 162 * tilepro hardware would be doing, if it could provide us with the
161 * actual bad address in an SPR, which it doesn't. 163 * actual bad address in an SPR, which it doesn't.
162 */ 164 */
163 if (unaligned_fixup == 0) { 165 if (align_ctl == 0) {
164 siginfo_t info = { 166 siginfo_t info = {
165 .si_signo = SIGBUS, 167 .si_signo = SIGBUS,
166 .si_code = BUS_ADRALN, 168 .si_code = BUS_ADRALN,
@@ -209,14 +211,14 @@ static tile_bundle_bits rewrite_load_store_unaligned(
209 211
210 if (err) { 212 if (err) {
211 siginfo_t info = { 213 siginfo_t info = {
212 .si_signo = SIGSEGV, 214 .si_signo = SIGBUS,
213 .si_code = SEGV_MAPERR, 215 .si_code = BUS_ADRALN,
214 .si_addr = addr 216 .si_addr = addr
215 }; 217 };
216 trace_unhandled_signal("segfault", regs, 218 trace_unhandled_signal("bad address for unaligned fixup", regs,
217 (unsigned long)addr, SIGSEGV); 219 (unsigned long)addr, SIGBUS);
218 force_sig_info(info.si_signo, &info, current); 220 force_sig_info(info.si_signo, &info, current);
219 return (tile_bundle_bits) 0; 221 return (tilepro_bundle_bits) 0;
220 } 222 }
221 223
222 if (unaligned_printk || unaligned_fixup_count == 0) { 224 if (unaligned_printk || unaligned_fixup_count == 0) {
@@ -285,7 +287,7 @@ void single_step_execve(void)
285 ti->step_state = NULL; 287 ti->step_state = NULL;
286} 288}
287 289
288/** 290/*
289 * single_step_once() - entry point when single stepping has been triggered. 291 * single_step_once() - entry point when single stepping has been triggered.
290 * @regs: The machine register state 292 * @regs: The machine register state
291 * 293 *
@@ -304,20 +306,31 @@ void single_step_execve(void)
304 */ 306 */
305void single_step_once(struct pt_regs *regs) 307void single_step_once(struct pt_regs *regs)
306{ 308{
307 extern tile_bundle_bits __single_step_ill_insn; 309 extern tilepro_bundle_bits __single_step_ill_insn;
308 extern tile_bundle_bits __single_step_j_insn; 310 extern tilepro_bundle_bits __single_step_j_insn;
309 extern tile_bundle_bits __single_step_addli_insn; 311 extern tilepro_bundle_bits __single_step_addli_insn;
310 extern tile_bundle_bits __single_step_auli_insn; 312 extern tilepro_bundle_bits __single_step_auli_insn;
311 struct thread_info *info = (void *)current_thread_info(); 313 struct thread_info *info = (void *)current_thread_info();
312 struct single_step_state *state = info->step_state; 314 struct single_step_state *state = info->step_state;
313 int is_single_step = test_ti_thread_flag(info, TIF_SINGLESTEP); 315 int is_single_step = test_ti_thread_flag(info, TIF_SINGLESTEP);
314 tile_bundle_bits __user *buffer, *pc; 316 tilepro_bundle_bits __user *buffer, *pc;
315 tile_bundle_bits bundle; 317 tilepro_bundle_bits bundle;
316 int temp_reg; 318 int temp_reg;
317 int target_reg = TREG_LR; 319 int target_reg = TREG_LR;
318 int err; 320 int err;
319 enum mem_op mem_op = MEMOP_NONE; 321 enum mem_op mem_op = MEMOP_NONE;
320 int size = 0, sign_ext = 0; /* happy compiler */ 322 int size = 0, sign_ext = 0; /* happy compiler */
323 int align_ctl;
324
325 align_ctl = unaligned_fixup;
326 switch (task_thread_info(current)->align_ctl) {
327 case PR_UNALIGN_NOPRINT:
328 align_ctl = 1;
329 break;
330 case PR_UNALIGN_SIGBUS:
331 align_ctl = 0;
332 break;
333 }
321 334
322 asm( 335 asm(
323" .pushsection .rodata.single_step\n" 336" .pushsection .rodata.single_step\n"
@@ -390,7 +403,7 @@ void single_step_once(struct pt_regs *regs)
390 if (regs->faultnum == INT_SWINT_1) 403 if (regs->faultnum == INT_SWINT_1)
391 regs->pc -= 8; 404 regs->pc -= 8;
392 405
393 pc = (tile_bundle_bits __user *)(regs->pc); 406 pc = (tilepro_bundle_bits __user *)(regs->pc);
394 if (get_user(bundle, pc) != 0) { 407 if (get_user(bundle, pc) != 0) {
395 pr_err("Couldn't read instruction at %p trying to step\n", pc); 408 pr_err("Couldn't read instruction at %p trying to step\n", pc);
396 return; 409 return;
@@ -533,7 +546,6 @@ void single_step_once(struct pt_regs *regs)
533 } 546 }
534 break; 547 break;
535 548
536#if CHIP_HAS_WH64()
537 /* postincrement operations */ 549 /* postincrement operations */
538 case IMM_0_OPCODE_X1: 550 case IMM_0_OPCODE_X1:
539 switch (get_ImmOpcodeExtension_X1(bundle)) { 551 switch (get_ImmOpcodeExtension_X1(bundle)) {
@@ -568,7 +580,6 @@ void single_step_once(struct pt_regs *regs)
568 break; 580 break;
569 } 581 }
570 break; 582 break;
571#endif /* CHIP_HAS_WH64() */
572 } 583 }
573 584
574 if (state->update) { 585 if (state->update) {
@@ -627,9 +638,9 @@ void single_step_once(struct pt_regs *regs)
627 638
628 /* 639 /*
629 * Check if we need to rewrite an unaligned load/store. 640 * Check if we need to rewrite an unaligned load/store.
630 * Returning zero is a special value meaning we need to SIGSEGV. 641 * Returning zero is a special value meaning we generated a signal.
631 */ 642 */
632 if (mem_op != MEMOP_NONE && unaligned_fixup >= 0) { 643 if (mem_op != MEMOP_NONE && align_ctl >= 0) {
633 bundle = rewrite_load_store_unaligned(state, bundle, regs, 644 bundle = rewrite_load_store_unaligned(state, bundle, regs,
634 mem_op, size, sign_ext); 645 mem_op, size, sign_ext);
635 if (bundle == 0) 646 if (bundle == 0)
@@ -668,9 +679,9 @@ void single_step_once(struct pt_regs *regs)
668 } 679 }
669 680
670 /* End with a jump back to the next instruction */ 681 /* End with a jump back to the next instruction */
671 delta = ((regs->pc + TILE_BUNDLE_SIZE_IN_BYTES) - 682 delta = ((regs->pc + TILEPRO_BUNDLE_SIZE_IN_BYTES) -
672 (unsigned long)buffer) >> 683 (unsigned long)buffer) >>
673 TILE_LOG2_BUNDLE_ALIGNMENT_IN_BYTES; 684 TILEPRO_LOG2_BUNDLE_ALIGNMENT_IN_BYTES;
674 bundle = __single_step_j_insn; 685 bundle = __single_step_j_insn;
675 bundle |= create_JOffLong_X1(delta); 686 bundle |= create_JOffLong_X1(delta);
676 err |= __put_user(bundle, buffer++); 687 err |= __put_user(bundle, buffer++);
@@ -698,9 +709,6 @@ void single_step_once(struct pt_regs *regs)
698} 709}
699 710
700#else 711#else
701#include <linux/smp.h>
702#include <linux/ptrace.h>
703#include <arch/spr_def.h>
704 712
705static DEFINE_PER_CPU(unsigned long, ss_saved_pc); 713static DEFINE_PER_CPU(unsigned long, ss_saved_pc);
706 714
@@ -743,10 +751,10 @@ void gx_singlestep_handle(struct pt_regs *regs, int fault_num)
743 } else if ((*ss_pc != regs->pc) || 751 } else if ((*ss_pc != regs->pc) ||
744 (!(control & SPR_SINGLE_STEP_CONTROL_1__CANCELED_MASK))) { 752 (!(control & SPR_SINGLE_STEP_CONTROL_1__CANCELED_MASK))) {
745 753
746 ptrace_notify(SIGTRAP);
747 control |= SPR_SINGLE_STEP_CONTROL_1__CANCELED_MASK; 754 control |= SPR_SINGLE_STEP_CONTROL_1__CANCELED_MASK;
748 control |= SPR_SINGLE_STEP_CONTROL_1__INHIBIT_MASK; 755 control |= SPR_SINGLE_STEP_CONTROL_1__INHIBIT_MASK;
749 __insn_mtspr(SPR_SINGLE_STEP_CONTROL_K, control); 756 __insn_mtspr(SPR_SINGLE_STEP_CONTROL_K, control);
757 send_sigtrap(current, regs);
750 } 758 }
751} 759}
752 760
diff --git a/arch/tile/kernel/smp.c b/arch/tile/kernel/smp.c
index cbc73a8b8fe1..01e8ab29f43a 100644
--- a/arch/tile/kernel/smp.c
+++ b/arch/tile/kernel/smp.c
@@ -20,8 +20,13 @@
20#include <linux/irq.h> 20#include <linux/irq.h>
21#include <linux/module.h> 21#include <linux/module.h>
22#include <asm/cacheflush.h> 22#include <asm/cacheflush.h>
23#include <asm/homecache.h>
23 24
24HV_Topology smp_topology __write_once; 25/*
26 * We write to width and height with a single store in head_NN.S,
27 * so make the variable aligned to "long".
28 */
29HV_Topology smp_topology __write_once __aligned(sizeof(long));
25EXPORT_SYMBOL(smp_topology); 30EXPORT_SYMBOL(smp_topology);
26 31
27#if CHIP_HAS_IPI() 32#if CHIP_HAS_IPI()
@@ -100,8 +105,8 @@ static void smp_start_cpu_interrupt(void)
100/* Handler to stop the current cpu. */ 105/* Handler to stop the current cpu. */
101static void smp_stop_cpu_interrupt(void) 106static void smp_stop_cpu_interrupt(void)
102{ 107{
103 set_cpu_online(smp_processor_id(), 0);
104 arch_local_irq_disable_all(); 108 arch_local_irq_disable_all();
109 set_cpu_online(smp_processor_id(), 0);
105 for (;;) 110 for (;;)
106 asm("nap; nop"); 111 asm("nap; nop");
107} 112}
@@ -167,9 +172,16 @@ static void ipi_flush_icache_range(void *info)
167void flush_icache_range(unsigned long start, unsigned long end) 172void flush_icache_range(unsigned long start, unsigned long end)
168{ 173{
169 struct ipi_flush flush = { start, end }; 174 struct ipi_flush flush = { start, end };
170 preempt_disable(); 175
171 on_each_cpu(ipi_flush_icache_range, &flush, 1); 176 /* If invoked with irqs disabled, we can not issue IPIs. */
172 preempt_enable(); 177 if (irqs_disabled())
178 flush_remote(0, HV_FLUSH_EVICT_L1I, NULL, 0, 0, 0,
179 NULL, NULL, 0);
180 else {
181 preempt_disable();
182 on_each_cpu(ipi_flush_icache_range, &flush, 1);
183 preempt_enable();
184 }
173} 185}
174 186
175 187
diff --git a/arch/tile/kernel/smpboot.c b/arch/tile/kernel/smpboot.c
index a535655b7089..732e9d138661 100644
--- a/arch/tile/kernel/smpboot.c
+++ b/arch/tile/kernel/smpboot.c
@@ -142,13 +142,15 @@ static struct cpumask cpu_started;
142 */ 142 */
143static void start_secondary(void) 143static void start_secondary(void)
144{ 144{
145 int cpuid = smp_processor_id(); 145 int cpuid;
146
147 preempt_disable();
148
149 cpuid = smp_processor_id();
146 150
147 /* Set our thread pointer appropriately. */ 151 /* Set our thread pointer appropriately. */
148 set_my_cpu_offset(__per_cpu_offset[cpuid]); 152 set_my_cpu_offset(__per_cpu_offset[cpuid]);
149 153
150 preempt_disable();
151
152 /* 154 /*
153 * In large machines even this will slow us down, since we 155 * In large machines even this will slow us down, since we
154 * will be contending for for the printk spinlock. 156 * will be contending for for the printk spinlock.
diff --git a/arch/tile/kernel/stack.c b/arch/tile/kernel/stack.c
index af8dfc9665f6..362284af3afd 100644
--- a/arch/tile/kernel/stack.c
+++ b/arch/tile/kernel/stack.c
@@ -29,6 +29,7 @@
29#include <asm/switch_to.h> 29#include <asm/switch_to.h>
30#include <asm/sigframe.h> 30#include <asm/sigframe.h>
31#include <asm/stack.h> 31#include <asm/stack.h>
32#include <asm/vdso.h>
32#include <arch/abi.h> 33#include <arch/abi.h>
33#include <arch/interrupts.h> 34#include <arch/interrupts.h>
34 35
@@ -102,9 +103,8 @@ static struct pt_regs *valid_fault_handler(struct KBacktraceIterator* kbt)
102 p->sp >= sp) { 103 p->sp >= sp) {
103 if (kbt->verbose) 104 if (kbt->verbose)
104 pr_err(" <%s while in kernel mode>\n", fault); 105 pr_err(" <%s while in kernel mode>\n", fault);
105 } else if (EX1_PL(p->ex1) == USER_PL && 106 } else if (user_mode(p) &&
106 p->pc < PAGE_OFFSET && 107 p->sp < PAGE_OFFSET && p->sp != 0) {
107 p->sp < PAGE_OFFSET) {
108 if (kbt->verbose) 108 if (kbt->verbose)
109 pr_err(" <%s while in user mode>\n", fault); 109 pr_err(" <%s while in user mode>\n", fault);
110 } else if (kbt->verbose) { 110 } else if (kbt->verbose) {
@@ -120,7 +120,7 @@ static struct pt_regs *valid_fault_handler(struct KBacktraceIterator* kbt)
120/* Is the pc pointing to a sigreturn trampoline? */ 120/* Is the pc pointing to a sigreturn trampoline? */
121static int is_sigreturn(unsigned long pc) 121static int is_sigreturn(unsigned long pc)
122{ 122{
123 return (pc == VDSO_BASE); 123 return current->mm && (pc == VDSO_SYM(&__vdso_rt_sigreturn));
124} 124}
125 125
126/* Return a pt_regs pointer for a valid signal handler frame */ 126/* Return a pt_regs pointer for a valid signal handler frame */
@@ -129,7 +129,7 @@ static struct pt_regs *valid_sigframe(struct KBacktraceIterator* kbt,
129{ 129{
130 BacktraceIterator *b = &kbt->it; 130 BacktraceIterator *b = &kbt->it;
131 131
132 if (b->pc == VDSO_BASE && b->sp < PAGE_OFFSET && 132 if (is_sigreturn(b->pc) && b->sp < PAGE_OFFSET &&
133 b->sp % sizeof(long) == 0) { 133 b->sp % sizeof(long) == 0) {
134 int retval; 134 int retval;
135 pagefault_disable(); 135 pagefault_disable();
@@ -195,21 +195,21 @@ static int KBacktraceIterator_next_item_inclusive(
195 */ 195 */
196static void validate_stack(struct pt_regs *regs) 196static void validate_stack(struct pt_regs *regs)
197{ 197{
198 int cpu = smp_processor_id(); 198 int cpu = raw_smp_processor_id();
199 unsigned long ksp0 = get_current_ksp0(); 199 unsigned long ksp0 = get_current_ksp0();
200 unsigned long ksp0_base = ksp0 - THREAD_SIZE; 200 unsigned long ksp0_base = ksp0 & -THREAD_SIZE;
201 unsigned long sp = stack_pointer; 201 unsigned long sp = stack_pointer;
202 202
203 if (EX1_PL(regs->ex1) == KERNEL_PL && regs->sp >= ksp0) { 203 if (EX1_PL(regs->ex1) == KERNEL_PL && regs->sp >= ksp0) {
204 pr_err("WARNING: cpu %d: kernel stack page %#lx underrun!\n" 204 pr_err("WARNING: cpu %d: kernel stack %#lx..%#lx underrun!\n"
205 " sp %#lx (%#lx in caller), caller pc %#lx, lr %#lx\n", 205 " sp %#lx (%#lx in caller), caller pc %#lx, lr %#lx\n",
206 cpu, ksp0_base, sp, regs->sp, regs->pc, regs->lr); 206 cpu, ksp0_base, ksp0, sp, regs->sp, regs->pc, regs->lr);
207 } 207 }
208 208
209 else if (sp < ksp0_base + sizeof(struct thread_info)) { 209 else if (sp < ksp0_base + sizeof(struct thread_info)) {
210 pr_err("WARNING: cpu %d: kernel stack page %#lx overrun!\n" 210 pr_err("WARNING: cpu %d: kernel stack %#lx..%#lx overrun!\n"
211 " sp %#lx (%#lx in caller), caller pc %#lx, lr %#lx\n", 211 " sp %#lx (%#lx in caller), caller pc %#lx, lr %#lx\n",
212 cpu, ksp0_base, sp, regs->sp, regs->pc, regs->lr); 212 cpu, ksp0_base, ksp0, sp, regs->sp, regs->pc, regs->lr);
213 } 213 }
214} 214}
215 215
@@ -352,6 +352,26 @@ static void describe_addr(struct KBacktraceIterator *kbt,
352} 352}
353 353
354/* 354/*
355 * Avoid possible crash recursion during backtrace. If it happens, it
356 * makes it easy to lose the actual root cause of the failure, so we
357 * put a simple guard on all the backtrace loops.
358 */
359static bool start_backtrace(void)
360{
361 if (current->thread.in_backtrace) {
362 pr_err("Backtrace requested while in backtrace!\n");
363 return false;
364 }
365 current->thread.in_backtrace = true;
366 return true;
367}
368
369static void end_backtrace(void)
370{
371 current->thread.in_backtrace = false;
372}
373
374/*
355 * This method wraps the backtracer's more generic support. 375 * This method wraps the backtracer's more generic support.
356 * It is only invoked from the architecture-specific code; show_stack() 376 * It is only invoked from the architecture-specific code; show_stack()
357 * and dump_stack() (in entry.S) are architecture-independent entry points. 377 * and dump_stack() (in entry.S) are architecture-independent entry points.
@@ -361,6 +381,8 @@ void tile_show_stack(struct KBacktraceIterator *kbt, int headers)
361 int i; 381 int i;
362 int have_mmap_sem = 0; 382 int have_mmap_sem = 0;
363 383
384 if (!start_backtrace())
385 return;
364 if (headers) { 386 if (headers) {
365 /* 387 /*
366 * Add a blank line since if we are called from panic(), 388 * Add a blank line since if we are called from panic(),
@@ -371,7 +393,7 @@ void tile_show_stack(struct KBacktraceIterator *kbt, int headers)
371 pr_err("Starting stack dump of tid %d, pid %d (%s)" 393 pr_err("Starting stack dump of tid %d, pid %d (%s)"
372 " on cpu %d at cycle %lld\n", 394 " on cpu %d at cycle %lld\n",
373 kbt->task->pid, kbt->task->tgid, kbt->task->comm, 395 kbt->task->pid, kbt->task->tgid, kbt->task->comm,
374 smp_processor_id(), get_cycles()); 396 raw_smp_processor_id(), get_cycles());
375 } 397 }
376 kbt->verbose = 1; 398 kbt->verbose = 1;
377 i = 0; 399 i = 0;
@@ -402,6 +424,7 @@ void tile_show_stack(struct KBacktraceIterator *kbt, int headers)
402 pr_err("Stack dump complete\n"); 424 pr_err("Stack dump complete\n");
403 if (have_mmap_sem) 425 if (have_mmap_sem)
404 up_read(&kbt->task->mm->mmap_sem); 426 up_read(&kbt->task->mm->mmap_sem);
427 end_backtrace();
405} 428}
406EXPORT_SYMBOL(tile_show_stack); 429EXPORT_SYMBOL(tile_show_stack);
407 430
@@ -463,6 +486,8 @@ void save_stack_trace_tsk(struct task_struct *task, struct stack_trace *trace)
463 int skip = trace->skip; 486 int skip = trace->skip;
464 int i = 0; 487 int i = 0;
465 488
489 if (!start_backtrace())
490 goto done;
466 if (task == NULL || task == current) 491 if (task == NULL || task == current)
467 KBacktraceIterator_init_current(&kbt); 492 KBacktraceIterator_init_current(&kbt);
468 else 493 else
@@ -476,6 +501,8 @@ void save_stack_trace_tsk(struct task_struct *task, struct stack_trace *trace)
476 break; 501 break;
477 trace->entries[i++] = kbt.it.pc; 502 trace->entries[i++] = kbt.it.pc;
478 } 503 }
504 end_backtrace();
505done:
479 trace->nr_entries = i; 506 trace->nr_entries = i;
480} 507}
481EXPORT_SYMBOL(save_stack_trace_tsk); 508EXPORT_SYMBOL(save_stack_trace_tsk);
diff --git a/arch/tile/kernel/sys.c b/arch/tile/kernel/sys.c
index b881a7be24bd..38debe706061 100644
--- a/arch/tile/kernel/sys.c
+++ b/arch/tile/kernel/sys.c
@@ -38,8 +38,10 @@
38SYSCALL_DEFINE3(cacheflush, unsigned long, addr, unsigned long, len, 38SYSCALL_DEFINE3(cacheflush, unsigned long, addr, unsigned long, len,
39 unsigned long, flags) 39 unsigned long, flags)
40{ 40{
41 /* DCACHE is not particularly effective if not bound to one cpu. */
41 if (flags & DCACHE) 42 if (flags & DCACHE)
42 homecache_evict(cpumask_of(smp_processor_id())); 43 homecache_evict(cpumask_of(raw_smp_processor_id()));
44
43 if (flags & ICACHE) 45 if (flags & ICACHE)
44 flush_remote(0, HV_FLUSH_EVICT_L1I, mm_cpumask(current->mm), 46 flush_remote(0, HV_FLUSH_EVICT_L1I, mm_cpumask(current->mm),
45 0, 0, 0, NULL, NULL, 0); 47 0, 0, 0, NULL, NULL, 0);
diff --git a/arch/tile/kernel/sysfs.c b/arch/tile/kernel/sysfs.c
index e25b0a89c18f..a3ed12f8f83b 100644
--- a/arch/tile/kernel/sysfs.c
+++ b/arch/tile/kernel/sysfs.c
@@ -157,6 +157,67 @@ hvconfig_bin_read(struct file *filp, struct kobject *kobj,
157 return count; 157 return count;
158} 158}
159 159
160static ssize_t hv_stats_show(struct device *dev,
161 struct device_attribute *attr,
162 char *page)
163{
164 int cpu = dev->id;
165 long lotar = HV_XY_TO_LOTAR(cpu_x(cpu), cpu_y(cpu));
166
167 ssize_t n = hv_confstr(HV_CONFSTR_HV_STATS,
168 (unsigned long)page, PAGE_SIZE - 1,
169 lotar, 0);
170 n = n < 0 ? 0 : min(n, (ssize_t)PAGE_SIZE - 1);
171 page[n] = '\0';
172 return n;
173}
174
175static ssize_t hv_stats_store(struct device *dev,
176 struct device_attribute *attr,
177 const char *page,
178 size_t count)
179{
180 int cpu = dev->id;
181 long lotar = HV_XY_TO_LOTAR(cpu_x(cpu), cpu_y(cpu));
182
183 ssize_t n = hv_confstr(HV_CONFSTR_HV_STATS, 0, 0, lotar, 1);
184 return n < 0 ? n : count;
185}
186
187static DEVICE_ATTR(hv_stats, 0644, hv_stats_show, hv_stats_store);
188
189static int hv_stats_device_add(struct device *dev, struct subsys_interface *sif)
190{
191 int err, cpu = dev->id;
192
193 if (!cpu_online(cpu))
194 return 0;
195
196 err = sysfs_create_file(&dev->kobj, &dev_attr_hv_stats.attr);
197
198 return err;
199}
200
201static int hv_stats_device_remove(struct device *dev,
202 struct subsys_interface *sif)
203{
204 int cpu = dev->id;
205
206 if (!cpu_online(cpu))
207 return 0;
208
209 sysfs_remove_file(&dev->kobj, &dev_attr_hv_stats.attr);
210 return 0;
211}
212
213
214static struct subsys_interface hv_stats_interface = {
215 .name = "hv_stats",
216 .subsys = &cpu_subsys,
217 .add_dev = hv_stats_device_add,
218 .remove_dev = hv_stats_device_remove,
219};
220
160static int __init create_sysfs_entries(void) 221static int __init create_sysfs_entries(void)
161{ 222{
162 int err = 0; 223 int err = 0;
@@ -188,6 +249,21 @@ static int __init create_sysfs_entries(void)
188 err = sysfs_create_bin_file(hypervisor_kobj, &hvconfig_bin); 249 err = sysfs_create_bin_file(hypervisor_kobj, &hvconfig_bin);
189 } 250 }
190 251
252 if (!err) {
253 /*
254 * Don't bother adding the hv_stats files on each CPU if
255 * our hypervisor doesn't supply statistics.
256 */
257 int cpu = raw_smp_processor_id();
258 long lotar = HV_XY_TO_LOTAR(cpu_x(cpu), cpu_y(cpu));
259 char dummy;
260 ssize_t n = hv_confstr(HV_CONFSTR_HV_STATS,
261 (unsigned long) &dummy, 1,
262 lotar, 0);
263 if (n >= 0)
264 err = subsys_interface_register(&hv_stats_interface);
265 }
266
191 return err; 267 return err;
192} 268}
193subsys_initcall(create_sysfs_entries); 269subsys_initcall(create_sysfs_entries);
diff --git a/arch/tile/kernel/time.c b/arch/tile/kernel/time.c
index 7c353d8c2da9..5d10642db63e 100644
--- a/arch/tile/kernel/time.c
+++ b/arch/tile/kernel/time.c
@@ -23,8 +23,10 @@
23#include <linux/smp.h> 23#include <linux/smp.h>
24#include <linux/delay.h> 24#include <linux/delay.h>
25#include <linux/module.h> 25#include <linux/module.h>
26#include <linux/timekeeper_internal.h>
26#include <asm/irq_regs.h> 27#include <asm/irq_regs.h>
27#include <asm/traps.h> 28#include <asm/traps.h>
29#include <asm/vdso.h>
28#include <hv/hypervisor.h> 30#include <hv/hypervisor.h>
29#include <arch/interrupts.h> 31#include <arch/interrupts.h>
30#include <arch/spr_def.h> 32#include <arch/spr_def.h>
@@ -110,7 +112,6 @@ void __init time_init(void)
110 setup_tile_timer(); 112 setup_tile_timer();
111} 113}
112 114
113
114/* 115/*
115 * Define the tile timer clock event device. The timer is driven by 116 * Define the tile timer clock event device. The timer is driven by
116 * the TILE_TIMER_CONTROL register, which consists of a 31-bit down 117 * the TILE_TIMER_CONTROL register, which consists of a 31-bit down
@@ -237,3 +238,37 @@ cycles_t ns2cycles(unsigned long nsecs)
237 struct clock_event_device *dev = &__raw_get_cpu_var(tile_timer); 238 struct clock_event_device *dev = &__raw_get_cpu_var(tile_timer);
238 return ((u64)nsecs * dev->mult) >> dev->shift; 239 return ((u64)nsecs * dev->mult) >> dev->shift;
239} 240}
241
242void update_vsyscall_tz(void)
243{
244 /* Userspace gettimeofday will spin while this value is odd. */
245 ++vdso_data->tz_update_count;
246 smp_wmb();
247 vdso_data->tz_minuteswest = sys_tz.tz_minuteswest;
248 vdso_data->tz_dsttime = sys_tz.tz_dsttime;
249 smp_wmb();
250 ++vdso_data->tz_update_count;
251}
252
253void update_vsyscall(struct timekeeper *tk)
254{
255 struct timespec wall_time = tk_xtime(tk);
256 struct timespec *wtm = &tk->wall_to_monotonic;
257 struct clocksource *clock = tk->clock;
258
259 if (clock != &cycle_counter_cs)
260 return;
261
262 /* Userspace gettimeofday will spin while this value is odd. */
263 ++vdso_data->tb_update_count;
264 smp_wmb();
265 vdso_data->xtime_tod_stamp = clock->cycle_last;
266 vdso_data->xtime_clock_sec = wall_time.tv_sec;
267 vdso_data->xtime_clock_nsec = wall_time.tv_nsec;
268 vdso_data->wtom_clock_sec = wtm->tv_sec;
269 vdso_data->wtom_clock_nsec = wtm->tv_nsec;
270 vdso_data->mult = clock->mult;
271 vdso_data->shift = clock->shift;
272 smp_wmb();
273 ++vdso_data->tb_update_count;
274}
diff --git a/arch/tile/kernel/tlb.c b/arch/tile/kernel/tlb.c
index 3fd54d5bbd4c..f23b53515671 100644
--- a/arch/tile/kernel/tlb.c
+++ b/arch/tile/kernel/tlb.c
@@ -91,8 +91,14 @@ void flush_tlb_all(void)
91 } 91 }
92} 92}
93 93
94/*
95 * Callers need to flush the L1I themselves if necessary, e.g. for
96 * kernel module unload. Otherwise we assume callers are not using
97 * executable pgprot_t's. Using EVICT_L1I means that dataplane cpus
98 * will get an unnecessary interrupt otherwise.
99 */
94void flush_tlb_kernel_range(unsigned long start, unsigned long end) 100void flush_tlb_kernel_range(unsigned long start, unsigned long end)
95{ 101{
96 flush_remote(0, HV_FLUSH_EVICT_L1I, cpu_online_mask, 102 flush_remote(0, 0, NULL,
97 start, end - start, PAGE_SIZE, cpu_online_mask, NULL, 0); 103 start, end - start, PAGE_SIZE, cpu_online_mask, NULL, 0);
98} 104}
diff --git a/arch/tile/kernel/traps.c b/arch/tile/kernel/traps.c
index 5b19a23c8908..6b603d556ca6 100644
--- a/arch/tile/kernel/traps.c
+++ b/arch/tile/kernel/traps.c
@@ -15,6 +15,7 @@
15#include <linux/sched.h> 15#include <linux/sched.h>
16#include <linux/kernel.h> 16#include <linux/kernel.h>
17#include <linux/kprobes.h> 17#include <linux/kprobes.h>
18#include <linux/kdebug.h>
18#include <linux/module.h> 19#include <linux/module.h>
19#include <linux/reboot.h> 20#include <linux/reboot.h>
20#include <linux/uaccess.h> 21#include <linux/uaccess.h>
@@ -29,7 +30,7 @@
29 30
30void __init trap_init(void) 31void __init trap_init(void)
31{ 32{
32 /* Nothing needed here since we link code at .intrpt1 */ 33 /* Nothing needed here since we link code at .intrpt */
33} 34}
34 35
35int unaligned_fixup = 1; 36int unaligned_fixup = 1;
@@ -100,13 +101,7 @@ static int retry_gpv(unsigned int gpv_reason)
100 101
101#endif /* CHIP_HAS_TILE_DMA() */ 102#endif /* CHIP_HAS_TILE_DMA() */
102 103
103#ifdef __tilegx__ 104extern tile_bundle_bits bpt_code;
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 105
111asm(".pushsection .rodata.bpt_code,\"a\";" 106asm(".pushsection .rodata.bpt_code,\"a\";"
112 ".align 8;" 107 ".align 8;"
@@ -114,7 +109,7 @@ asm(".pushsection .rodata.bpt_code,\"a\";"
114 ".size bpt_code,.-bpt_code;" 109 ".size bpt_code,.-bpt_code;"
115 ".popsection"); 110 ".popsection");
116 111
117static int special_ill(bundle_bits bundle, int *sigp, int *codep) 112static int special_ill(tile_bundle_bits bundle, int *sigp, int *codep)
118{ 113{
119 int sig, code, maxcode; 114 int sig, code, maxcode;
120 115
@@ -214,24 +209,73 @@ static const char *const int_name[] = {
214#endif 209#endif
215}; 210};
216 211
212static int do_bpt(struct pt_regs *regs)
213{
214 unsigned long bundle, bcode, bpt;
215
216 bundle = *(unsigned long *)instruction_pointer(regs);
217
218 /*
219 * bpt shoule be { bpt; nop }, which is 0x286a44ae51485000ULL.
220 * we encode the unused least significant bits for other purpose.
221 */
222 bpt = bundle & ~((1ULL << 12) - 1);
223 if (bpt != TILE_BPT_BUNDLE)
224 return 0;
225
226 bcode = bundle & ((1ULL << 12) - 1);
227 /*
228 * notify the kprobe handlers, if instruction is likely to
229 * pertain to them.
230 */
231 switch (bcode) {
232 /* breakpoint_insn */
233 case 0:
234 notify_die(DIE_BREAK, "debug", regs, bundle,
235 INT_ILL, SIGTRAP);
236 break;
237 /* compiled_bpt */
238 case DIE_COMPILED_BPT:
239 notify_die(DIE_COMPILED_BPT, "debug", regs, bundle,
240 INT_ILL, SIGTRAP);
241 break;
242 /* breakpoint2_insn */
243 case DIE_SSTEPBP:
244 notify_die(DIE_SSTEPBP, "single_step", regs, bundle,
245 INT_ILL, SIGTRAP);
246 break;
247 default:
248 return 0;
249 }
250
251 return 1;
252}
253
217void __kprobes do_trap(struct pt_regs *regs, int fault_num, 254void __kprobes do_trap(struct pt_regs *regs, int fault_num,
218 unsigned long reason) 255 unsigned long reason)
219{ 256{
220 siginfo_t info = { 0 }; 257 siginfo_t info = { 0 };
221 int signo, code; 258 int signo, code;
222 unsigned long address = 0; 259 unsigned long address = 0;
223 bundle_bits instr; 260 tile_bundle_bits instr;
261 int is_kernel = !user_mode(regs);
262
263 /* Handle breakpoints, etc. */
264 if (is_kernel && fault_num == INT_ILL && do_bpt(regs))
265 return;
224 266
225 /* Re-enable interrupts. */ 267 /* Re-enable interrupts, if they were previously enabled. */
226 local_irq_enable(); 268 if (!(regs->flags & PT_FLAGS_DISABLE_IRQ))
269 local_irq_enable();
227 270
228 /* 271 /*
229 * If it hits in kernel mode and we can't fix it up, just exit the 272 * If it hits in kernel mode and we can't fix it up, just exit the
230 * current process and hope for the best. 273 * current process and hope for the best.
231 */ 274 */
232 if (!user_mode(regs)) { 275 if (is_kernel) {
233 const char *name; 276 const char *name;
234 if (fixup_exception(regs)) /* only UNALIGN_DATA in practice */ 277 char buf[100];
278 if (fixup_exception(regs)) /* ILL_TRANS or UNALIGN_DATA */
235 return; 279 return;
236 if (fault_num >= 0 && 280 if (fault_num >= 0 &&
237 fault_num < sizeof(int_name)/sizeof(int_name[0]) && 281 fault_num < sizeof(int_name)/sizeof(int_name[0]) &&
@@ -239,10 +283,16 @@ void __kprobes do_trap(struct pt_regs *regs, int fault_num,
239 name = int_name[fault_num]; 283 name = int_name[fault_num];
240 else 284 else
241 name = "Unknown interrupt"; 285 name = "Unknown interrupt";
242 pr_alert("Kernel took bad trap %d (%s) at PC %#lx\n",
243 fault_num, name, regs->pc);
244 if (fault_num == INT_GPV) 286 if (fault_num == INT_GPV)
245 pr_alert("GPV_REASON is %#lx\n", reason); 287 snprintf(buf, sizeof(buf), "; GPV_REASON %#lx", reason);
288#ifdef __tilegx__
289 else if (fault_num == INT_ILL_TRANS)
290 snprintf(buf, sizeof(buf), "; address %#lx", reason);
291#endif
292 else
293 buf[0] = '\0';
294 pr_alert("Kernel took bad trap %d (%s) at PC %#lx%s\n",
295 fault_num, name, regs->pc, buf);
246 show_regs(regs); 296 show_regs(regs);
247 do_exit(SIGKILL); /* FIXME: implement i386 die() */ 297 do_exit(SIGKILL); /* FIXME: implement i386 die() */
248 return; 298 return;
@@ -324,11 +374,8 @@ void __kprobes do_trap(struct pt_regs *regs, int fault_num,
324 fill_ra_stack(); 374 fill_ra_stack();
325 375
326 signo = SIGSEGV; 376 signo = SIGSEGV;
377 address = reason;
327 code = SEGV_MAPERR; 378 code = SEGV_MAPERR;
328 if (reason & SPR_ILL_TRANS_REASON__I_STREAM_VA_RMASK)
329 address = regs->pc;
330 else
331 address = 0; /* FIXME: GX: single-step for address */
332 break; 379 break;
333 } 380 }
334#endif 381#endif
diff --git a/arch/tile/kernel/unaligned.c b/arch/tile/kernel/unaligned.c
new file mode 100644
index 000000000000..b425fb6a480d
--- /dev/null
+++ b/arch/tile/kernel/unaligned.c
@@ -0,0 +1,1609 @@
1/*
2 * Copyright 2013 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 handles unaligned exception.
15 */
16
17#include <linux/smp.h>
18#include <linux/ptrace.h>
19#include <linux/slab.h>
20#include <linux/thread_info.h>
21#include <linux/uaccess.h>
22#include <linux/mman.h>
23#include <linux/types.h>
24#include <linux/err.h>
25#include <linux/module.h>
26#include <linux/compat.h>
27#include <linux/prctl.h>
28#include <asm/cacheflush.h>
29#include <asm/traps.h>
30#include <asm/uaccess.h>
31#include <asm/unaligned.h>
32#include <arch/abi.h>
33#include <arch/spr_def.h>
34#include <arch/opcode.h>
35
36
37/*
38 * This file handles unaligned exception for tile-Gx. The tilepro's unaligned
39 * exception is supported out of single_step.c
40 */
41
42int unaligned_printk;
43
44static int __init setup_unaligned_printk(char *str)
45{
46 long val;
47 if (kstrtol(str, 0, &val) != 0)
48 return 0;
49 unaligned_printk = val;
50 pr_info("Printk for each unaligned data accesses is %s\n",
51 unaligned_printk ? "enabled" : "disabled");
52 return 1;
53}
54__setup("unaligned_printk=", setup_unaligned_printk);
55
56unsigned int unaligned_fixup_count;
57
58#ifdef __tilegx__
59
60/*
61 * Unalign data jit fixup code fragement. Reserved space is 128 bytes.
62 * The 1st 64-bit word saves fault PC address, 2nd word is the fault
63 * instruction bundle followed by 14 JIT bundles.
64 */
65
66struct unaligned_jit_fragment {
67 unsigned long pc;
68 tilegx_bundle_bits bundle;
69 tilegx_bundle_bits insn[14];
70};
71
72/*
73 * Check if a nop or fnop at bundle's pipeline X0.
74 */
75
76static bool is_bundle_x0_nop(tilegx_bundle_bits bundle)
77{
78 return (((get_UnaryOpcodeExtension_X0(bundle) ==
79 NOP_UNARY_OPCODE_X0) &&
80 (get_RRROpcodeExtension_X0(bundle) ==
81 UNARY_RRR_0_OPCODE_X0) &&
82 (get_Opcode_X0(bundle) ==
83 RRR_0_OPCODE_X0)) ||
84 ((get_UnaryOpcodeExtension_X0(bundle) ==
85 FNOP_UNARY_OPCODE_X0) &&
86 (get_RRROpcodeExtension_X0(bundle) ==
87 UNARY_RRR_0_OPCODE_X0) &&
88 (get_Opcode_X0(bundle) ==
89 RRR_0_OPCODE_X0)));
90}
91
92/*
93 * Check if nop or fnop at bundle's pipeline X1.
94 */
95
96static bool is_bundle_x1_nop(tilegx_bundle_bits bundle)
97{
98 return (((get_UnaryOpcodeExtension_X1(bundle) ==
99 NOP_UNARY_OPCODE_X1) &&
100 (get_RRROpcodeExtension_X1(bundle) ==
101 UNARY_RRR_0_OPCODE_X1) &&
102 (get_Opcode_X1(bundle) ==
103 RRR_0_OPCODE_X1)) ||
104 ((get_UnaryOpcodeExtension_X1(bundle) ==
105 FNOP_UNARY_OPCODE_X1) &&
106 (get_RRROpcodeExtension_X1(bundle) ==
107 UNARY_RRR_0_OPCODE_X1) &&
108 (get_Opcode_X1(bundle) ==
109 RRR_0_OPCODE_X1)));
110}
111
112/*
113 * Check if nop or fnop at bundle's Y0 pipeline.
114 */
115
116static bool is_bundle_y0_nop(tilegx_bundle_bits bundle)
117{
118 return (((get_UnaryOpcodeExtension_Y0(bundle) ==
119 NOP_UNARY_OPCODE_Y0) &&
120 (get_RRROpcodeExtension_Y0(bundle) ==
121 UNARY_RRR_1_OPCODE_Y0) &&
122 (get_Opcode_Y0(bundle) ==
123 RRR_1_OPCODE_Y0)) ||
124 ((get_UnaryOpcodeExtension_Y0(bundle) ==
125 FNOP_UNARY_OPCODE_Y0) &&
126 (get_RRROpcodeExtension_Y0(bundle) ==
127 UNARY_RRR_1_OPCODE_Y0) &&
128 (get_Opcode_Y0(bundle) ==
129 RRR_1_OPCODE_Y0)));
130}
131
132/*
133 * Check if nop or fnop at bundle's pipeline Y1.
134 */
135
136static bool is_bundle_y1_nop(tilegx_bundle_bits bundle)
137{
138 return (((get_UnaryOpcodeExtension_Y1(bundle) ==
139 NOP_UNARY_OPCODE_Y1) &&
140 (get_RRROpcodeExtension_Y1(bundle) ==
141 UNARY_RRR_1_OPCODE_Y1) &&
142 (get_Opcode_Y1(bundle) ==
143 RRR_1_OPCODE_Y1)) ||
144 ((get_UnaryOpcodeExtension_Y1(bundle) ==
145 FNOP_UNARY_OPCODE_Y1) &&
146 (get_RRROpcodeExtension_Y1(bundle) ==
147 UNARY_RRR_1_OPCODE_Y1) &&
148 (get_Opcode_Y1(bundle) ==
149 RRR_1_OPCODE_Y1)));
150}
151
152/*
153 * Test if a bundle's y0 and y1 pipelines are both nop or fnop.
154 */
155
156static bool is_y0_y1_nop(tilegx_bundle_bits bundle)
157{
158 return is_bundle_y0_nop(bundle) && is_bundle_y1_nop(bundle);
159}
160
161/*
162 * Test if a bundle's x0 and x1 pipelines are both nop or fnop.
163 */
164
165static bool is_x0_x1_nop(tilegx_bundle_bits bundle)
166{
167 return is_bundle_x0_nop(bundle) && is_bundle_x1_nop(bundle);
168}
169
170/*
171 * Find the destination, source registers of fault unalign access instruction
172 * at X1 or Y2. Also, allocate up to 3 scratch registers clob1, clob2 and
173 * clob3, which are guaranteed different from any register used in the fault
174 * bundle. r_alias is used to return if the other instructions other than the
175 * unalign load/store shares same register with ra, rb and rd.
176 */
177
178static void find_regs(tilegx_bundle_bits bundle, uint64_t *rd, uint64_t *ra,
179 uint64_t *rb, uint64_t *clob1, uint64_t *clob2,
180 uint64_t *clob3, bool *r_alias)
181{
182 int i;
183 uint64_t reg;
184 uint64_t reg_map = 0, alias_reg_map = 0, map;
185 bool alias;
186
187 *ra = -1;
188 *rb = -1;
189
190 if (rd)
191 *rd = -1;
192
193 *clob1 = -1;
194 *clob2 = -1;
195 *clob3 = -1;
196 alias = false;
197
198 /*
199 * Parse fault bundle, find potential used registers and mark
200 * corresponding bits in reg_map and alias_map. These 2 bit maps
201 * are used to find the scratch registers and determine if there
202 * is register alais.
203 */
204 if (bundle & TILEGX_BUNDLE_MODE_MASK) { /* Y Mode Bundle. */
205
206 reg = get_SrcA_Y2(bundle);
207 reg_map |= 1ULL << reg;
208 *ra = reg;
209 reg = get_SrcBDest_Y2(bundle);
210 reg_map |= 1ULL << reg;
211
212 if (rd) {
213 /* Load. */
214 *rd = reg;
215 alias_reg_map = (1ULL << *rd) | (1ULL << *ra);
216 } else {
217 /* Store. */
218 *rb = reg;
219 alias_reg_map = (1ULL << *ra) | (1ULL << *rb);
220 }
221
222 if (!is_bundle_y1_nop(bundle)) {
223 reg = get_SrcA_Y1(bundle);
224 reg_map |= (1ULL << reg);
225 map = (1ULL << reg);
226
227 reg = get_SrcB_Y1(bundle);
228 reg_map |= (1ULL << reg);
229 map |= (1ULL << reg);
230
231 reg = get_Dest_Y1(bundle);
232 reg_map |= (1ULL << reg);
233 map |= (1ULL << reg);
234
235 if (map & alias_reg_map)
236 alias = true;
237 }
238
239 if (!is_bundle_y0_nop(bundle)) {
240 reg = get_SrcA_Y0(bundle);
241 reg_map |= (1ULL << reg);
242 map = (1ULL << reg);
243
244 reg = get_SrcB_Y0(bundle);
245 reg_map |= (1ULL << reg);
246 map |= (1ULL << reg);
247
248 reg = get_Dest_Y0(bundle);
249 reg_map |= (1ULL << reg);
250 map |= (1ULL << reg);
251
252 if (map & alias_reg_map)
253 alias = true;
254 }
255 } else { /* X Mode Bundle. */
256
257 reg = get_SrcA_X1(bundle);
258 reg_map |= (1ULL << reg);
259 *ra = reg;
260 if (rd) {
261 /* Load. */
262 reg = get_Dest_X1(bundle);
263 reg_map |= (1ULL << reg);
264 *rd = reg;
265 alias_reg_map = (1ULL << *rd) | (1ULL << *ra);
266 } else {
267 /* Store. */
268 reg = get_SrcB_X1(bundle);
269 reg_map |= (1ULL << reg);
270 *rb = reg;
271 alias_reg_map = (1ULL << *ra) | (1ULL << *rb);
272 }
273
274 if (!is_bundle_x0_nop(bundle)) {
275 reg = get_SrcA_X0(bundle);
276 reg_map |= (1ULL << reg);
277 map = (1ULL << reg);
278
279 reg = get_SrcB_X0(bundle);
280 reg_map |= (1ULL << reg);
281 map |= (1ULL << reg);
282
283 reg = get_Dest_X0(bundle);
284 reg_map |= (1ULL << reg);
285 map |= (1ULL << reg);
286
287 if (map & alias_reg_map)
288 alias = true;
289 }
290 }
291
292 /*
293 * "alias" indicates if the unalign access registers have collision
294 * with others in the same bundle. We jsut simply test all register
295 * operands case (RRR), ignored the case with immidate. If a bundle
296 * has no register alias, we may do fixup in a simple or fast manner.
297 * So if an immidata field happens to hit with a register, we may end
298 * up fall back to the generic handling.
299 */
300
301 *r_alias = alias;
302
303 /* Flip bits on reg_map. */
304 reg_map ^= -1ULL;
305
306 /* Scan reg_map lower 54(TREG_SP) bits to find 3 set bits. */
307 for (i = 0; i < TREG_SP; i++) {
308 if (reg_map & (0x1ULL << i)) {
309 if (*clob1 == -1) {
310 *clob1 = i;
311 } else if (*clob2 == -1) {
312 *clob2 = i;
313 } else if (*clob3 == -1) {
314 *clob3 = i;
315 return;
316 }
317 }
318 }
319}
320
321/*
322 * Sanity check for register ra, rb, rd, clob1/2/3. Return true if any of them
323 * is unexpected.
324 */
325
326static bool check_regs(uint64_t rd, uint64_t ra, uint64_t rb,
327 uint64_t clob1, uint64_t clob2, uint64_t clob3)
328{
329 bool unexpected = false;
330 if ((ra >= 56) && (ra != TREG_ZERO))
331 unexpected = true;
332
333 if ((clob1 >= 56) || (clob2 >= 56) || (clob3 >= 56))
334 unexpected = true;
335
336 if (rd != -1) {
337 if ((rd >= 56) && (rd != TREG_ZERO))
338 unexpected = true;
339 } else {
340 if ((rb >= 56) && (rb != TREG_ZERO))
341 unexpected = true;
342 }
343 return unexpected;
344}
345
346
347#define GX_INSN_X0_MASK ((1ULL << 31) - 1)
348#define GX_INSN_X1_MASK (((1ULL << 31) - 1) << 31)
349#define GX_INSN_Y0_MASK ((0xFULL << 27) | (0xFFFFFULL))
350#define GX_INSN_Y1_MASK (GX_INSN_Y0_MASK << 31)
351#define GX_INSN_Y2_MASK ((0x7FULL << 51) | (0x7FULL << 20))
352
353#ifdef __LITTLE_ENDIAN
354#define GX_INSN_BSWAP(_bundle_) (_bundle_)
355#else
356#define GX_INSN_BSWAP(_bundle_) swab64(_bundle_)
357#endif /* __LITTLE_ENDIAN */
358
359/*
360 * __JIT_CODE(.) creates template bundles in .rodata.unalign_data section.
361 * The corresponding static function jix_x#_###(.) generates partial or
362 * whole bundle based on the template and given arguments.
363 */
364
365#define __JIT_CODE(_X_) \
366 asm (".pushsection .rodata.unalign_data, \"a\"\n" \
367 _X_"\n" \
368 ".popsection\n")
369
370__JIT_CODE("__unalign_jit_x1_mtspr: {mtspr 0, r0}");
371static tilegx_bundle_bits jit_x1_mtspr(int spr, int reg)
372{
373 extern tilegx_bundle_bits __unalign_jit_x1_mtspr;
374 return (GX_INSN_BSWAP(__unalign_jit_x1_mtspr) & GX_INSN_X1_MASK) |
375 create_MT_Imm14_X1(spr) | create_SrcA_X1(reg);
376}
377
378__JIT_CODE("__unalign_jit_x1_mfspr: {mfspr r0, 0}");
379static tilegx_bundle_bits jit_x1_mfspr(int reg, int spr)
380{
381 extern tilegx_bundle_bits __unalign_jit_x1_mfspr;
382 return (GX_INSN_BSWAP(__unalign_jit_x1_mfspr) & GX_INSN_X1_MASK) |
383 create_MF_Imm14_X1(spr) | create_Dest_X1(reg);
384}
385
386__JIT_CODE("__unalign_jit_x0_addi: {addi r0, r0, 0; iret}");
387static tilegx_bundle_bits jit_x0_addi(int rd, int ra, int imm8)
388{
389 extern tilegx_bundle_bits __unalign_jit_x0_addi;
390 return (GX_INSN_BSWAP(__unalign_jit_x0_addi) & GX_INSN_X0_MASK) |
391 create_Dest_X0(rd) | create_SrcA_X0(ra) |
392 create_Imm8_X0(imm8);
393}
394
395__JIT_CODE("__unalign_jit_x1_ldna: {ldna r0, r0}");
396static tilegx_bundle_bits jit_x1_ldna(int rd, int ra)
397{
398 extern tilegx_bundle_bits __unalign_jit_x1_ldna;
399 return (GX_INSN_BSWAP(__unalign_jit_x1_ldna) & GX_INSN_X1_MASK) |
400 create_Dest_X1(rd) | create_SrcA_X1(ra);
401}
402
403__JIT_CODE("__unalign_jit_x0_dblalign: {dblalign r0, r0 ,r0}");
404static tilegx_bundle_bits jit_x0_dblalign(int rd, int ra, int rb)
405{
406 extern tilegx_bundle_bits __unalign_jit_x0_dblalign;
407 return (GX_INSN_BSWAP(__unalign_jit_x0_dblalign) & GX_INSN_X0_MASK) |
408 create_Dest_X0(rd) | create_SrcA_X0(ra) |
409 create_SrcB_X0(rb);
410}
411
412__JIT_CODE("__unalign_jit_x1_iret: {iret}");
413static tilegx_bundle_bits jit_x1_iret(void)
414{
415 extern tilegx_bundle_bits __unalign_jit_x1_iret;
416 return GX_INSN_BSWAP(__unalign_jit_x1_iret) & GX_INSN_X1_MASK;
417}
418
419__JIT_CODE("__unalign_jit_x01_fnop: {fnop;fnop}");
420static tilegx_bundle_bits jit_x0_fnop(void)
421{
422 extern tilegx_bundle_bits __unalign_jit_x01_fnop;
423 return GX_INSN_BSWAP(__unalign_jit_x01_fnop) & GX_INSN_X0_MASK;
424}
425
426static tilegx_bundle_bits jit_x1_fnop(void)
427{
428 extern tilegx_bundle_bits __unalign_jit_x01_fnop;
429 return GX_INSN_BSWAP(__unalign_jit_x01_fnop) & GX_INSN_X1_MASK;
430}
431
432__JIT_CODE("__unalign_jit_y2_dummy: {fnop; fnop; ld zero, sp}");
433static tilegx_bundle_bits jit_y2_dummy(void)
434{
435 extern tilegx_bundle_bits __unalign_jit_y2_dummy;
436 return GX_INSN_BSWAP(__unalign_jit_y2_dummy) & GX_INSN_Y2_MASK;
437}
438
439static tilegx_bundle_bits jit_y1_fnop(void)
440{
441 extern tilegx_bundle_bits __unalign_jit_y2_dummy;
442 return GX_INSN_BSWAP(__unalign_jit_y2_dummy) & GX_INSN_Y1_MASK;
443}
444
445__JIT_CODE("__unalign_jit_x1_st1_add: {st1_add r1, r0, 0}");
446static tilegx_bundle_bits jit_x1_st1_add(int ra, int rb, int imm8)
447{
448 extern tilegx_bundle_bits __unalign_jit_x1_st1_add;
449 return (GX_INSN_BSWAP(__unalign_jit_x1_st1_add) &
450 (~create_SrcA_X1(-1)) &
451 GX_INSN_X1_MASK) | create_SrcA_X1(ra) |
452 create_SrcB_X1(rb) | create_Dest_Imm8_X1(imm8);
453}
454
455__JIT_CODE("__unalign_jit_x1_st: {crc32_8 r1, r0, r0; st r0, r0}");
456static tilegx_bundle_bits jit_x1_st(int ra, int rb)
457{
458 extern tilegx_bundle_bits __unalign_jit_x1_st;
459 return (GX_INSN_BSWAP(__unalign_jit_x1_st) & GX_INSN_X1_MASK) |
460 create_SrcA_X1(ra) | create_SrcB_X1(rb);
461}
462
463__JIT_CODE("__unalign_jit_x1_st_add: {st_add r1, r0, 0}");
464static tilegx_bundle_bits jit_x1_st_add(int ra, int rb, int imm8)
465{
466 extern tilegx_bundle_bits __unalign_jit_x1_st_add;
467 return (GX_INSN_BSWAP(__unalign_jit_x1_st_add) &
468 (~create_SrcA_X1(-1)) &
469 GX_INSN_X1_MASK) | create_SrcA_X1(ra) |
470 create_SrcB_X1(rb) | create_Dest_Imm8_X1(imm8);
471}
472
473__JIT_CODE("__unalign_jit_x1_ld: {crc32_8 r1, r0, r0; ld r0, r0}");
474static tilegx_bundle_bits jit_x1_ld(int rd, int ra)
475{
476 extern tilegx_bundle_bits __unalign_jit_x1_ld;
477 return (GX_INSN_BSWAP(__unalign_jit_x1_ld) & GX_INSN_X1_MASK) |
478 create_Dest_X1(rd) | create_SrcA_X1(ra);
479}
480
481__JIT_CODE("__unalign_jit_x1_ld_add: {ld_add r1, r0, 0}");
482static tilegx_bundle_bits jit_x1_ld_add(int rd, int ra, int imm8)
483{
484 extern tilegx_bundle_bits __unalign_jit_x1_ld_add;
485 return (GX_INSN_BSWAP(__unalign_jit_x1_ld_add) &
486 (~create_Dest_X1(-1)) &
487 GX_INSN_X1_MASK) | create_Dest_X1(rd) |
488 create_SrcA_X1(ra) | create_Imm8_X1(imm8);
489}
490
491__JIT_CODE("__unalign_jit_x0_bfexts: {bfexts r0, r0, 0, 0}");
492static tilegx_bundle_bits jit_x0_bfexts(int rd, int ra, int bfs, int bfe)
493{
494 extern tilegx_bundle_bits __unalign_jit_x0_bfexts;
495 return (GX_INSN_BSWAP(__unalign_jit_x0_bfexts) &
496 GX_INSN_X0_MASK) |
497 create_Dest_X0(rd) | create_SrcA_X0(ra) |
498 create_BFStart_X0(bfs) | create_BFEnd_X0(bfe);
499}
500
501__JIT_CODE("__unalign_jit_x0_bfextu: {bfextu r0, r0, 0, 0}");
502static tilegx_bundle_bits jit_x0_bfextu(int rd, int ra, int bfs, int bfe)
503{
504 extern tilegx_bundle_bits __unalign_jit_x0_bfextu;
505 return (GX_INSN_BSWAP(__unalign_jit_x0_bfextu) &
506 GX_INSN_X0_MASK) |
507 create_Dest_X0(rd) | create_SrcA_X0(ra) |
508 create_BFStart_X0(bfs) | create_BFEnd_X0(bfe);
509}
510
511__JIT_CODE("__unalign_jit_x1_addi: {bfextu r1, r1, 0, 0; addi r0, r0, 0}");
512static tilegx_bundle_bits jit_x1_addi(int rd, int ra, int imm8)
513{
514 extern tilegx_bundle_bits __unalign_jit_x1_addi;
515 return (GX_INSN_BSWAP(__unalign_jit_x1_addi) & GX_INSN_X1_MASK) |
516 create_Dest_X1(rd) | create_SrcA_X1(ra) |
517 create_Imm8_X1(imm8);
518}
519
520__JIT_CODE("__unalign_jit_x0_shrui: {shrui r0, r0, 0; iret}");
521static tilegx_bundle_bits jit_x0_shrui(int rd, int ra, int imm6)
522{
523 extern tilegx_bundle_bits __unalign_jit_x0_shrui;
524 return (GX_INSN_BSWAP(__unalign_jit_x0_shrui) &
525 GX_INSN_X0_MASK) |
526 create_Dest_X0(rd) | create_SrcA_X0(ra) |
527 create_ShAmt_X0(imm6);
528}
529
530__JIT_CODE("__unalign_jit_x0_rotli: {rotli r0, r0, 0; iret}");
531static tilegx_bundle_bits jit_x0_rotli(int rd, int ra, int imm6)
532{
533 extern tilegx_bundle_bits __unalign_jit_x0_rotli;
534 return (GX_INSN_BSWAP(__unalign_jit_x0_rotli) &
535 GX_INSN_X0_MASK) |
536 create_Dest_X0(rd) | create_SrcA_X0(ra) |
537 create_ShAmt_X0(imm6);
538}
539
540__JIT_CODE("__unalign_jit_x1_bnezt: {bnezt r0, __unalign_jit_x1_bnezt}");
541static tilegx_bundle_bits jit_x1_bnezt(int ra, int broff)
542{
543 extern tilegx_bundle_bits __unalign_jit_x1_bnezt;
544 return (GX_INSN_BSWAP(__unalign_jit_x1_bnezt) &
545 GX_INSN_X1_MASK) |
546 create_SrcA_X1(ra) | create_BrOff_X1(broff);
547}
548
549#undef __JIT_CODE
550
551/*
552 * This function generates unalign fixup JIT.
553 *
554 * We fist find unalign load/store instruction's destination, source
555 * reguisters: ra, rb and rd. and 3 scratch registers by calling
556 * find_regs(...). 3 scratch clobbers should not alias with any register
557 * used in the fault bundle. Then analyze the fault bundle to determine
558 * if it's a load or store, operand width, branch or address increment etc.
559 * At last generated JIT is copied into JIT code area in user space.
560 */
561
562static
563void jit_bundle_gen(struct pt_regs *regs, tilegx_bundle_bits bundle,
564 int align_ctl)
565{
566 struct thread_info *info = current_thread_info();
567 struct unaligned_jit_fragment frag;
568 struct unaligned_jit_fragment *jit_code_area;
569 tilegx_bundle_bits bundle_2 = 0;
570 /* If bundle_2_enable = false, bundle_2 is fnop/nop operation. */
571 bool bundle_2_enable = true;
572 uint64_t ra, rb, rd = -1, clob1, clob2, clob3;
573 /*
574 * Indicate if the unalign access
575 * instruction's registers hit with
576 * others in the same bundle.
577 */
578 bool alias = false;
579 bool load_n_store = true;
580 bool load_store_signed = false;
581 unsigned int load_store_size = 8;
582 bool y1_br = false; /* True, for a branch in same bundle at Y1.*/
583 int y1_br_reg = 0;
584 /* True for link operation. i.e. jalr or lnk at Y1 */
585 bool y1_lr = false;
586 int y1_lr_reg = 0;
587 bool x1_add = false;/* True, for load/store ADD instruction at X1*/
588 int x1_add_imm8 = 0;
589 bool unexpected = false;
590 int n = 0, k;
591
592 jit_code_area =
593 (struct unaligned_jit_fragment *)(info->unalign_jit_base);
594
595 memset((void *)&frag, 0, sizeof(frag));
596
597 /* 0: X mode, Otherwise: Y mode. */
598 if (bundle & TILEGX_BUNDLE_MODE_MASK) {
599 unsigned int mod, opcode;
600
601 if (get_Opcode_Y1(bundle) == RRR_1_OPCODE_Y1 &&
602 get_RRROpcodeExtension_Y1(bundle) ==
603 UNARY_RRR_1_OPCODE_Y1) {
604
605 opcode = get_UnaryOpcodeExtension_Y1(bundle);
606
607 /*
608 * Test "jalr", "jalrp", "jr", "jrp" instruction at Y1
609 * pipeline.
610 */
611 switch (opcode) {
612 case JALR_UNARY_OPCODE_Y1:
613 case JALRP_UNARY_OPCODE_Y1:
614 y1_lr = true;
615 y1_lr_reg = 55; /* Link register. */
616 /* FALLTHROUGH */
617 case JR_UNARY_OPCODE_Y1:
618 case JRP_UNARY_OPCODE_Y1:
619 y1_br = true;
620 y1_br_reg = get_SrcA_Y1(bundle);
621 break;
622 case LNK_UNARY_OPCODE_Y1:
623 /* "lnk" at Y1 pipeline. */
624 y1_lr = true;
625 y1_lr_reg = get_Dest_Y1(bundle);
626 break;
627 }
628 }
629
630 opcode = get_Opcode_Y2(bundle);
631 mod = get_Mode(bundle);
632
633 /*
634 * bundle_2 is bundle after making Y2 as a dummy operation
635 * - ld zero, sp
636 */
637 bundle_2 = (bundle & (~GX_INSN_Y2_MASK)) | jit_y2_dummy();
638
639 /* Make Y1 as fnop if Y1 is a branch or lnk operation. */
640 if (y1_br || y1_lr) {
641 bundle_2 &= ~(GX_INSN_Y1_MASK);
642 bundle_2 |= jit_y1_fnop();
643 }
644
645 if (is_y0_y1_nop(bundle_2))
646 bundle_2_enable = false;
647
648 if (mod == MODE_OPCODE_YC2) {
649 /* Store. */
650 load_n_store = false;
651 load_store_size = 1 << opcode;
652 load_store_signed = false;
653 find_regs(bundle, 0, &ra, &rb, &clob1, &clob2,
654 &clob3, &alias);
655 if (load_store_size > 8)
656 unexpected = true;
657 } else {
658 /* Load. */
659 load_n_store = true;
660 if (mod == MODE_OPCODE_YB2) {
661 switch (opcode) {
662 case LD_OPCODE_Y2:
663 load_store_signed = false;
664 load_store_size = 8;
665 break;
666 case LD4S_OPCODE_Y2:
667 load_store_signed = true;
668 load_store_size = 4;
669 break;
670 case LD4U_OPCODE_Y2:
671 load_store_signed = false;
672 load_store_size = 4;
673 break;
674 default:
675 unexpected = true;
676 }
677 } else if (mod == MODE_OPCODE_YA2) {
678 if (opcode == LD2S_OPCODE_Y2) {
679 load_store_signed = true;
680 load_store_size = 2;
681 } else if (opcode == LD2U_OPCODE_Y2) {
682 load_store_signed = false;
683 load_store_size = 2;
684 } else
685 unexpected = true;
686 } else
687 unexpected = true;
688 find_regs(bundle, &rd, &ra, &rb, &clob1, &clob2,
689 &clob3, &alias);
690 }
691 } else {
692 unsigned int opcode;
693
694 /* bundle_2 is bundle after making X1 as "fnop". */
695 bundle_2 = (bundle & (~GX_INSN_X1_MASK)) | jit_x1_fnop();
696
697 if (is_x0_x1_nop(bundle_2))
698 bundle_2_enable = false;
699
700 if (get_Opcode_X1(bundle) == RRR_0_OPCODE_X1) {
701 opcode = get_UnaryOpcodeExtension_X1(bundle);
702
703 if (get_RRROpcodeExtension_X1(bundle) ==
704 UNARY_RRR_0_OPCODE_X1) {
705 load_n_store = true;
706 find_regs(bundle, &rd, &ra, &rb, &clob1,
707 &clob2, &clob3, &alias);
708
709 switch (opcode) {
710 case LD_UNARY_OPCODE_X1:
711 load_store_signed = false;
712 load_store_size = 8;
713 break;
714 case LD4S_UNARY_OPCODE_X1:
715 load_store_signed = true;
716 /* FALLTHROUGH */
717 case LD4U_UNARY_OPCODE_X1:
718 load_store_size = 4;
719 break;
720
721 case LD2S_UNARY_OPCODE_X1:
722 load_store_signed = true;
723 /* FALLTHROUGH */
724 case LD2U_UNARY_OPCODE_X1:
725 load_store_size = 2;
726 break;
727 default:
728 unexpected = true;
729 }
730 } else {
731 load_n_store = false;
732 load_store_signed = false;
733 find_regs(bundle, 0, &ra, &rb,
734 &clob1, &clob2, &clob3,
735 &alias);
736
737 opcode = get_RRROpcodeExtension_X1(bundle);
738 switch (opcode) {
739 case ST_RRR_0_OPCODE_X1:
740 load_store_size = 8;
741 break;
742 case ST4_RRR_0_OPCODE_X1:
743 load_store_size = 4;
744 break;
745 case ST2_RRR_0_OPCODE_X1:
746 load_store_size = 2;
747 break;
748 default:
749 unexpected = true;
750 }
751 }
752 } else if (get_Opcode_X1(bundle) == IMM8_OPCODE_X1) {
753 load_n_store = true;
754 opcode = get_Imm8OpcodeExtension_X1(bundle);
755 switch (opcode) {
756 case LD_ADD_IMM8_OPCODE_X1:
757 load_store_size = 8;
758 break;
759
760 case LD4S_ADD_IMM8_OPCODE_X1:
761 load_store_signed = true;
762 /* FALLTHROUGH */
763 case LD4U_ADD_IMM8_OPCODE_X1:
764 load_store_size = 4;
765 break;
766
767 case LD2S_ADD_IMM8_OPCODE_X1:
768 load_store_signed = true;
769 /* FALLTHROUGH */
770 case LD2U_ADD_IMM8_OPCODE_X1:
771 load_store_size = 2;
772 break;
773
774 case ST_ADD_IMM8_OPCODE_X1:
775 load_n_store = false;
776 load_store_size = 8;
777 break;
778 case ST4_ADD_IMM8_OPCODE_X1:
779 load_n_store = false;
780 load_store_size = 4;
781 break;
782 case ST2_ADD_IMM8_OPCODE_X1:
783 load_n_store = false;
784 load_store_size = 2;
785 break;
786 default:
787 unexpected = true;
788 }
789
790 if (!unexpected) {
791 x1_add = true;
792 if (load_n_store)
793 x1_add_imm8 = get_Imm8_X1(bundle);
794 else
795 x1_add_imm8 = get_Dest_Imm8_X1(bundle);
796 }
797
798 find_regs(bundle, load_n_store ? (&rd) : NULL,
799 &ra, &rb, &clob1, &clob2, &clob3, &alias);
800 } else
801 unexpected = true;
802 }
803
804 /*
805 * Some sanity check for register numbers extracted from fault bundle.
806 */
807 if (check_regs(rd, ra, rb, clob1, clob2, clob3) == true)
808 unexpected = true;
809
810 /* Give warning if register ra has an aligned address. */
811 if (!unexpected)
812 WARN_ON(!((load_store_size - 1) & (regs->regs[ra])));
813
814
815 /*
816 * Fault came from kernel space, here we only need take care of
817 * unaligned "get_user/put_user" macros defined in "uaccess.h".
818 * Basically, we will handle bundle like this:
819 * {ld/2u/4s rd, ra; movei rx, 0} or {st/2/4 ra, rb; movei rx, 0}
820 * (Refer to file "arch/tile/include/asm/uaccess.h" for details).
821 * For either load or store, byte-wise operation is performed by calling
822 * get_user() or put_user(). If the macro returns non-zero value,
823 * set the value to rx, otherwise set zero to rx. Finally make pc point
824 * to next bundle and return.
825 */
826
827 if (EX1_PL(regs->ex1) != USER_PL) {
828
829 unsigned long rx = 0;
830 unsigned long x = 0, ret = 0;
831
832 if (y1_br || y1_lr || x1_add ||
833 (load_store_signed !=
834 (load_n_store && load_store_size == 4))) {
835 /* No branch, link, wrong sign-ext or load/store add. */
836 unexpected = true;
837 } else if (!unexpected) {
838 if (bundle & TILEGX_BUNDLE_MODE_MASK) {
839 /*
840 * Fault bundle is Y mode.
841 * Check if the Y1 and Y0 is the form of
842 * { movei rx, 0; nop/fnop }, if yes,
843 * find the rx.
844 */
845
846 if ((get_Opcode_Y1(bundle) == ADDI_OPCODE_Y1)
847 && (get_SrcA_Y1(bundle) == TREG_ZERO) &&
848 (get_Imm8_Y1(bundle) == 0) &&
849 is_bundle_y0_nop(bundle)) {
850 rx = get_Dest_Y1(bundle);
851 } else if ((get_Opcode_Y0(bundle) ==
852 ADDI_OPCODE_Y0) &&
853 (get_SrcA_Y0(bundle) == TREG_ZERO) &&
854 (get_Imm8_Y0(bundle) == 0) &&
855 is_bundle_y1_nop(bundle)) {
856 rx = get_Dest_Y0(bundle);
857 } else {
858 unexpected = true;
859 }
860 } else {
861 /*
862 * Fault bundle is X mode.
863 * Check if the X0 is 'movei rx, 0',
864 * if yes, find the rx.
865 */
866
867 if ((get_Opcode_X0(bundle) == IMM8_OPCODE_X0)
868 && (get_Imm8OpcodeExtension_X0(bundle) ==
869 ADDI_IMM8_OPCODE_X0) &&
870 (get_SrcA_X0(bundle) == TREG_ZERO) &&
871 (get_Imm8_X0(bundle) == 0)) {
872 rx = get_Dest_X0(bundle);
873 } else {
874 unexpected = true;
875 }
876 }
877
878 /* rx should be less than 56. */
879 if (!unexpected && (rx >= 56))
880 unexpected = true;
881 }
882
883 if (!search_exception_tables(regs->pc)) {
884 /* No fixup in the exception tables for the pc. */
885 unexpected = true;
886 }
887
888 if (unexpected) {
889 /* Unexpected unalign kernel fault. */
890 struct task_struct *tsk = validate_current();
891
892 bust_spinlocks(1);
893
894 show_regs(regs);
895
896 if (unlikely(tsk->pid < 2)) {
897 panic("Kernel unalign fault running %s!",
898 tsk->pid ? "init" : "the idle task");
899 }
900#ifdef SUPPORT_DIE
901 die("Oops", regs);
902#endif
903 bust_spinlocks(1);
904
905 do_group_exit(SIGKILL);
906
907 } else {
908 unsigned long i, b = 0;
909 unsigned char *ptr =
910 (unsigned char *)regs->regs[ra];
911 if (load_n_store) {
912 /* handle get_user(x, ptr) */
913 for (i = 0; i < load_store_size; i++) {
914 ret = get_user(b, ptr++);
915 if (!ret) {
916 /* Success! update x. */
917#ifdef __LITTLE_ENDIAN
918 x |= (b << (8 * i));
919#else
920 x <<= 8;
921 x |= b;
922#endif /* __LITTLE_ENDIAN */
923 } else {
924 x = 0;
925 break;
926 }
927 }
928
929 /* Sign-extend 4-byte loads. */
930 if (load_store_size == 4)
931 x = (long)(int)x;
932
933 /* Set register rd. */
934 regs->regs[rd] = x;
935
936 /* Set register rx. */
937 regs->regs[rx] = ret;
938
939 /* Bump pc. */
940 regs->pc += 8;
941
942 } else {
943 /* Handle put_user(x, ptr) */
944 x = regs->regs[rb];
945#ifdef __LITTLE_ENDIAN
946 b = x;
947#else
948 /*
949 * Swap x in order to store x from low
950 * to high memory same as the
951 * little-endian case.
952 */
953 switch (load_store_size) {
954 case 8:
955 b = swab64(x);
956 break;
957 case 4:
958 b = swab32(x);
959 break;
960 case 2:
961 b = swab16(x);
962 break;
963 }
964#endif /* __LITTLE_ENDIAN */
965 for (i = 0; i < load_store_size; i++) {
966 ret = put_user(b, ptr++);
967 if (ret)
968 break;
969 /* Success! shift 1 byte. */
970 b >>= 8;
971 }
972 /* Set register rx. */
973 regs->regs[rx] = ret;
974
975 /* Bump pc. */
976 regs->pc += 8;
977 }
978 }
979
980 unaligned_fixup_count++;
981
982 if (unaligned_printk) {
983 pr_info("%s/%d. Unalign fixup for kernel access "
984 "to userspace %lx.",
985 current->comm, current->pid, regs->regs[ra]);
986 }
987
988 /* Done! Return to the exception handler. */
989 return;
990 }
991
992 if ((align_ctl == 0) || unexpected) {
993 siginfo_t info = {
994 .si_signo = SIGBUS,
995 .si_code = BUS_ADRALN,
996 .si_addr = (unsigned char __user *)0
997 };
998 if (unaligned_printk)
999 pr_info("Unalign bundle: unexp @%llx, %llx",
1000 (unsigned long long)regs->pc,
1001 (unsigned long long)bundle);
1002
1003 if (ra < 56) {
1004 unsigned long uaa = (unsigned long)regs->regs[ra];
1005 /* Set bus Address. */
1006 info.si_addr = (unsigned char __user *)uaa;
1007 }
1008
1009 unaligned_fixup_count++;
1010
1011 trace_unhandled_signal("unaligned fixup trap", regs,
1012 (unsigned long)info.si_addr, SIGBUS);
1013 force_sig_info(info.si_signo, &info, current);
1014 return;
1015 }
1016
1017#ifdef __LITTLE_ENDIAN
1018#define UA_FIXUP_ADDR_DELTA 1
1019#define UA_FIXUP_BFEXT_START(_B_) 0
1020#define UA_FIXUP_BFEXT_END(_B_) (8 * (_B_) - 1)
1021#else /* __BIG_ENDIAN */
1022#define UA_FIXUP_ADDR_DELTA -1
1023#define UA_FIXUP_BFEXT_START(_B_) (64 - 8 * (_B_))
1024#define UA_FIXUP_BFEXT_END(_B_) 63
1025#endif /* __LITTLE_ENDIAN */
1026
1027
1028
1029 if ((ra != rb) && (rd != TREG_SP) && !alias &&
1030 !y1_br && !y1_lr && !x1_add) {
1031 /*
1032 * Simple case: ra != rb and no register alias found,
1033 * and no branch or link. This will be the majority.
1034 * We can do a little better for simplae case than the
1035 * generic scheme below.
1036 */
1037 if (!load_n_store) {
1038 /*
1039 * Simple store: ra != rb, no need for scratch register.
1040 * Just store and rotate to right bytewise.
1041 */
1042#ifdef __BIG_ENDIAN
1043 frag.insn[n++] =
1044 jit_x0_addi(ra, ra, load_store_size - 1) |
1045 jit_x1_fnop();
1046#endif /* __BIG_ENDIAN */
1047 for (k = 0; k < load_store_size; k++) {
1048 /* Store a byte. */
1049 frag.insn[n++] =
1050 jit_x0_rotli(rb, rb, 56) |
1051 jit_x1_st1_add(ra, rb,
1052 UA_FIXUP_ADDR_DELTA);
1053 }
1054#ifdef __BIG_ENDIAN
1055 frag.insn[n] = jit_x1_addi(ra, ra, 1);
1056#else
1057 frag.insn[n] = jit_x1_addi(ra, ra,
1058 -1 * load_store_size);
1059#endif /* __LITTLE_ENDIAN */
1060
1061 if (load_store_size == 8) {
1062 frag.insn[n] |= jit_x0_fnop();
1063 } else if (load_store_size == 4) {
1064 frag.insn[n] |= jit_x0_rotli(rb, rb, 32);
1065 } else { /* = 2 */
1066 frag.insn[n] |= jit_x0_rotli(rb, rb, 16);
1067 }
1068 n++;
1069 if (bundle_2_enable)
1070 frag.insn[n++] = bundle_2;
1071 frag.insn[n++] = jit_x0_fnop() | jit_x1_iret();
1072 } else {
1073 if (rd == ra) {
1074 /* Use two clobber registers: clob1/2. */
1075 frag.insn[n++] =
1076 jit_x0_addi(TREG_SP, TREG_SP, -16) |
1077 jit_x1_fnop();
1078 frag.insn[n++] =
1079 jit_x0_addi(clob1, ra, 7) |
1080 jit_x1_st_add(TREG_SP, clob1, -8);
1081 frag.insn[n++] =
1082 jit_x0_addi(clob2, ra, 0) |
1083 jit_x1_st(TREG_SP, clob2);
1084 frag.insn[n++] =
1085 jit_x0_fnop() |
1086 jit_x1_ldna(rd, ra);
1087 frag.insn[n++] =
1088 jit_x0_fnop() |
1089 jit_x1_ldna(clob1, clob1);
1090 /*
1091 * Note: we must make sure that rd must not
1092 * be sp. Recover clob1/2 from stack.
1093 */
1094 frag.insn[n++] =
1095 jit_x0_dblalign(rd, clob1, clob2) |
1096 jit_x1_ld_add(clob2, TREG_SP, 8);
1097 frag.insn[n++] =
1098 jit_x0_fnop() |
1099 jit_x1_ld_add(clob1, TREG_SP, 16);
1100 } else {
1101 /* Use one clobber register: clob1 only. */
1102 frag.insn[n++] =
1103 jit_x0_addi(TREG_SP, TREG_SP, -16) |
1104 jit_x1_fnop();
1105 frag.insn[n++] =
1106 jit_x0_addi(clob1, ra, 7) |
1107 jit_x1_st(TREG_SP, clob1);
1108 frag.insn[n++] =
1109 jit_x0_fnop() |
1110 jit_x1_ldna(rd, ra);
1111 frag.insn[n++] =
1112 jit_x0_fnop() |
1113 jit_x1_ldna(clob1, clob1);
1114 /*
1115 * Note: we must make sure that rd must not
1116 * be sp. Recover clob1 from stack.
1117 */
1118 frag.insn[n++] =
1119 jit_x0_dblalign(rd, clob1, ra) |
1120 jit_x1_ld_add(clob1, TREG_SP, 16);
1121 }
1122
1123 if (bundle_2_enable)
1124 frag.insn[n++] = bundle_2;
1125 /*
1126 * For non 8-byte load, extract corresponding bytes and
1127 * signed extension.
1128 */
1129 if (load_store_size == 4) {
1130 if (load_store_signed)
1131 frag.insn[n++] =
1132 jit_x0_bfexts(
1133 rd, rd,
1134 UA_FIXUP_BFEXT_START(4),
1135 UA_FIXUP_BFEXT_END(4)) |
1136 jit_x1_fnop();
1137 else
1138 frag.insn[n++] =
1139 jit_x0_bfextu(
1140 rd, rd,
1141 UA_FIXUP_BFEXT_START(4),
1142 UA_FIXUP_BFEXT_END(4)) |
1143 jit_x1_fnop();
1144 } else if (load_store_size == 2) {
1145 if (load_store_signed)
1146 frag.insn[n++] =
1147 jit_x0_bfexts(
1148 rd, rd,
1149 UA_FIXUP_BFEXT_START(2),
1150 UA_FIXUP_BFEXT_END(2)) |
1151 jit_x1_fnop();
1152 else
1153 frag.insn[n++] =
1154 jit_x0_bfextu(
1155 rd, rd,
1156 UA_FIXUP_BFEXT_START(2),
1157 UA_FIXUP_BFEXT_END(2)) |
1158 jit_x1_fnop();
1159 }
1160
1161 frag.insn[n++] =
1162 jit_x0_fnop() |
1163 jit_x1_iret();
1164 }
1165 } else if (!load_n_store) {
1166
1167 /*
1168 * Generic memory store cases: use 3 clobber registers.
1169 *
1170 * Alloc space for saveing clob2,1,3 on user's stack.
1171 * register clob3 points to where clob2 saved, followed by
1172 * clob1 and 3 from high to low memory.
1173 */
1174 frag.insn[n++] =
1175 jit_x0_addi(TREG_SP, TREG_SP, -32) |
1176 jit_x1_fnop();
1177 frag.insn[n++] =
1178 jit_x0_addi(clob3, TREG_SP, 16) |
1179 jit_x1_st_add(TREG_SP, clob3, 8);
1180#ifdef __LITTLE_ENDIAN
1181 frag.insn[n++] =
1182 jit_x0_addi(clob1, ra, 0) |
1183 jit_x1_st_add(TREG_SP, clob1, 8);
1184#else
1185 frag.insn[n++] =
1186 jit_x0_addi(clob1, ra, load_store_size - 1) |
1187 jit_x1_st_add(TREG_SP, clob1, 8);
1188#endif
1189 if (load_store_size == 8) {
1190 /*
1191 * We save one byte a time, not for fast, but compact
1192 * code. After each store, data source register shift
1193 * right one byte. unchanged after 8 stores.
1194 */
1195 frag.insn[n++] =
1196 jit_x0_addi(clob2, TREG_ZERO, 7) |
1197 jit_x1_st_add(TREG_SP, clob2, 16);
1198 frag.insn[n++] =
1199 jit_x0_rotli(rb, rb, 56) |
1200 jit_x1_st1_add(clob1, rb, UA_FIXUP_ADDR_DELTA);
1201 frag.insn[n++] =
1202 jit_x0_addi(clob2, clob2, -1) |
1203 jit_x1_bnezt(clob2, -1);
1204 frag.insn[n++] =
1205 jit_x0_fnop() |
1206 jit_x1_addi(clob2, y1_br_reg, 0);
1207 } else if (load_store_size == 4) {
1208 frag.insn[n++] =
1209 jit_x0_addi(clob2, TREG_ZERO, 3) |
1210 jit_x1_st_add(TREG_SP, clob2, 16);
1211 frag.insn[n++] =
1212 jit_x0_rotli(rb, rb, 56) |
1213 jit_x1_st1_add(clob1, rb, UA_FIXUP_ADDR_DELTA);
1214 frag.insn[n++] =
1215 jit_x0_addi(clob2, clob2, -1) |
1216 jit_x1_bnezt(clob2, -1);
1217 /*
1218 * same as 8-byte case, but need shift another 4
1219 * byte to recover rb for 4-byte store.
1220 */
1221 frag.insn[n++] = jit_x0_rotli(rb, rb, 32) |
1222 jit_x1_addi(clob2, y1_br_reg, 0);
1223 } else { /* =2 */
1224 frag.insn[n++] =
1225 jit_x0_addi(clob2, rb, 0) |
1226 jit_x1_st_add(TREG_SP, clob2, 16);
1227 for (k = 0; k < 2; k++) {
1228 frag.insn[n++] =
1229 jit_x0_shrui(rb, rb, 8) |
1230 jit_x1_st1_add(clob1, rb,
1231 UA_FIXUP_ADDR_DELTA);
1232 }
1233 frag.insn[n++] =
1234 jit_x0_addi(rb, clob2, 0) |
1235 jit_x1_addi(clob2, y1_br_reg, 0);
1236 }
1237
1238 if (bundle_2_enable)
1239 frag.insn[n++] = bundle_2;
1240
1241 if (y1_lr) {
1242 frag.insn[n++] =
1243 jit_x0_fnop() |
1244 jit_x1_mfspr(y1_lr_reg,
1245 SPR_EX_CONTEXT_0_0);
1246 }
1247 if (y1_br) {
1248 frag.insn[n++] =
1249 jit_x0_fnop() |
1250 jit_x1_mtspr(SPR_EX_CONTEXT_0_0,
1251 clob2);
1252 }
1253 if (x1_add) {
1254 frag.insn[n++] =
1255 jit_x0_addi(ra, ra, x1_add_imm8) |
1256 jit_x1_ld_add(clob2, clob3, -8);
1257 } else {
1258 frag.insn[n++] =
1259 jit_x0_fnop() |
1260 jit_x1_ld_add(clob2, clob3, -8);
1261 }
1262 frag.insn[n++] =
1263 jit_x0_fnop() |
1264 jit_x1_ld_add(clob1, clob3, -8);
1265 frag.insn[n++] = jit_x0_fnop() | jit_x1_ld(clob3, clob3);
1266 frag.insn[n++] = jit_x0_fnop() | jit_x1_iret();
1267
1268 } else {
1269 /*
1270 * Generic memory load cases.
1271 *
1272 * Alloc space for saveing clob1,2,3 on user's stack.
1273 * register clob3 points to where clob1 saved, followed
1274 * by clob2 and 3 from high to low memory.
1275 */
1276
1277 frag.insn[n++] =
1278 jit_x0_addi(TREG_SP, TREG_SP, -32) |
1279 jit_x1_fnop();
1280 frag.insn[n++] =
1281 jit_x0_addi(clob3, TREG_SP, 16) |
1282 jit_x1_st_add(TREG_SP, clob3, 8);
1283 frag.insn[n++] =
1284 jit_x0_addi(clob2, ra, 0) |
1285 jit_x1_st_add(TREG_SP, clob2, 8);
1286
1287 if (y1_br) {
1288 frag.insn[n++] =
1289 jit_x0_addi(clob1, y1_br_reg, 0) |
1290 jit_x1_st_add(TREG_SP, clob1, 16);
1291 } else {
1292 frag.insn[n++] =
1293 jit_x0_fnop() |
1294 jit_x1_st_add(TREG_SP, clob1, 16);
1295 }
1296
1297 if (bundle_2_enable)
1298 frag.insn[n++] = bundle_2;
1299
1300 if (y1_lr) {
1301 frag.insn[n++] =
1302 jit_x0_fnop() |
1303 jit_x1_mfspr(y1_lr_reg,
1304 SPR_EX_CONTEXT_0_0);
1305 }
1306
1307 if (y1_br) {
1308 frag.insn[n++] =
1309 jit_x0_fnop() |
1310 jit_x1_mtspr(SPR_EX_CONTEXT_0_0,
1311 clob1);
1312 }
1313
1314 frag.insn[n++] =
1315 jit_x0_addi(clob1, clob2, 7) |
1316 jit_x1_ldna(rd, clob2);
1317 frag.insn[n++] =
1318 jit_x0_fnop() |
1319 jit_x1_ldna(clob1, clob1);
1320 frag.insn[n++] =
1321 jit_x0_dblalign(rd, clob1, clob2) |
1322 jit_x1_ld_add(clob1, clob3, -8);
1323 if (x1_add) {
1324 frag.insn[n++] =
1325 jit_x0_addi(ra, ra, x1_add_imm8) |
1326 jit_x1_ld_add(clob2, clob3, -8);
1327 } else {
1328 frag.insn[n++] =
1329 jit_x0_fnop() |
1330 jit_x1_ld_add(clob2, clob3, -8);
1331 }
1332
1333 frag.insn[n++] =
1334 jit_x0_fnop() |
1335 jit_x1_ld(clob3, clob3);
1336
1337 if (load_store_size == 4) {
1338 if (load_store_signed)
1339 frag.insn[n++] =
1340 jit_x0_bfexts(
1341 rd, rd,
1342 UA_FIXUP_BFEXT_START(4),
1343 UA_FIXUP_BFEXT_END(4)) |
1344 jit_x1_fnop();
1345 else
1346 frag.insn[n++] =
1347 jit_x0_bfextu(
1348 rd, rd,
1349 UA_FIXUP_BFEXT_START(4),
1350 UA_FIXUP_BFEXT_END(4)) |
1351 jit_x1_fnop();
1352 } else if (load_store_size == 2) {
1353 if (load_store_signed)
1354 frag.insn[n++] =
1355 jit_x0_bfexts(
1356 rd, rd,
1357 UA_FIXUP_BFEXT_START(2),
1358 UA_FIXUP_BFEXT_END(2)) |
1359 jit_x1_fnop();
1360 else
1361 frag.insn[n++] =
1362 jit_x0_bfextu(
1363 rd, rd,
1364 UA_FIXUP_BFEXT_START(2),
1365 UA_FIXUP_BFEXT_END(2)) |
1366 jit_x1_fnop();
1367 }
1368
1369 frag.insn[n++] = jit_x0_fnop() | jit_x1_iret();
1370 }
1371
1372 /* Max JIT bundle count is 14. */
1373 WARN_ON(n > 14);
1374
1375 if (!unexpected) {
1376 int status = 0;
1377 int idx = (regs->pc >> 3) &
1378 ((1ULL << (PAGE_SHIFT - UNALIGN_JIT_SHIFT)) - 1);
1379
1380 frag.pc = regs->pc;
1381 frag.bundle = bundle;
1382
1383 if (unaligned_printk) {
1384 pr_info("%s/%d, Unalign fixup: pc=%lx "
1385 "bundle=%lx %d %d %d %d %d %d %d %d.",
1386 current->comm, current->pid,
1387 (unsigned long)frag.pc,
1388 (unsigned long)frag.bundle,
1389 (int)alias, (int)rd, (int)ra,
1390 (int)rb, (int)bundle_2_enable,
1391 (int)y1_lr, (int)y1_br, (int)x1_add);
1392
1393 for (k = 0; k < n; k += 2)
1394 pr_info("[%d] %016llx %016llx", k,
1395 (unsigned long long)frag.insn[k],
1396 (unsigned long long)frag.insn[k+1]);
1397 }
1398
1399 /* Swap bundle byte order for big endian sys. */
1400#ifdef __BIG_ENDIAN
1401 frag.bundle = GX_INSN_BSWAP(frag.bundle);
1402 for (k = 0; k < n; k++)
1403 frag.insn[k] = GX_INSN_BSWAP(frag.insn[k]);
1404#endif /* __BIG_ENDIAN */
1405
1406 status = copy_to_user((void __user *)&jit_code_area[idx],
1407 &frag, sizeof(frag));
1408 if (status) {
1409 /* Fail to copy JIT into user land. send SIGSEGV. */
1410 siginfo_t info = {
1411 .si_signo = SIGSEGV,
1412 .si_code = SEGV_MAPERR,
1413 .si_addr = (void __user *)&jit_code_area[idx]
1414 };
1415
1416 pr_warn("Unalign fixup: pid=%d %s jit_code_area=%llx",
1417 current->pid, current->comm,
1418 (unsigned long long)&jit_code_area[idx]);
1419
1420 trace_unhandled_signal("segfault in unalign fixup",
1421 regs,
1422 (unsigned long)info.si_addr,
1423 SIGSEGV);
1424 force_sig_info(info.si_signo, &info, current);
1425 return;
1426 }
1427
1428
1429 /* Do a cheaper increment, not accurate. */
1430 unaligned_fixup_count++;
1431 __flush_icache_range((unsigned long)&jit_code_area[idx],
1432 (unsigned long)&jit_code_area[idx] +
1433 sizeof(frag));
1434
1435 /* Setup SPR_EX_CONTEXT_0_0/1 for returning to user program.*/
1436 __insn_mtspr(SPR_EX_CONTEXT_0_0, regs->pc + 8);
1437 __insn_mtspr(SPR_EX_CONTEXT_0_1, PL_ICS_EX1(USER_PL, 0));
1438
1439 /* Modify pc at the start of new JIT. */
1440 regs->pc = (unsigned long)&jit_code_area[idx].insn[0];
1441 /* Set ICS in SPR_EX_CONTEXT_K_1. */
1442 regs->ex1 = PL_ICS_EX1(USER_PL, 1);
1443 }
1444}
1445
1446
1447/*
1448 * C function to generate unalign data JIT. Called from unalign data
1449 * interrupt handler.
1450 *
1451 * First check if unalign fix is disabled or exception did not not come from
1452 * user space or sp register points to unalign address, if true, generate a
1453 * SIGBUS. Then map a page into user space as JIT area if it is not mapped
1454 * yet. Genenerate JIT code by calling jit_bundle_gen(). After that return
1455 * back to exception handler.
1456 *
1457 * The exception handler will "iret" to new generated JIT code after
1458 * restoring caller saved registers. In theory, the JIT code will perform
1459 * another "iret" to resume user's program.
1460 */
1461
1462void do_unaligned(struct pt_regs *regs, int vecnum)
1463{
1464 tilegx_bundle_bits __user *pc;
1465 tilegx_bundle_bits bundle;
1466 struct thread_info *info = current_thread_info();
1467 int align_ctl;
1468
1469 /* Checks the per-process unaligned JIT flags */
1470 align_ctl = unaligned_fixup;
1471 switch (task_thread_info(current)->align_ctl) {
1472 case PR_UNALIGN_NOPRINT:
1473 align_ctl = 1;
1474 break;
1475 case PR_UNALIGN_SIGBUS:
1476 align_ctl = 0;
1477 break;
1478 }
1479
1480 /* Enable iterrupt in order to access user land. */
1481 local_irq_enable();
1482
1483 /*
1484 * The fault came from kernel space. Two choices:
1485 * (a) unaligned_fixup < 1, we will first call get/put_user fixup
1486 * to return -EFAULT. If no fixup, simply panic the kernel.
1487 * (b) unaligned_fixup >=1, we will try to fix the unaligned access
1488 * if it was triggered by get_user/put_user() macros. Panic the
1489 * kernel if it is not fixable.
1490 */
1491
1492 if (EX1_PL(regs->ex1) != USER_PL) {
1493
1494 if (align_ctl < 1) {
1495 unaligned_fixup_count++;
1496 /* If exception came from kernel, try fix it up. */
1497 if (fixup_exception(regs)) {
1498 if (unaligned_printk)
1499 pr_info("Unalign fixup: %d %llx @%llx",
1500 (int)unaligned_fixup,
1501 (unsigned long long)regs->ex1,
1502 (unsigned long long)regs->pc);
1503 return;
1504 }
1505 /* Not fixable. Go panic. */
1506 panic("Unalign exception in Kernel. pc=%lx",
1507 regs->pc);
1508 return;
1509 } else {
1510 /*
1511 * Try to fix the exception. If we can't, panic the
1512 * kernel.
1513 */
1514 bundle = GX_INSN_BSWAP(
1515 *((tilegx_bundle_bits *)(regs->pc)));
1516 jit_bundle_gen(regs, bundle, align_ctl);
1517 return;
1518 }
1519 }
1520
1521 /*
1522 * Fault came from user with ICS or stack is not aligned.
1523 * If so, we will trigger SIGBUS.
1524 */
1525 if ((regs->sp & 0x7) || (regs->ex1) || (align_ctl < 0)) {
1526 siginfo_t info = {
1527 .si_signo = SIGBUS,
1528 .si_code = BUS_ADRALN,
1529 .si_addr = (unsigned char __user *)0
1530 };
1531
1532 if (unaligned_printk)
1533 pr_info("Unalign fixup: %d %llx @%llx",
1534 (int)unaligned_fixup,
1535 (unsigned long long)regs->ex1,
1536 (unsigned long long)regs->pc);
1537
1538 unaligned_fixup_count++;
1539
1540 trace_unhandled_signal("unaligned fixup trap", regs, 0, SIGBUS);
1541 force_sig_info(info.si_signo, &info, current);
1542 return;
1543 }
1544
1545
1546 /* Read the bundle casued the exception! */
1547 pc = (tilegx_bundle_bits __user *)(regs->pc);
1548 if (get_user(bundle, pc) != 0) {
1549 /* Probably never be here since pc is valid user address.*/
1550 siginfo_t info = {
1551 .si_signo = SIGSEGV,
1552 .si_code = SEGV_MAPERR,
1553 .si_addr = (void __user *)pc
1554 };
1555 pr_err("Couldn't read instruction at %p trying to step\n", pc);
1556 trace_unhandled_signal("segfault in unalign fixup", regs,
1557 (unsigned long)info.si_addr, SIGSEGV);
1558 force_sig_info(info.si_signo, &info, current);
1559 return;
1560 }
1561
1562 if (!info->unalign_jit_base) {
1563 void __user *user_page;
1564
1565 /*
1566 * Allocate a page in userland.
1567 * For 64-bit processes we try to place the mapping far
1568 * from anything else that might be going on (specifically
1569 * 64 GB below the top of the user address space). If it
1570 * happens not to be possible to put it there, it's OK;
1571 * the kernel will choose another location and we'll
1572 * remember it for later.
1573 */
1574 if (is_compat_task())
1575 user_page = NULL;
1576 else
1577 user_page = (void __user *)(TASK_SIZE - (1UL << 36)) +
1578 (current->pid << PAGE_SHIFT);
1579
1580 user_page = (void __user *) vm_mmap(NULL,
1581 (unsigned long)user_page,
1582 PAGE_SIZE,
1583 PROT_EXEC | PROT_READ |
1584 PROT_WRITE,
1585#ifdef CONFIG_HOMECACHE
1586 MAP_CACHE_HOME_TASK |
1587#endif
1588 MAP_PRIVATE |
1589 MAP_ANONYMOUS,
1590 0);
1591
1592 if (IS_ERR((void __force *)user_page)) {
1593 pr_err("Out of kernel pages trying do_mmap.\n");
1594 return;
1595 }
1596
1597 /* Save the address in the thread_info struct */
1598 info->unalign_jit_base = user_page;
1599 if (unaligned_printk)
1600 pr_info("Unalign bundle: %d:%d, allocate page @%llx",
1601 raw_smp_processor_id(), current->pid,
1602 (unsigned long long)user_page);
1603 }
1604
1605 /* Generate unalign JIT */
1606 jit_bundle_gen(regs, GX_INSN_BSWAP(bundle), align_ctl);
1607}
1608
1609#endif /* __tilegx__ */
diff --git a/arch/tile/kernel/vdso.c b/arch/tile/kernel/vdso.c
new file mode 100644
index 000000000000..1533af24106e
--- /dev/null
+++ b/arch/tile/kernel/vdso.c
@@ -0,0 +1,212 @@
1/*
2 * Copyright 2012 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/binfmts.h>
16#include <linux/compat.h>
17#include <linux/elf.h>
18#include <linux/mm.h>
19#include <linux/pagemap.h>
20
21#include <asm/vdso.h>
22#include <asm/mman.h>
23#include <asm/sections.h>
24
25#include <arch/sim.h>
26
27/* The alignment of the vDSO. */
28#define VDSO_ALIGNMENT PAGE_SIZE
29
30
31static unsigned int vdso_pages;
32static struct page **vdso_pagelist;
33
34#ifdef CONFIG_COMPAT
35static unsigned int vdso32_pages;
36static struct page **vdso32_pagelist;
37#endif
38static int vdso_ready;
39
40/*
41 * The vdso data page.
42 */
43static union {
44 struct vdso_data data;
45 u8 page[PAGE_SIZE];
46} vdso_data_store __page_aligned_data;
47
48struct vdso_data *vdso_data = &vdso_data_store.data;
49
50static unsigned int __read_mostly vdso_enabled = 1;
51
52static struct page **vdso_setup(void *vdso_kbase, unsigned int pages)
53{
54 int i;
55 struct page **pagelist;
56
57 pagelist = kzalloc(sizeof(struct page *) * (pages + 1), GFP_KERNEL);
58 BUG_ON(pagelist == NULL);
59 for (i = 0; i < pages - 1; i++) {
60 struct page *pg = virt_to_page(vdso_kbase + i*PAGE_SIZE);
61 ClearPageReserved(pg);
62 pagelist[i] = pg;
63 }
64 pagelist[pages - 1] = virt_to_page(vdso_data);
65 pagelist[pages] = NULL;
66
67 return pagelist;
68}
69
70static int __init vdso_init(void)
71{
72 int data_pages = sizeof(vdso_data_store) >> PAGE_SHIFT;
73
74 /*
75 * We can disable vDSO support generally, but we need to retain
76 * one page to support the two-bundle (16-byte) rt_sigreturn path.
77 */
78 if (!vdso_enabled) {
79 size_t offset = (unsigned long)&__vdso_rt_sigreturn;
80 static struct page *sigret_page;
81 sigret_page = alloc_page(GFP_KERNEL | __GFP_ZERO);
82 BUG_ON(sigret_page == NULL);
83 vdso_pagelist = &sigret_page;
84 vdso_pages = 1;
85 BUG_ON(offset >= PAGE_SIZE);
86 memcpy(page_address(sigret_page) + offset,
87 vdso_start + offset, 16);
88#ifdef CONFIG_COMPAT
89 vdso32_pages = vdso_pages;
90 vdso32_pagelist = vdso_pagelist;
91#endif
92 vdso_ready = 1;
93 return 0;
94 }
95
96 vdso_pages = (vdso_end - vdso_start) >> PAGE_SHIFT;
97 vdso_pages += data_pages;
98 vdso_pagelist = vdso_setup(vdso_start, vdso_pages);
99
100#ifdef CONFIG_COMPAT
101 vdso32_pages = (vdso32_end - vdso32_start) >> PAGE_SHIFT;
102 vdso32_pages += data_pages;
103 vdso32_pagelist = vdso_setup(vdso32_start, vdso32_pages);
104#endif
105
106 smp_wmb();
107 vdso_ready = 1;
108
109 return 0;
110}
111arch_initcall(vdso_init);
112
113const char *arch_vma_name(struct vm_area_struct *vma)
114{
115 if (vma->vm_mm && vma->vm_start == VDSO_BASE)
116 return "[vdso]";
117#ifndef __tilegx__
118 if (vma->vm_start == MEM_USER_INTRPT)
119 return "[intrpt]";
120#endif
121 return NULL;
122}
123
124struct vm_area_struct *get_gate_vma(struct mm_struct *mm)
125{
126 return NULL;
127}
128
129int in_gate_area(struct mm_struct *mm, unsigned long address)
130{
131 return 0;
132}
133
134int in_gate_area_no_mm(unsigned long address)
135{
136 return 0;
137}
138
139int setup_vdso_pages(void)
140{
141 struct page **pagelist;
142 unsigned long pages;
143 struct mm_struct *mm = current->mm;
144 unsigned long vdso_base = 0;
145 int retval = 0;
146
147 if (!vdso_ready)
148 return 0;
149
150 mm->context.vdso_base = 0;
151
152 pagelist = vdso_pagelist;
153 pages = vdso_pages;
154#ifdef CONFIG_COMPAT
155 if (is_compat_task()) {
156 pagelist = vdso32_pagelist;
157 pages = vdso32_pages;
158 }
159#endif
160
161 /*
162 * vDSO has a problem and was disabled, just don't "enable" it for the
163 * process.
164 */
165 if (pages == 0)
166 return 0;
167
168 vdso_base = get_unmapped_area(NULL, vdso_base,
169 (pages << PAGE_SHIFT) +
170 ((VDSO_ALIGNMENT - 1) & PAGE_MASK),
171 0, 0);
172 if (IS_ERR_VALUE(vdso_base)) {
173 retval = vdso_base;
174 return retval;
175 }
176
177 /* Add required alignment. */
178 vdso_base = ALIGN(vdso_base, VDSO_ALIGNMENT);
179
180 /*
181 * Put vDSO base into mm struct. We need to do this before calling
182 * install_special_mapping or the perf counter mmap tracking code
183 * will fail to recognise it as a vDSO (since arch_vma_name fails).
184 */
185 mm->context.vdso_base = vdso_base;
186
187 /*
188 * our vma flags don't have VM_WRITE so by default, the process isn't
189 * allowed to write those pages.
190 * gdb can break that with ptrace interface, and thus trigger COW on
191 * those pages but it's then your responsibility to never do that on
192 * the "data" page of the vDSO or you'll stop getting kernel updates
193 * and your nice userland gettimeofday will be totally dead.
194 * It's fine to use that for setting breakpoints in the vDSO code
195 * pages though
196 */
197 retval = install_special_mapping(mm, vdso_base,
198 pages << PAGE_SHIFT,
199 VM_READ|VM_EXEC |
200 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC,
201 pagelist);
202 if (retval)
203 mm->context.vdso_base = 0;
204
205 return retval;
206}
207
208static __init int vdso_func(char *s)
209{
210 return kstrtouint(s, 0, &vdso_enabled);
211}
212__setup("vdso=", vdso_func);
diff --git a/arch/tile/kernel/vdso/Makefile b/arch/tile/kernel/vdso/Makefile
new file mode 100644
index 000000000000..e2b7a2f4ee41
--- /dev/null
+++ b/arch/tile/kernel/vdso/Makefile
@@ -0,0 +1,118 @@
1# Symbols present in the vdso
2vdso-syms = rt_sigreturn gettimeofday
3
4# Files to link into the vdso
5obj-vdso = $(patsubst %, v%.o, $(vdso-syms))
6
7# Build rules
8targets := $(obj-vdso) vdso.so vdso.so.dbg vdso.lds
9obj-vdso := $(addprefix $(obj)/, $(obj-vdso))
10
11# vdso32 is only for tilegx -m32 compat task.
12VDSO32-$(CONFIG_COMPAT) := y
13
14obj-y += vdso.o
15obj-$(VDSO32-y) += vdso32.o
16extra-y += vdso.lds
17CPPFLAGS_vdso.lds += -P -C -U$(ARCH)
18
19# vDSO code runs in userspace and -pg doesn't help with profiling anyway.
20CFLAGS_REMOVE_vdso.o = -pg
21CFLAGS_REMOVE_vdso32.o = -pg
22CFLAGS_REMOVE_vrt_sigreturn.o = -pg
23CFLAGS_REMOVE_vrt_sigreturn32.o = -pg
24CFLAGS_REMOVE_vgettimeofday.o = -pg
25CFLAGS_REMOVE_vgettimeofday32.o = -pg
26
27ifdef CONFIG_FEEDBACK_COLLECT
28# vDSO code runs in userspace, not collecting feedback data.
29CFLAGS_REMOVE_vdso.o = -ffeedback-generate
30CFLAGS_REMOVE_vdso32.o = -ffeedback-generate
31CFLAGS_REMOVE_vrt_sigreturn.o = -ffeedback-generate
32CFLAGS_REMOVE_vrt_sigreturn32.o = -ffeedback-generate
33CFLAGS_REMOVE_vgettimeofday.o = -ffeedback-generate
34CFLAGS_REMOVE_vgettimeofday32.o = -ffeedback-generate
35endif
36
37# Disable gcov profiling for VDSO code
38GCOV_PROFILE := n
39
40# Force dependency
41$(obj)/vdso.o: $(obj)/vdso.so
42
43# link rule for the .so file, .lds has to be first
44SYSCFLAGS_vdso.so.dbg = $(c_flags)
45$(obj)/vdso.so.dbg: $(src)/vdso.lds $(obj-vdso)
46 $(call if_changed,vdsold)
47
48
49# We also create a special relocatable object that should mirror the symbol
50# table and layout of the linked DSO. With ld -R we can then refer to
51# these symbols in the kernel code rather than hand-coded addresses.
52extra-y += vdso-syms.o
53$(obj)/built-in.o: $(obj)/vdso-syms.o
54$(obj)/built-in.o: ld_flags += -R $(obj)/vdso-syms.o
55
56SYSCFLAGS_vdso.so.dbg = -shared -s -Wl,-soname=linux-vdso.so.1 \
57 $(call cc-ldoption, -Wl$(comma)--hash-style=sysv)
58SYSCFLAGS_vdso_syms.o = -r
59$(obj)/vdso-syms.o: $(src)/vdso.lds $(obj)/vrt_sigreturn.o FORCE
60 $(call if_changed,vdsold)
61
62
63# strip rule for the .so file
64$(obj)/%.so: OBJCOPYFLAGS := -S
65$(obj)/%.so: $(obj)/%.so.dbg FORCE
66 $(call if_changed,objcopy)
67
68# actual build commands
69# The DSO images are built using a special linker script
70# Add -lgcc so tilepro gets static muldi3 and lshrdi3 definitions.
71# Make sure only to export the intended __vdso_xxx symbol offsets.
72quiet_cmd_vdsold = VDSOLD $@
73 cmd_vdsold = $(CC) $(KCFLAGS) -nostdlib $(SYSCFLAGS_$(@F)) \
74 -Wl,-T,$(filter-out FORCE,$^) -o $@.tmp -lgcc && \
75 $(CROSS_COMPILE)objcopy \
76 $(patsubst %, -G __vdso_%, $(vdso-syms)) $@.tmp $@
77
78# install commands for the unstripped file
79quiet_cmd_vdso_install = INSTALL $@
80 cmd_vdso_install = cp $(obj)/$@.dbg $(MODLIB)/vdso/$@
81
82vdso.so: $(obj)/vdso.so.dbg
83 @mkdir -p $(MODLIB)/vdso
84 $(call cmd,vdso_install)
85
86vdso32.so: $(obj)/vdso32.so.dbg
87 $(call cmd,vdso_install)
88
89vdso_install: vdso.so
90vdso32_install: vdso32.so
91
92
93KBUILD_AFLAGS_32 := $(filter-out -m64,$(KBUILD_AFLAGS))
94KBUILD_AFLAGS_32 += -m32 -s
95KBUILD_CFLAGS_32 := $(filter-out -m64,$(KBUILD_CFLAGS))
96KBUILD_CFLAGS_32 += -m32 -fPIC -shared
97
98obj-vdso32 = $(patsubst %, v%32.o, $(vdso-syms))
99obj-vdso32 := $(addprefix $(obj)/, $(obj-vdso32))
100
101targets += $(obj-vdso32) vdso32.so vdso32.so.dbg
102
103$(obj-vdso32:%=%): KBUILD_AFLAGS = $(KBUILD_AFLAGS_32)
104$(obj-vdso32:%=%): KBUILD_CFLAGS = $(KBUILD_CFLAGS_32)
105
106$(obj)/vgettimeofday32.o: $(obj)/vgettimeofday.c
107 $(call if_changed,cc_o_c)
108
109$(obj)/vrt_sigreturn32.o: $(obj)/vrt_sigreturn.S
110 $(call if_changed,as_o_S)
111
112# Force dependency
113$(obj)/vdso32.o: $(obj)/vdso32.so
114
115SYSCFLAGS_vdso32.so.dbg = -m32 -shared -s -Wl,-soname=linux-vdso32.so.1 \
116 $(call cc-ldoption, -Wl$(comma)--hash-style=sysv)
117$(obj)/vdso32.so.dbg: $(src)/vdso.lds $(obj-vdso32)
118 $(call if_changed,vdsold)
diff --git a/arch/tile/kernel/vdso/vdso.S b/arch/tile/kernel/vdso/vdso.S
new file mode 100644
index 000000000000..3467adb41630
--- /dev/null
+++ b/arch/tile/kernel/vdso/vdso.S
@@ -0,0 +1,28 @@
1/*
2 * Copyright 2012 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/init.h>
16#include <linux/linkage.h>
17#include <asm/page.h>
18
19 __PAGE_ALIGNED_DATA
20
21 .global vdso_start, vdso_end
22 .align PAGE_SIZE
23vdso_start:
24 .incbin "arch/tile/kernel/vdso/vdso.so"
25 .align PAGE_SIZE
26vdso_end:
27
28 .previous
diff --git a/arch/tile/kernel/vdso/vdso.lds.S b/arch/tile/kernel/vdso/vdso.lds.S
new file mode 100644
index 000000000000..041cd6c39c83
--- /dev/null
+++ b/arch/tile/kernel/vdso/vdso.lds.S
@@ -0,0 +1,87 @@
1/*
2 * Copyright 2012 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#define VDSO_VERSION_STRING LINUX_2.6
16
17
18OUTPUT_ARCH(tile)
19
20/* The ELF entry point can be used to set the AT_SYSINFO value. */
21ENTRY(__vdso_rt_sigreturn);
22
23
24SECTIONS
25{
26 . = SIZEOF_HEADERS;
27
28 .hash : { *(.hash) } :text
29 .gnu.hash : { *(.gnu.hash) }
30 .dynsym : { *(.dynsym) }
31 .dynstr : { *(.dynstr) }
32 .gnu.version : { *(.gnu.version) }
33 .gnu.version_d : { *(.gnu.version_d) }
34 .gnu.version_r : { *(.gnu.version_r) }
35
36 .note : { *(.note.*) } :text :note
37 .dynamic : { *(.dynamic) } :text :dynamic
38
39 .eh_frame_hdr : { *(.eh_frame_hdr) } :text :eh_frame_hdr
40 .eh_frame : { KEEP (*(.eh_frame)) } :text
41
42 .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
43
44 /*
45 * This linker script is used both with -r and with -shared.
46 * For the layouts to match, we need to skip more than enough
47 * space for the dynamic symbol table et al. If this amount
48 * is insufficient, ld -shared will barf. Just increase it here.
49 */
50 . = 0x1000;
51 .text : { *(.text .text.*) } :text
52
53 .data : {
54 *(.got.plt) *(.got)
55 *(.data .data.* .gnu.linkonce.d.*)
56 *(.dynbss)
57 *(.bss .bss.* .gnu.linkonce.b.*)
58 }
59}
60
61
62/*
63 * We must supply the ELF program headers explicitly to get just one
64 * PT_LOAD segment, and set the flags explicitly to make segments read-only.
65 */
66PHDRS
67{
68 text PT_LOAD FLAGS(5) FILEHDR PHDRS; /* PF_R|PF_X */
69 dynamic PT_DYNAMIC FLAGS(4); /* PF_R */
70 note PT_NOTE FLAGS(4); /* PF_R */
71 eh_frame_hdr PT_GNU_EH_FRAME;
72}
73
74
75/*
76 * This controls what userland symbols we export from the vDSO.
77 */
78VERSION
79{
80 VDSO_VERSION_STRING {
81 global:
82 __vdso_rt_sigreturn;
83 __vdso_gettimeofday;
84 gettimeofday;
85 local:*;
86 };
87}
diff --git a/arch/tile/kernel/vdso/vdso32.S b/arch/tile/kernel/vdso/vdso32.S
new file mode 100644
index 000000000000..1d1ac3257e11
--- /dev/null
+++ b/arch/tile/kernel/vdso/vdso32.S
@@ -0,0 +1,28 @@
1/*
2 * Copyright 2013 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/init.h>
16#include <linux/linkage.h>
17#include <asm/page.h>
18
19 __PAGE_ALIGNED_DATA
20
21 .global vdso32_start, vdso32_end
22 .align PAGE_SIZE
23vdso32_start:
24 .incbin "arch/tile/kernel/vdso/vdso32.so"
25 .align PAGE_SIZE
26vdso32_end:
27
28 .previous
diff --git a/arch/tile/kernel/vdso/vgettimeofday.c b/arch/tile/kernel/vdso/vgettimeofday.c
new file mode 100644
index 000000000000..51ec8e46f5f9
--- /dev/null
+++ b/arch/tile/kernel/vdso/vgettimeofday.c
@@ -0,0 +1,107 @@
1/*
2 * Copyright 2012 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#define VDSO_BUILD /* avoid some shift warnings for -m32 in <asm/page.h> */
16#include <linux/time.h>
17#include <asm/timex.h>
18#include <asm/vdso.h>
19
20#if CHIP_HAS_SPLIT_CYCLE()
21static inline cycles_t get_cycles_inline(void)
22{
23 unsigned int high = __insn_mfspr(SPR_CYCLE_HIGH);
24 unsigned int low = __insn_mfspr(SPR_CYCLE_LOW);
25 unsigned int high2 = __insn_mfspr(SPR_CYCLE_HIGH);
26
27 while (unlikely(high != high2)) {
28 low = __insn_mfspr(SPR_CYCLE_LOW);
29 high = high2;
30 high2 = __insn_mfspr(SPR_CYCLE_HIGH);
31 }
32
33 return (((cycles_t)high) << 32) | low;
34}
35#define get_cycles get_cycles_inline
36#endif
37
38/*
39 * Find out the vDSO data page address in the process address space.
40 */
41inline unsigned long get_datapage(void)
42{
43 unsigned long ret;
44
45 /* vdso data page located in the 2nd vDSO page. */
46 asm volatile ("lnk %0" : "=r"(ret));
47 ret &= ~(PAGE_SIZE - 1);
48 ret += PAGE_SIZE;
49
50 return ret;
51}
52
53int __vdso_gettimeofday(struct timeval *tv, struct timezone *tz)
54{
55 cycles_t cycles;
56 unsigned long count, sec, ns;
57 volatile struct vdso_data *vdso_data;
58
59 vdso_data = (struct vdso_data *)get_datapage();
60 /* The use of the timezone is obsolete, normally tz is NULL. */
61 if (unlikely(tz != NULL)) {
62 while (1) {
63 /* Spin until the update finish. */
64 count = vdso_data->tz_update_count;
65 if (count & 1)
66 continue;
67
68 tz->tz_minuteswest = vdso_data->tz_minuteswest;
69 tz->tz_dsttime = vdso_data->tz_dsttime;
70
71 /* Check whether updated, read again if so. */
72 if (count == vdso_data->tz_update_count)
73 break;
74 }
75 }
76
77 if (unlikely(tv == NULL))
78 return 0;
79
80 while (1) {
81 /* Spin until the update finish. */
82 count = vdso_data->tb_update_count;
83 if (count & 1)
84 continue;
85
86 cycles = (get_cycles() - vdso_data->xtime_tod_stamp);
87 ns = (cycles * vdso_data->mult) >> vdso_data->shift;
88 sec = vdso_data->xtime_clock_sec;
89 ns += vdso_data->xtime_clock_nsec;
90 if (ns >= NSEC_PER_SEC) {
91 ns -= NSEC_PER_SEC;
92 sec += 1;
93 }
94
95 /* Check whether updated, read again if so. */
96 if (count == vdso_data->tb_update_count)
97 break;
98 }
99
100 tv->tv_sec = sec;
101 tv->tv_usec = ns / 1000;
102
103 return 0;
104}
105
106int gettimeofday(struct timeval *tv, struct timezone *tz)
107 __attribute__((weak, alias("__vdso_gettimeofday")));
diff --git a/arch/tile/kernel/vdso/vrt_sigreturn.S b/arch/tile/kernel/vdso/vrt_sigreturn.S
new file mode 100644
index 000000000000..6326caf4a039
--- /dev/null
+++ b/arch/tile/kernel/vdso/vrt_sigreturn.S
@@ -0,0 +1,30 @@
1/*
2 * Copyright 2012 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 <arch/abi.h>
17#include <asm/unistd.h>
18
19/*
20 * Note that libc has a copy of this function that it uses to compare
21 * against the PC when a stack backtrace ends, so if this code is
22 * changed, the libc implementation(s) should also be updated.
23 */
24ENTRY(__vdso_rt_sigreturn)
25 moveli TREG_SYSCALL_NR_NAME, __NR_rt_sigreturn
26 swint1
27 /* We don't use ENDPROC to avoid tagging this symbol as FUNC,
28 * which confuses the perf tool.
29 */
30 END(__vdso_rt_sigreturn)
diff --git a/arch/tile/kernel/vmlinux.lds.S b/arch/tile/kernel/vmlinux.lds.S
index a13ed902afbb..f1819423ffc9 100644
--- a/arch/tile/kernel/vmlinux.lds.S
+++ b/arch/tile/kernel/vmlinux.lds.S
@@ -5,7 +5,7 @@
5#include <hv/hypervisor.h> 5#include <hv/hypervisor.h>
6 6
7/* Text loads starting from the supervisor interrupt vector address. */ 7/* Text loads starting from the supervisor interrupt vector address. */
8#define TEXT_OFFSET MEM_SV_INTRPT 8#define TEXT_OFFSET MEM_SV_START
9 9
10OUTPUT_ARCH(tile) 10OUTPUT_ARCH(tile)
11ENTRY(_start) 11ENTRY(_start)
@@ -13,7 +13,7 @@ jiffies = jiffies_64;
13 13
14PHDRS 14PHDRS
15{ 15{
16 intrpt1 PT_LOAD ; 16 intrpt PT_LOAD ;
17 text PT_LOAD ; 17 text PT_LOAD ;
18 data PT_LOAD ; 18 data PT_LOAD ;
19} 19}
@@ -24,14 +24,17 @@ SECTIONS
24 #define LOAD_OFFSET TEXT_OFFSET 24 #define LOAD_OFFSET TEXT_OFFSET
25 25
26 /* Interrupt vectors */ 26 /* Interrupt vectors */
27 .intrpt1 (LOAD_OFFSET) : AT ( 0 ) /* put at the start of physical memory */ 27 .intrpt (LOAD_OFFSET) : AT ( 0 ) /* put at the start of physical memory */
28 { 28 {
29 _text = .; 29 _text = .;
30 *(.intrpt1) 30 *(.intrpt)
31 } :intrpt1 =0 31 } :intrpt =0
32 32
33 /* Hypervisor call vectors */ 33 /* Hypervisor call vectors */
34 #include "hvglue.lds" 34 . = ALIGN(0x10000);
35 .hvglue : AT (ADDR(.hvglue) - LOAD_OFFSET) {
36 *(.hvglue)
37 } :NONE
35 38
36 /* Now the real code */ 39 /* Now the real code */
37 . = ALIGN(0x20000); 40 . = ALIGN(0x20000);
@@ -40,7 +43,11 @@ SECTIONS
40 HEAD_TEXT 43 HEAD_TEXT
41 SCHED_TEXT 44 SCHED_TEXT
42 LOCK_TEXT 45 LOCK_TEXT
46 KPROBES_TEXT
47 IRQENTRY_TEXT
43 __fix_text_end = .; /* tile-cpack won't rearrange before this */ 48 __fix_text_end = .; /* tile-cpack won't rearrange before this */
49 ALIGN_FUNCTION();
50 *(.hottext*)
44 TEXT_TEXT 51 TEXT_TEXT
45 *(.text.*) 52 *(.text.*)
46 *(.coldtext*) 53 *(.coldtext*)
@@ -67,20 +74,8 @@ SECTIONS
67 __init_end = .; 74 __init_end = .;
68 75
69 _sdata = .; /* Start of data section */ 76 _sdata = .; /* Start of data section */
70
71 RO_DATA_SECTION(PAGE_SIZE) 77 RO_DATA_SECTION(PAGE_SIZE)
72
73 /* initially writeable, then read-only */
74 . = ALIGN(PAGE_SIZE);
75 __w1data_begin = .;
76 .w1data : AT(ADDR(.w1data) - LOAD_OFFSET) {
77 VMLINUX_SYMBOL(__w1data_begin) = .;
78 *(.w1data)
79 VMLINUX_SYMBOL(__w1data_end) = .;
80 }
81
82 RW_DATA_SECTION(L2_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE) 78 RW_DATA_SECTION(L2_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE)
83
84 _edata = .; 79 _edata = .;
85 80
86 EXCEPTION_TABLE(L2_CACHE_BYTES) 81 EXCEPTION_TABLE(L2_CACHE_BYTES)
diff --git a/arch/tile/lib/Makefile b/arch/tile/lib/Makefile
index 985f59858234..c4211cbb2021 100644
--- a/arch/tile/lib/Makefile
+++ b/arch/tile/lib/Makefile
@@ -4,15 +4,15 @@
4 4
5lib-y = cacheflush.o checksum.o cpumask.o delay.o uaccess.o \ 5lib-y = cacheflush.o checksum.o cpumask.o delay.o uaccess.o \
6 memmove.o memcpy_$(BITS).o memchr_$(BITS).o memset_$(BITS).o \ 6 memmove.o memcpy_$(BITS).o memchr_$(BITS).o memset_$(BITS).o \
7 strchr_$(BITS).o strlen_$(BITS).o 7 strchr_$(BITS).o strlen_$(BITS).o strnlen_$(BITS).o
8
9ifeq ($(CONFIG_TILEGX),y)
10CFLAGS_REMOVE_memcpy_user_64.o = -fno-omit-frame-pointer
11lib-y += memcpy_user_64.o
12else
13lib-y += atomic_32.o atomic_asm_32.o memcpy_tile64.o
14endif
15 8
9lib-$(CONFIG_TILEGX) += memcpy_user_64.o
10lib-$(CONFIG_TILEPRO) += atomic_32.o atomic_asm_32.o
16lib-$(CONFIG_SMP) += spinlock_$(BITS).o usercopy_$(BITS).o 11lib-$(CONFIG_SMP) += spinlock_$(BITS).o usercopy_$(BITS).o
17 12
18obj-$(CONFIG_MODULES) += exports.o 13obj-$(CONFIG_MODULES) += exports.o
14
15# The finv_buffer_remote() and copy_{to,from}_user() routines can't
16# have -pg added, since they both rely on being leaf functions.
17CFLAGS_REMOVE_cacheflush.o = -pg
18CFLAGS_REMOVE_memcpy_user_64.o = -pg
diff --git a/arch/tile/lib/atomic_32.c b/arch/tile/lib/atomic_32.c
index f5cada70c3c8..759efa337be8 100644
--- a/arch/tile/lib/atomic_32.c
+++ b/arch/tile/lib/atomic_32.c
@@ -20,50 +20,12 @@
20#include <linux/atomic.h> 20#include <linux/atomic.h>
21#include <arch/chip.h> 21#include <arch/chip.h>
22 22
23/* See <asm/atomic_32.h> */
24#if ATOMIC_LOCKS_FOUND_VIA_TABLE()
25
26/*
27 * A block of memory containing locks for atomic ops. Each instance of this
28 * struct will be homed on a different CPU.
29 */
30struct atomic_locks_on_cpu {
31 int lock[ATOMIC_HASH_L2_SIZE];
32} __attribute__((aligned(ATOMIC_HASH_L2_SIZE * 4)));
33
34static DEFINE_PER_CPU(struct atomic_locks_on_cpu, atomic_lock_pool);
35
36/* The locks we'll use until __init_atomic_per_cpu is called. */
37static struct atomic_locks_on_cpu __initdata initial_atomic_locks;
38
39/* Hash into this vector to get a pointer to lock for the given atomic. */
40struct atomic_locks_on_cpu *atomic_lock_ptr[ATOMIC_HASH_L1_SIZE]
41 __write_once = {
42 [0 ... ATOMIC_HASH_L1_SIZE-1] (&initial_atomic_locks)
43};
44
45#else /* ATOMIC_LOCKS_FOUND_VIA_TABLE() */
46
47/* This page is remapped on startup to be hash-for-home. */ 23/* This page is remapped on startup to be hash-for-home. */
48int atomic_locks[PAGE_SIZE / sizeof(int)] __page_aligned_bss; 24int atomic_locks[PAGE_SIZE / sizeof(int)] __page_aligned_bss;
49 25
50#endif /* ATOMIC_LOCKS_FOUND_VIA_TABLE() */
51
52int *__atomic_hashed_lock(volatile void *v) 26int *__atomic_hashed_lock(volatile void *v)
53{ 27{
54 /* NOTE: this code must match "sys_cmpxchg" in kernel/intvec_32.S */ 28 /* NOTE: this code must match "sys_cmpxchg" in kernel/intvec_32.S */
55#if ATOMIC_LOCKS_FOUND_VIA_TABLE()
56 unsigned long i =
57 (unsigned long) v & ((PAGE_SIZE-1) & -sizeof(long long));
58 unsigned long n = __insn_crc32_32(0, i);
59
60 /* Grab high bits for L1 index. */
61 unsigned long l1_index = n >> ((sizeof(n) * 8) - ATOMIC_HASH_L1_SHIFT);
62 /* Grab low bits for L2 index. */
63 unsigned long l2_index = n & (ATOMIC_HASH_L2_SIZE - 1);
64
65 return &atomic_lock_ptr[l1_index]->lock[l2_index];
66#else
67 /* 29 /*
68 * Use bits [3, 3 + ATOMIC_HASH_SHIFT) as the lock index. 30 * Use bits [3, 3 + ATOMIC_HASH_SHIFT) as the lock index.
69 * Using mm works here because atomic_locks is page aligned. 31 * Using mm works here because atomic_locks is page aligned.
@@ -72,26 +34,13 @@ int *__atomic_hashed_lock(volatile void *v)
72 (unsigned long)atomic_locks, 34 (unsigned long)atomic_locks,
73 2, (ATOMIC_HASH_SHIFT + 2) - 1); 35 2, (ATOMIC_HASH_SHIFT + 2) - 1);
74 return (int *)ptr; 36 return (int *)ptr;
75#endif
76} 37}
77 38
78#ifdef CONFIG_SMP 39#ifdef CONFIG_SMP
79/* Return whether the passed pointer is a valid atomic lock pointer. */ 40/* Return whether the passed pointer is a valid atomic lock pointer. */
80static int is_atomic_lock(int *p) 41static int is_atomic_lock(int *p)
81{ 42{
82#if ATOMIC_LOCKS_FOUND_VIA_TABLE()
83 int i;
84 for (i = 0; i < ATOMIC_HASH_L1_SIZE; ++i) {
85
86 if (p >= &atomic_lock_ptr[i]->lock[0] &&
87 p < &atomic_lock_ptr[i]->lock[ATOMIC_HASH_L2_SIZE]) {
88 return 1;
89 }
90 }
91 return 0;
92#else
93 return p >= &atomic_locks[0] && p < &atomic_locks[ATOMIC_HASH_SIZE]; 43 return p >= &atomic_locks[0] && p < &atomic_locks[ATOMIC_HASH_SIZE];
94#endif
95} 44}
96 45
97void __atomic_fault_unlock(int *irqlock_word) 46void __atomic_fault_unlock(int *irqlock_word)
@@ -110,33 +59,32 @@ static inline int *__atomic_setup(volatile void *v)
110 return __atomic_hashed_lock(v); 59 return __atomic_hashed_lock(v);
111} 60}
112 61
113int _atomic_xchg(atomic_t *v, int n) 62int _atomic_xchg(int *v, int n)
114{ 63{
115 return __atomic_xchg(&v->counter, __atomic_setup(v), n).val; 64 return __atomic_xchg(v, __atomic_setup(v), n).val;
116} 65}
117EXPORT_SYMBOL(_atomic_xchg); 66EXPORT_SYMBOL(_atomic_xchg);
118 67
119int _atomic_xchg_add(atomic_t *v, int i) 68int _atomic_xchg_add(int *v, int i)
120{ 69{
121 return __atomic_xchg_add(&v->counter, __atomic_setup(v), i).val; 70 return __atomic_xchg_add(v, __atomic_setup(v), i).val;
122} 71}
123EXPORT_SYMBOL(_atomic_xchg_add); 72EXPORT_SYMBOL(_atomic_xchg_add);
124 73
125int _atomic_xchg_add_unless(atomic_t *v, int a, int u) 74int _atomic_xchg_add_unless(int *v, int a, int u)
126{ 75{
127 /* 76 /*
128 * Note: argument order is switched here since it is easier 77 * Note: argument order is switched here since it is easier
129 * to use the first argument consistently as the "old value" 78 * to use the first argument consistently as the "old value"
130 * in the assembly, as is done for _atomic_cmpxchg(). 79 * in the assembly, as is done for _atomic_cmpxchg().
131 */ 80 */
132 return __atomic_xchg_add_unless(&v->counter, __atomic_setup(v), u, a) 81 return __atomic_xchg_add_unless(v, __atomic_setup(v), u, a).val;
133 .val;
134} 82}
135EXPORT_SYMBOL(_atomic_xchg_add_unless); 83EXPORT_SYMBOL(_atomic_xchg_add_unless);
136 84
137int _atomic_cmpxchg(atomic_t *v, int o, int n) 85int _atomic_cmpxchg(int *v, int o, int n)
138{ 86{
139 return __atomic_cmpxchg(&v->counter, __atomic_setup(v), o, n).val; 87 return __atomic_cmpxchg(v, __atomic_setup(v), o, n).val;
140} 88}
141EXPORT_SYMBOL(_atomic_cmpxchg); 89EXPORT_SYMBOL(_atomic_cmpxchg);
142 90
@@ -159,33 +107,32 @@ unsigned long _atomic_xor(volatile unsigned long *p, unsigned long mask)
159EXPORT_SYMBOL(_atomic_xor); 107EXPORT_SYMBOL(_atomic_xor);
160 108
161 109
162u64 _atomic64_xchg(atomic64_t *v, u64 n) 110u64 _atomic64_xchg(u64 *v, u64 n)
163{ 111{
164 return __atomic64_xchg(&v->counter, __atomic_setup(v), n); 112 return __atomic64_xchg(v, __atomic_setup(v), n);
165} 113}
166EXPORT_SYMBOL(_atomic64_xchg); 114EXPORT_SYMBOL(_atomic64_xchg);
167 115
168u64 _atomic64_xchg_add(atomic64_t *v, u64 i) 116u64 _atomic64_xchg_add(u64 *v, u64 i)
169{ 117{
170 return __atomic64_xchg_add(&v->counter, __atomic_setup(v), i); 118 return __atomic64_xchg_add(v, __atomic_setup(v), i);
171} 119}
172EXPORT_SYMBOL(_atomic64_xchg_add); 120EXPORT_SYMBOL(_atomic64_xchg_add);
173 121
174u64 _atomic64_xchg_add_unless(atomic64_t *v, u64 a, u64 u) 122u64 _atomic64_xchg_add_unless(u64 *v, u64 a, u64 u)
175{ 123{
176 /* 124 /*
177 * Note: argument order is switched here since it is easier 125 * Note: argument order is switched here since it is easier
178 * to use the first argument consistently as the "old value" 126 * to use the first argument consistently as the "old value"
179 * in the assembly, as is done for _atomic_cmpxchg(). 127 * in the assembly, as is done for _atomic_cmpxchg().
180 */ 128 */
181 return __atomic64_xchg_add_unless(&v->counter, __atomic_setup(v), 129 return __atomic64_xchg_add_unless(v, __atomic_setup(v), u, a);
182 u, a);
183} 130}
184EXPORT_SYMBOL(_atomic64_xchg_add_unless); 131EXPORT_SYMBOL(_atomic64_xchg_add_unless);
185 132
186u64 _atomic64_cmpxchg(atomic64_t *v, u64 o, u64 n) 133u64 _atomic64_cmpxchg(u64 *v, u64 o, u64 n)
187{ 134{
188 return __atomic64_cmpxchg(&v->counter, __atomic_setup(v), o, n); 135 return __atomic64_cmpxchg(v, __atomic_setup(v), o, n);
189} 136}
190EXPORT_SYMBOL(_atomic64_cmpxchg); 137EXPORT_SYMBOL(_atomic64_cmpxchg);
191 138
@@ -208,54 +155,8 @@ struct __get_user __atomic_bad_address(int __user *addr)
208} 155}
209 156
210 157
211#if CHIP_HAS_CBOX_HOME_MAP()
212static int __init noatomichash(char *str)
213{
214 pr_warning("noatomichash is deprecated.\n");
215 return 1;
216}
217__setup("noatomichash", noatomichash);
218#endif
219
220void __init __init_atomic_per_cpu(void) 158void __init __init_atomic_per_cpu(void)
221{ 159{
222#if ATOMIC_LOCKS_FOUND_VIA_TABLE()
223
224 unsigned int i;
225 int actual_cpu;
226
227 /*
228 * Before this is called from setup, we just have one lock for
229 * all atomic objects/operations. Here we replace the
230 * elements of atomic_lock_ptr so that they point at per_cpu
231 * integers. This seemingly over-complex approach stems from
232 * the fact that DEFINE_PER_CPU defines an entry for each cpu
233 * in the grid, not each cpu from 0..ATOMIC_HASH_SIZE-1. But
234 * for efficient hashing of atomics to their locks we want a
235 * compile time constant power of 2 for the size of this
236 * table, so we use ATOMIC_HASH_SIZE.
237 *
238 * Here we populate atomic_lock_ptr from the per cpu
239 * atomic_lock_pool, interspersing by actual cpu so that
240 * subsequent elements are homed on consecutive cpus.
241 */
242
243 actual_cpu = cpumask_first(cpu_possible_mask);
244
245 for (i = 0; i < ATOMIC_HASH_L1_SIZE; ++i) {
246 /*
247 * Preincrement to slightly bias against using cpu 0,
248 * which has plenty of stuff homed on it already.
249 */
250 actual_cpu = cpumask_next(actual_cpu, cpu_possible_mask);
251 if (actual_cpu >= nr_cpu_ids)
252 actual_cpu = cpumask_first(cpu_possible_mask);
253
254 atomic_lock_ptr[i] = &per_cpu(atomic_lock_pool, actual_cpu);
255 }
256
257#else /* ATOMIC_LOCKS_FOUND_VIA_TABLE() */
258
259 /* Validate power-of-two and "bigger than cpus" assumption */ 160 /* Validate power-of-two and "bigger than cpus" assumption */
260 BUILD_BUG_ON(ATOMIC_HASH_SIZE & (ATOMIC_HASH_SIZE-1)); 161 BUILD_BUG_ON(ATOMIC_HASH_SIZE & (ATOMIC_HASH_SIZE-1));
261 BUG_ON(ATOMIC_HASH_SIZE < nr_cpu_ids); 162 BUG_ON(ATOMIC_HASH_SIZE < nr_cpu_ids);
@@ -279,6 +180,4 @@ void __init __init_atomic_per_cpu(void)
279 * That should not produce more indices than ATOMIC_HASH_SIZE. 180 * That should not produce more indices than ATOMIC_HASH_SIZE.
280 */ 181 */
281 BUILD_BUG_ON((PAGE_SIZE >> 3) > ATOMIC_HASH_SIZE); 182 BUILD_BUG_ON((PAGE_SIZE >> 3) > ATOMIC_HASH_SIZE);
282
283#endif /* ATOMIC_LOCKS_FOUND_VIA_TABLE() */
284} 183}
diff --git a/arch/tile/lib/atomic_asm_32.S b/arch/tile/lib/atomic_asm_32.S
index 30638042691d..6bda3132cd61 100644
--- a/arch/tile/lib/atomic_asm_32.S
+++ b/arch/tile/lib/atomic_asm_32.S
@@ -164,6 +164,7 @@ STD_ENTRY_SECTION(__atomic\name, .text.atomic)
164 STD_ENDPROC(__atomic\name) 164 STD_ENDPROC(__atomic\name)
165 .ifc \bitwidth,32 165 .ifc \bitwidth,32
166 .pushsection __ex_table,"a" 166 .pushsection __ex_table,"a"
167 .align 4
167 .word 1b, __atomic\name 168 .word 1b, __atomic\name
168 .word 2b, __atomic\name 169 .word 2b, __atomic\name
169 .word __atomic\name, __atomic_bad_address 170 .word __atomic\name, __atomic_bad_address
diff --git a/arch/tile/lib/cacheflush.c b/arch/tile/lib/cacheflush.c
index 8f8ad814b139..9c0ec22009a5 100644
--- a/arch/tile/lib/cacheflush.c
+++ b/arch/tile/lib/cacheflush.c
@@ -36,7 +36,8 @@ static inline void force_load(char *p)
36 * core (if "!hfh") or homed via hash-for-home (if "hfh"), waiting 36 * core (if "!hfh") or homed via hash-for-home (if "hfh"), waiting
37 * until the memory controller holds the flushed values. 37 * until the memory controller holds the flushed values.
38 */ 38 */
39void finv_buffer_remote(void *buffer, size_t size, int hfh) 39void __attribute__((optimize("omit-frame-pointer")))
40finv_buffer_remote(void *buffer, size_t size, int hfh)
40{ 41{
41 char *p, *base; 42 char *p, *base;
42 size_t step_size, load_count; 43 size_t step_size, load_count;
@@ -147,18 +148,21 @@ void finv_buffer_remote(void *buffer, size_t size, int hfh)
147 force_load(p); 148 force_load(p);
148 149
149 /* 150 /*
150 * Repeat, but with inv's instead of loads, to get rid of the 151 * Repeat, but with finv's instead of loads, to get rid of the
151 * data we just loaded into our own cache and the old home L3. 152 * data we just loaded into our own cache and the old home L3.
152 * No need to unroll since inv's don't target a register. 153 * No need to unroll since finv's don't target a register.
154 * The finv's are guaranteed not to actually flush the data in
155 * the buffer back to their home, since we just read it, so the
156 * lines are clean in cache; we will only invalidate those lines.
153 */ 157 */
154 p = (char *)buffer + size - 1; 158 p = (char *)buffer + size - 1;
155 __insn_inv(p); 159 __insn_finv(p);
156 p -= step_size; 160 p -= step_size;
157 p = (char *)((unsigned long)p | (step_size - 1)); 161 p = (char *)((unsigned long)p | (step_size - 1));
158 for (; p >= base; p -= step_size) 162 for (; p >= base; p -= step_size)
159 __insn_inv(p); 163 __insn_finv(p);
160 164
161 /* Wait for the load+inv's (and thus finvs) to have completed. */ 165 /* Wait for these finv's (and thus the first finvs) to be done. */
162 __insn_mf(); 166 __insn_mf();
163 167
164#ifdef __tilegx__ 168#ifdef __tilegx__
diff --git a/arch/tile/lib/exports.c b/arch/tile/lib/exports.c
index a93b02a25222..82733c87d67e 100644
--- a/arch/tile/lib/exports.c
+++ b/arch/tile/lib/exports.c
@@ -22,7 +22,6 @@ EXPORT_SYMBOL(strnlen_user_asm);
22EXPORT_SYMBOL(strncpy_from_user_asm); 22EXPORT_SYMBOL(strncpy_from_user_asm);
23EXPORT_SYMBOL(clear_user_asm); 23EXPORT_SYMBOL(clear_user_asm);
24EXPORT_SYMBOL(flush_user_asm); 24EXPORT_SYMBOL(flush_user_asm);
25EXPORT_SYMBOL(inv_user_asm);
26EXPORT_SYMBOL(finv_user_asm); 25EXPORT_SYMBOL(finv_user_asm);
27 26
28/* arch/tile/kernel/entry.S */ 27/* arch/tile/kernel/entry.S */
@@ -34,6 +33,12 @@ EXPORT_SYMBOL(dump_stack);
34/* arch/tile/kernel/head.S */ 33/* arch/tile/kernel/head.S */
35EXPORT_SYMBOL(empty_zero_page); 34EXPORT_SYMBOL(empty_zero_page);
36 35
36#ifdef CONFIG_FUNCTION_TRACER
37/* arch/tile/kernel/mcount_64.S */
38#include <asm/ftrace.h>
39EXPORT_SYMBOL(__mcount);
40#endif /* CONFIG_FUNCTION_TRACER */
41
37/* arch/tile/lib/, various memcpy files */ 42/* arch/tile/lib/, various memcpy files */
38EXPORT_SYMBOL(memcpy); 43EXPORT_SYMBOL(memcpy);
39EXPORT_SYMBOL(__copy_to_user_inatomic); 44EXPORT_SYMBOL(__copy_to_user_inatomic);
diff --git a/arch/tile/lib/memchr_64.c b/arch/tile/lib/memchr_64.c
index 6f867dbf7c56..f8196b3a950e 100644
--- a/arch/tile/lib/memchr_64.c
+++ b/arch/tile/lib/memchr_64.c
@@ -36,7 +36,7 @@ void *memchr(const void *s, int c, size_t n)
36 p = (const uint64_t *)(s_int & -8); 36 p = (const uint64_t *)(s_int & -8);
37 37
38 /* Create eight copies of the byte for which we are looking. */ 38 /* Create eight copies of the byte for which we are looking. */
39 goal = 0x0101010101010101ULL * (uint8_t) c; 39 goal = copy_byte(c);
40 40
41 /* Read the first word, but munge it so that bytes before the array 41 /* Read the first word, but munge it so that bytes before the array
42 * will not match goal. 42 * will not match goal.
diff --git a/arch/tile/lib/memcpy_32.S b/arch/tile/lib/memcpy_32.S
index 2a419a6122db..a2771ae5da53 100644
--- a/arch/tile/lib/memcpy_32.S
+++ b/arch/tile/lib/memcpy_32.S
@@ -22,14 +22,6 @@
22 22
23#include <linux/linkage.h> 23#include <linux/linkage.h>
24 24
25/* On TILE64, we wrap these functions via arch/tile/lib/memcpy_tile64.c */
26#if !CHIP_HAS_COHERENT_LOCAL_CACHE()
27#define memcpy __memcpy_asm
28#define __copy_to_user_inatomic __copy_to_user_inatomic_asm
29#define __copy_from_user_inatomic __copy_from_user_inatomic_asm
30#define __copy_from_user_zeroing __copy_from_user_zeroing_asm
31#endif
32
33#define IS_MEMCPY 0 25#define IS_MEMCPY 0
34#define IS_COPY_FROM_USER 1 26#define IS_COPY_FROM_USER 1
35#define IS_COPY_FROM_USER_ZEROING 2 27#define IS_COPY_FROM_USER_ZEROING 2
@@ -44,6 +36,7 @@
44 */ 36 */
45#define EX \ 37#define EX \
46 .pushsection __ex_table, "a"; \ 38 .pushsection __ex_table, "a"; \
39 .align 4; \
47 .word 9f, memcpy_common_fixup; \ 40 .word 9f, memcpy_common_fixup; \
48 .popsection; \ 41 .popsection; \
49 9 42 9
@@ -158,12 +151,9 @@ EX: { sw r0, r3; addi r0, r0, 4; addi r2, r2, -4 }
158 151
159 { addi r3, r1, 60; andi r9, r9, -64 } 152 { addi r3, r1, 60; andi r9, r9, -64 }
160 153
161#if CHIP_HAS_WH64()
162 /* No need to prefetch dst, we'll just do the wh64 154 /* No need to prefetch dst, we'll just do the wh64
163 * right before we copy a line. 155 * right before we copy a line.
164 */ 156 */
165#endif
166
167EX: { lw r5, r3; addi r3, r3, 64; movei r4, 1 } 157EX: { lw r5, r3; addi r3, r3, 64; movei r4, 1 }
168 /* Intentionally stall for a few cycles to leave L2 cache alone. */ 158 /* Intentionally stall for a few cycles to leave L2 cache alone. */
169 { bnzt zero, .; move r27, lr } 159 { bnzt zero, .; move r27, lr }
@@ -171,21 +161,6 @@ EX: { lw r6, r3; addi r3, r3, 64 }
171 /* Intentionally stall for a few cycles to leave L2 cache alone. */ 161 /* Intentionally stall for a few cycles to leave L2 cache alone. */
172 { bnzt zero, . } 162 { bnzt zero, . }
173EX: { lw r7, r3; addi r3, r3, 64 } 163EX: { lw r7, r3; addi r3, r3, 64 }
174#if !CHIP_HAS_WH64()
175 /* Prefetch the dest */
176 /* Intentionally stall for a few cycles to leave L2 cache alone. */
177 { bnzt zero, . }
178 /* Use a real load to cause a TLB miss if necessary. We aren't using
179 * r28, so this should be fine.
180 */
181EX: { lw r28, r9; addi r9, r9, 64 }
182 /* Intentionally stall for a few cycles to leave L2 cache alone. */
183 { bnzt zero, . }
184 { prefetch r9; addi r9, r9, 64 }
185 /* Intentionally stall for a few cycles to leave L2 cache alone. */
186 { bnzt zero, . }
187 { prefetch r9; addi r9, r9, 64 }
188#endif
189 /* Intentionally stall for a few cycles to leave L2 cache alone. */ 164 /* Intentionally stall for a few cycles to leave L2 cache alone. */
190 { bz zero, .Lbig_loop2 } 165 { bz zero, .Lbig_loop2 }
191 166
@@ -286,13 +261,8 @@ EX: { lw r7, r3; addi r3, r3, 64 }
286 /* Fill second L1D line. */ 261 /* Fill second L1D line. */
287EX: { lw r17, r17; addi r1, r1, 48; mvz r3, r13, r1 } /* r17 = WORD_4 */ 262EX: { lw r17, r17; addi r1, r1, 48; mvz r3, r13, r1 } /* r17 = WORD_4 */
288 263
289#if CHIP_HAS_WH64()
290 /* Prepare destination line for writing. */ 264 /* Prepare destination line for writing. */
291EX: { wh64 r9; addi r9, r9, 64 } 265EX: { wh64 r9; addi r9, r9, 64 }
292#else
293 /* Prefetch dest line */
294 { prefetch r9; addi r9, r9, 64 }
295#endif
296 /* Load seven words that are L1D hits to cover wh64 L2 usage. */ 266 /* Load seven words that are L1D hits to cover wh64 L2 usage. */
297 267
298 /* Load the three remaining words from the last L1D line, which 268 /* Load the three remaining words from the last L1D line, which
@@ -330,16 +300,7 @@ EX: { lw r18, r1; addi r1, r1, 4 } /* r18 = WORD_8 */
330EX: { sw r0, r16; addi r0, r0, 4; add r16, r0, r2 } /* store(WORD_0) */ 300EX: { sw r0, r16; addi r0, r0, 4; add r16, r0, r2 } /* store(WORD_0) */
331EX: { sw r0, r13; addi r0, r0, 4; andi r16, r16, -64 } /* store(WORD_1) */ 301EX: { sw r0, r13; addi r0, r0, 4; andi r16, r16, -64 } /* store(WORD_1) */
332EX: { sw r0, r14; addi r0, r0, 4; slt_u r16, r9, r16 } /* store(WORD_2) */ 302EX: { sw r0, r14; addi r0, r0, 4; slt_u r16, r9, r16 } /* store(WORD_2) */
333#if CHIP_HAS_WH64()
334EX: { sw r0, r15; addi r0, r0, 4; addi r13, sp, -64 } /* store(WORD_3) */ 303EX: { sw r0, r15; addi r0, r0, 4; addi r13, sp, -64 } /* store(WORD_3) */
335#else
336 /* Back up the r9 to a cache line we are already storing to
337 * if it gets past the end of the dest vector. Strictly speaking,
338 * we don't need to back up to the start of a cache line, but it's free
339 * and tidy, so why not?
340 */
341EX: { sw r0, r15; addi r0, r0, 4; andi r13, r0, -64 } /* store(WORD_3) */
342#endif
343 /* Store second L1D line. */ 304 /* Store second L1D line. */
344EX: { sw r0, r17; addi r0, r0, 4; mvz r9, r16, r13 }/* store(WORD_4) */ 305EX: { sw r0, r17; addi r0, r0, 4; mvz r9, r16, r13 }/* store(WORD_4) */
345EX: { sw r0, r19; addi r0, r0, 4 } /* store(WORD_5) */ 306EX: { sw r0, r19; addi r0, r0, 4 } /* store(WORD_5) */
@@ -403,7 +364,6 @@ EX: { sb r0, r3; addi r0, r0, 1; addi r2, r2, -1 }
403 364
404.Ldest_is_word_aligned: 365.Ldest_is_word_aligned:
405 366
406#if CHIP_HAS_DWORD_ALIGN()
407EX: { andi r8, r0, 63; lwadd_na r6, r1, 4} 367EX: { andi r8, r0, 63; lwadd_na r6, r1, 4}
408 { slti_u r9, r2, 64; bz r8, .Ldest_is_L2_line_aligned } 368 { slti_u r9, r2, 64; bz r8, .Ldest_is_L2_line_aligned }
409 369
@@ -511,26 +471,6 @@ EX: { swadd r0, r13, 4; addi r2, r2, -32 }
511 /* Move r1 back to the point where it corresponds to r0. */ 471 /* Move r1 back to the point where it corresponds to r0. */
512 { addi r1, r1, -4 } 472 { addi r1, r1, -4 }
513 473
514#else /* !CHIP_HAS_DWORD_ALIGN() */
515
516 /* Compute right/left shift counts and load initial source words. */
517 { andi r5, r1, -4; andi r3, r1, 3 }
518EX: { lw r6, r5; addi r5, r5, 4; shli r3, r3, 3 }
519EX: { lw r7, r5; addi r5, r5, 4; sub r4, zero, r3 }
520
521 /* Load and store one word at a time, using shifts and ORs
522 * to correct for the misaligned src.
523 */
524.Lcopy_unaligned_src_loop:
525 { shr r6, r6, r3; shl r8, r7, r4 }
526EX: { lw r7, r5; or r8, r8, r6; move r6, r7 }
527EX: { sw r0, r8; addi r0, r0, 4; addi r2, r2, -4 }
528 { addi r5, r5, 4; slti_u r8, r2, 8 }
529 { bzt r8, .Lcopy_unaligned_src_loop; addi r1, r1, 4 }
530
531 { bz r2, .Lcopy_unaligned_done }
532#endif /* !CHIP_HAS_DWORD_ALIGN() */
533
534 /* Fall through */ 474 /* Fall through */
535 475
536/* 476/*
@@ -614,5 +554,6 @@ memcpy_fixup_loop:
614 .size memcpy_common_fixup, . - memcpy_common_fixup 554 .size memcpy_common_fixup, . - memcpy_common_fixup
615 555
616 .section __ex_table,"a" 556 .section __ex_table,"a"
557 .align 4
617 .word .Lcfu, .Lcopy_from_user_fixup_zero_remainder 558 .word .Lcfu, .Lcopy_from_user_fixup_zero_remainder
618 .word .Lctu, .Lcopy_to_user_fixup_done 559 .word .Lctu, .Lcopy_to_user_fixup_done
diff --git a/arch/tile/lib/memcpy_64.c b/arch/tile/lib/memcpy_64.c
index c79b8e7c6828..4815354b8cd2 100644
--- a/arch/tile/lib/memcpy_64.c
+++ b/arch/tile/lib/memcpy_64.c
@@ -18,14 +18,17 @@
18/* EXPORT_SYMBOL() is in arch/tile/lib/exports.c since this should be asm. */ 18/* EXPORT_SYMBOL() is in arch/tile/lib/exports.c since this should be asm. */
19 19
20/* Must be 8 bytes in size. */ 20/* Must be 8 bytes in size. */
21#define word_t uint64_t 21#define op_t uint64_t
22 22
23#if CHIP_L2_LINE_SIZE() != 64 && CHIP_L2_LINE_SIZE() != 128 23/* Threshold value for when to enter the unrolled loops. */
24#error "Assumes 64 or 128 byte line size" 24#define OP_T_THRES 16
25
26#if CHIP_L2_LINE_SIZE() != 64
27#error "Assumes 64 byte line size"
25#endif 28#endif
26 29
27/* How many cache lines ahead should we prefetch? */ 30/* How many cache lines ahead should we prefetch? */
28#define PREFETCH_LINES_AHEAD 3 31#define PREFETCH_LINES_AHEAD 4
29 32
30/* 33/*
31 * Provide "base versions" of load and store for the normal code path. 34 * Provide "base versions" of load and store for the normal code path.
@@ -51,15 +54,16 @@ void *memcpy(void *__restrict dstv, const void *__restrict srcv, size_t n)
51 * macros to return a count of uncopied bytes due to mm fault. 54 * macros to return a count of uncopied bytes due to mm fault.
52 */ 55 */
53#define RETVAL 0 56#define RETVAL 0
54int USERCOPY_FUNC(void *__restrict dstv, const void *__restrict srcv, size_t n) 57int __attribute__((optimize("omit-frame-pointer")))
58USERCOPY_FUNC(void *__restrict dstv, const void *__restrict srcv, size_t n)
55#endif 59#endif
56{ 60{
57 char *__restrict dst1 = (char *)dstv; 61 char *__restrict dst1 = (char *)dstv;
58 const char *__restrict src1 = (const char *)srcv; 62 const char *__restrict src1 = (const char *)srcv;
59 const char *__restrict src1_end; 63 const char *__restrict src1_end;
60 const char *__restrict prefetch; 64 const char *__restrict prefetch;
61 word_t *__restrict dst8; /* 8-byte pointer to destination memory. */ 65 op_t *__restrict dst8; /* 8-byte pointer to destination memory. */
62 word_t final; /* Final bytes to write to trailing word, if any */ 66 op_t final; /* Final bytes to write to trailing word, if any */
63 long i; 67 long i;
64 68
65 if (n < 16) { 69 if (n < 16) {
@@ -79,104 +83,228 @@ int USERCOPY_FUNC(void *__restrict dstv, const void *__restrict srcv, size_t n)
79 for (i = 0; i < PREFETCH_LINES_AHEAD; i++) { 83 for (i = 0; i < PREFETCH_LINES_AHEAD; i++) {
80 __insn_prefetch(prefetch); 84 __insn_prefetch(prefetch);
81 prefetch += CHIP_L2_LINE_SIZE(); 85 prefetch += CHIP_L2_LINE_SIZE();
82 prefetch = (prefetch > src1_end) ? prefetch : src1; 86 prefetch = (prefetch < src1_end) ? prefetch : src1;
83 } 87 }
84 88
85 /* Copy bytes until dst is word-aligned. */ 89 /* Copy bytes until dst is word-aligned. */
86 for (; (uintptr_t)dst1 & (sizeof(word_t) - 1); n--) 90 for (; (uintptr_t)dst1 & (sizeof(op_t) - 1); n--)
87 ST1(dst1++, LD1(src1++)); 91 ST1(dst1++, LD1(src1++));
88 92
89 /* 8-byte pointer to destination memory. */ 93 /* 8-byte pointer to destination memory. */
90 dst8 = (word_t *)dst1; 94 dst8 = (op_t *)dst1;
91 95
92 if (__builtin_expect((uintptr_t)src1 & (sizeof(word_t) - 1), 0)) { 96 if (__builtin_expect((uintptr_t)src1 & (sizeof(op_t) - 1), 0)) {
93 /* 97 /* Unaligned copy. */
94 * Misaligned copy. Copy 8 bytes at a time, but don't 98
95 * bother with other fanciness. 99 op_t tmp0 = 0, tmp1 = 0, tmp2, tmp3;
96 * 100 const op_t *src8 = (const op_t *) ((uintptr_t)src1 &
97 * TODO: Consider prefetching and using wh64 as well. 101 -sizeof(op_t));
98 */ 102 const void *srci = (void *)src1;
99 103 int m;
100 /* Create an aligned src8. */ 104
101 const word_t *__restrict src8 = 105 m = (CHIP_L2_LINE_SIZE() << 2) -
102 (const word_t *)((uintptr_t)src1 & -sizeof(word_t)); 106 (((uintptr_t)dst8) & ((CHIP_L2_LINE_SIZE() << 2) - 1));
103 word_t b; 107 m = (n < m) ? n : m;
104 108 m /= sizeof(op_t);
105 word_t a = LD8(src8++); 109
106 for (; n >= sizeof(word_t); n -= sizeof(word_t)) { 110 /* Copy until 'dst' is cache-line-aligned. */
107 b = LD8(src8++); 111 n -= (sizeof(op_t) * m);
108 a = __insn_dblalign(a, b, src1); 112
109 ST8(dst8++, a); 113 switch (m % 4) {
110 a = b; 114 case 0:
115 if (__builtin_expect(!m, 0))
116 goto _M0;
117 tmp1 = LD8(src8++);
118 tmp2 = LD8(src8++);
119 goto _8B3;
120 case 2:
121 m += 2;
122 tmp3 = LD8(src8++);
123 tmp0 = LD8(src8++);
124 goto _8B1;
125 case 3:
126 m += 1;
127 tmp2 = LD8(src8++);
128 tmp3 = LD8(src8++);
129 goto _8B2;
130 case 1:
131 m--;
132 tmp0 = LD8(src8++);
133 tmp1 = LD8(src8++);
134 if (__builtin_expect(!m, 0))
135 goto _8B0;
136 }
137
138 do {
139 tmp2 = LD8(src8++);
140 tmp0 = __insn_dblalign(tmp0, tmp1, srci);
141 ST8(dst8++, tmp0);
142_8B3:
143 tmp3 = LD8(src8++);
144 tmp1 = __insn_dblalign(tmp1, tmp2, srci);
145 ST8(dst8++, tmp1);
146_8B2:
147 tmp0 = LD8(src8++);
148 tmp2 = __insn_dblalign(tmp2, tmp3, srci);
149 ST8(dst8++, tmp2);
150_8B1:
151 tmp1 = LD8(src8++);
152 tmp3 = __insn_dblalign(tmp3, tmp0, srci);
153 ST8(dst8++, tmp3);
154 m -= 4;
155 } while (m);
156
157_8B0:
158 tmp0 = __insn_dblalign(tmp0, tmp1, srci);
159 ST8(dst8++, tmp0);
160 src8--;
161
162_M0:
163 if (__builtin_expect(n >= CHIP_L2_LINE_SIZE(), 0)) {
164 op_t tmp4, tmp5, tmp6, tmp7, tmp8;
165
166 prefetch = ((const char *)src8) +
167 CHIP_L2_LINE_SIZE() * PREFETCH_LINES_AHEAD;
168
169 for (tmp0 = LD8(src8++); n >= CHIP_L2_LINE_SIZE();
170 n -= CHIP_L2_LINE_SIZE()) {
171 /* Prefetch and advance to next line to
172 prefetch, but don't go past the end. */
173 __insn_prefetch(prefetch);
174
175 /* Make sure prefetch got scheduled
176 earlier. */
177 __asm__ ("" : : : "memory");
178
179 prefetch += CHIP_L2_LINE_SIZE();
180 prefetch = (prefetch < src1_end) ? prefetch :
181 (const char *) src8;
182
183 tmp1 = LD8(src8++);
184 tmp2 = LD8(src8++);
185 tmp3 = LD8(src8++);
186 tmp4 = LD8(src8++);
187 tmp5 = LD8(src8++);
188 tmp6 = LD8(src8++);
189 tmp7 = LD8(src8++);
190 tmp8 = LD8(src8++);
191
192 tmp0 = __insn_dblalign(tmp0, tmp1, srci);
193 tmp1 = __insn_dblalign(tmp1, tmp2, srci);
194 tmp2 = __insn_dblalign(tmp2, tmp3, srci);
195 tmp3 = __insn_dblalign(tmp3, tmp4, srci);
196 tmp4 = __insn_dblalign(tmp4, tmp5, srci);
197 tmp5 = __insn_dblalign(tmp5, tmp6, srci);
198 tmp6 = __insn_dblalign(tmp6, tmp7, srci);
199 tmp7 = __insn_dblalign(tmp7, tmp8, srci);
200
201 __insn_wh64(dst8);
202
203 ST8(dst8++, tmp0);
204 ST8(dst8++, tmp1);
205 ST8(dst8++, tmp2);
206 ST8(dst8++, tmp3);
207 ST8(dst8++, tmp4);
208 ST8(dst8++, tmp5);
209 ST8(dst8++, tmp6);
210 ST8(dst8++, tmp7);
211
212 tmp0 = tmp8;
213 }
214 src8--;
215 }
216
217 /* Copy the rest 8-byte chunks. */
218 if (n >= sizeof(op_t)) {
219 tmp0 = LD8(src8++);
220 for (; n >= sizeof(op_t); n -= sizeof(op_t)) {
221 tmp1 = LD8(src8++);
222 tmp0 = __insn_dblalign(tmp0, tmp1, srci);
223 ST8(dst8++, tmp0);
224 tmp0 = tmp1;
225 }
226 src8--;
111 } 227 }
112 228
113 if (n == 0) 229 if (n == 0)
114 return RETVAL; 230 return RETVAL;
115 231
116 b = ((const char *)src8 <= src1_end) ? *src8 : 0; 232 tmp0 = LD8(src8++);
233 tmp1 = ((const char *)src8 <= src1_end)
234 ? LD8((op_t *)src8) : 0;
235 final = __insn_dblalign(tmp0, tmp1, srci);
117 236
118 /*
119 * Final source bytes to write to trailing partial
120 * word, if any.
121 */
122 final = __insn_dblalign(a, b, src1);
123 } else { 237 } else {
124 /* Aligned copy. */ 238 /* Aligned copy. */
125 239
126 const word_t* __restrict src8 = (const word_t *)src1; 240 const op_t *__restrict src8 = (const op_t *)src1;
127 241
128 /* src8 and dst8 are both word-aligned. */ 242 /* src8 and dst8 are both word-aligned. */
129 if (n >= CHIP_L2_LINE_SIZE()) { 243 if (n >= CHIP_L2_LINE_SIZE()) {
130 /* Copy until 'dst' is cache-line-aligned. */ 244 /* Copy until 'dst' is cache-line-aligned. */
131 for (; (uintptr_t)dst8 & (CHIP_L2_LINE_SIZE() - 1); 245 for (; (uintptr_t)dst8 & (CHIP_L2_LINE_SIZE() - 1);
132 n -= sizeof(word_t)) 246 n -= sizeof(op_t))
133 ST8(dst8++, LD8(src8++)); 247 ST8(dst8++, LD8(src8++));
134 248
135 for (; n >= CHIP_L2_LINE_SIZE(); ) { 249 for (; n >= CHIP_L2_LINE_SIZE(); ) {
136 __insn_wh64(dst8); 250 op_t tmp0, tmp1, tmp2, tmp3;
251 op_t tmp4, tmp5, tmp6, tmp7;
137 252
138 /* 253 /*
139 * Prefetch and advance to next line 254 * Prefetch and advance to next line
140 * to prefetch, but don't go past the end 255 * to prefetch, but don't go past the
256 * end.
141 */ 257 */
142 __insn_prefetch(prefetch); 258 __insn_prefetch(prefetch);
259
260 /* Make sure prefetch got scheduled
261 earlier. */
262 __asm__ ("" : : : "memory");
263
143 prefetch += CHIP_L2_LINE_SIZE(); 264 prefetch += CHIP_L2_LINE_SIZE();
144 prefetch = (prefetch > src1_end) ? prefetch : 265 prefetch = (prefetch < src1_end) ? prefetch :
145 (const char *)src8; 266 (const char *)src8;
146 267
147 /* 268 /*
148 * Copy an entire cache line. Manually 269 * Do all the loads before wh64. This
149 * unrolled to avoid idiosyncracies of 270 * is necessary if [src8, src8+7] and
150 * compiler unrolling. 271 * [dst8, dst8+7] share the same cache
272 * line and dst8 <= src8, as can be
273 * the case when called from memmove,
274 * or with code tested on x86 whose
275 * memcpy always works with forward
276 * copies.
151 */ 277 */
152#define COPY_WORD(offset) ({ ST8(dst8+offset, LD8(src8+offset)); n -= 8; }) 278 tmp0 = LD8(src8++);
153 COPY_WORD(0); 279 tmp1 = LD8(src8++);
154 COPY_WORD(1); 280 tmp2 = LD8(src8++);
155 COPY_WORD(2); 281 tmp3 = LD8(src8++);
156 COPY_WORD(3); 282 tmp4 = LD8(src8++);
157 COPY_WORD(4); 283 tmp5 = LD8(src8++);
158 COPY_WORD(5); 284 tmp6 = LD8(src8++);
159 COPY_WORD(6); 285 tmp7 = LD8(src8++);
160 COPY_WORD(7); 286
161#if CHIP_L2_LINE_SIZE() == 128 287 /* wh64 and wait for tmp7 load completion. */
162 COPY_WORD(8); 288 __asm__ ("move %0, %0; wh64 %1\n"
163 COPY_WORD(9); 289 : : "r"(tmp7), "r"(dst8));
164 COPY_WORD(10);
165 COPY_WORD(11);
166 COPY_WORD(12);
167 COPY_WORD(13);
168 COPY_WORD(14);
169 COPY_WORD(15);
170#elif CHIP_L2_LINE_SIZE() != 64
171# error Fix code that assumes particular L2 cache line sizes
172#endif
173 290
174 dst8 += CHIP_L2_LINE_SIZE() / sizeof(word_t); 291 ST8(dst8++, tmp0);
175 src8 += CHIP_L2_LINE_SIZE() / sizeof(word_t); 292 ST8(dst8++, tmp1);
293 ST8(dst8++, tmp2);
294 ST8(dst8++, tmp3);
295 ST8(dst8++, tmp4);
296 ST8(dst8++, tmp5);
297 ST8(dst8++, tmp6);
298 ST8(dst8++, tmp7);
299
300 n -= CHIP_L2_LINE_SIZE();
176 } 301 }
302#if CHIP_L2_LINE_SIZE() != 64
303# error "Fix code that assumes particular L2 cache line size."
304#endif
177 } 305 }
178 306
179 for (; n >= sizeof(word_t); n -= sizeof(word_t)) 307 for (; n >= sizeof(op_t); n -= sizeof(op_t))
180 ST8(dst8++, LD8(src8++)); 308 ST8(dst8++, LD8(src8++));
181 309
182 if (__builtin_expect(n == 0, 1)) 310 if (__builtin_expect(n == 0, 1))
diff --git a/arch/tile/lib/memcpy_tile64.c b/arch/tile/lib/memcpy_tile64.c
deleted file mode 100644
index 3bc4b4e40d93..000000000000
--- a/arch/tile/lib/memcpy_tile64.c
+++ /dev/null
@@ -1,276 +0,0 @@
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 kmap_atomic 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 type0, type1;
68 int cpu = get_cpu();
69
70 /*
71 * Disable interrupts so that we don't recurse into memcpy()
72 * in an interrupt handler, nor accidentally reference
73 * the PA of the source from an interrupt routine. Also
74 * notify the simulator that we're playing games so we don't
75 * generate spurious coherency warnings.
76 */
77 local_irq_save(flags);
78 sim_allow_multiple_caching(1);
79
80 /* Set up the new dest mapping */
81 type0 = kmap_atomic_idx_push();
82 idx = FIX_KMAP_BEGIN + (KM_TYPE_NR * cpu) + type0;
83 newdst = __fix_to_virt(idx) + ((unsigned long)dest & (PAGE_SIZE-1));
84 pmdp = pmd_offset(pud_offset(pgd_offset_k(newdst), newdst), newdst);
85 ptep = pte_offset_kernel(pmdp, newdst);
86 if (pte_val(*ptep) != pte_val(dst_pte)) {
87 set_pte(ptep, dst_pte);
88 local_flush_tlb_page(NULL, newdst, PAGE_SIZE);
89 }
90
91 /* Set up the new source mapping */
92 type1 = kmap_atomic_idx_push();
93 idx += (type0 - type1);
94 src_pte = hv_pte_set_nc(src_pte);
95 src_pte = hv_pte_clear_writable(src_pte); /* be paranoid */
96 newsrc = __fix_to_virt(idx) + ((unsigned long)source & (PAGE_SIZE-1));
97 pmdp = pmd_offset(pud_offset(pgd_offset_k(newsrc), newsrc), newsrc);
98 ptep = pte_offset_kernel(pmdp, newsrc);
99 __set_pte(ptep, src_pte); /* set_pte() would be confused by this */
100 local_flush_tlb_page(NULL, newsrc, PAGE_SIZE);
101
102 /* Actually move the data. */
103 __memcpy_asm((void *)newdst, (const void *)newsrc, len);
104
105 /*
106 * Remap the source as locally-cached and not OLOC'ed so that
107 * we can inval without also invaling the remote cpu's cache.
108 * This also avoids known errata with inv'ing cacheable oloc data.
109 */
110 src_pte = hv_pte_set_mode(src_pte, HV_PTE_MODE_CACHE_NO_L3);
111 src_pte = hv_pte_set_writable(src_pte); /* need write access for inv */
112 __set_pte(ptep, src_pte); /* set_pte() would be confused by this */
113 local_flush_tlb_page(NULL, newsrc, PAGE_SIZE);
114
115 /*
116 * Do the actual invalidation, covering the full L2 cache line
117 * at the end since __memcpy_asm() is somewhat aggressive.
118 */
119 __inv_buffer((void *)newsrc, len);
120
121 /*
122 * We're done: notify the simulator that all is back to normal,
123 * and re-enable interrupts and pre-emption.
124 */
125 kmap_atomic_idx_pop();
126 kmap_atomic_idx_pop();
127 sim_allow_multiple_caching(0);
128 local_irq_restore(flags);
129 put_cpu();
130}
131
132/*
133 * Identify large copies from remotely-cached memory, and copy them
134 * via memcpy_multicache() if they look good, otherwise fall back
135 * to the particular kind of copying passed as the memcpy_t function.
136 */
137static unsigned long fast_copy(void *dest, const void *source, int len,
138 memcpy_t func)
139{
140 /*
141 * Check if it's big enough to bother with. We may end up doing a
142 * small copy via TLB manipulation if we're near a page boundary,
143 * but presumably we'll make it up when we hit the second page.
144 */
145 while (len >= LARGE_COPY_CUTOFF) {
146 int copy_size, bytes_left_on_page;
147 pte_t *src_ptep, *dst_ptep;
148 pte_t src_pte, dst_pte;
149 struct page *src_page, *dst_page;
150
151 /* Is the source page oloc'ed to a remote cpu? */
152retry_source:
153 src_ptep = virt_to_pte(current->mm, (unsigned long)source);
154 if (src_ptep == NULL)
155 break;
156 src_pte = *src_ptep;
157 if (!hv_pte_get_present(src_pte) ||
158 !hv_pte_get_readable(src_pte) ||
159 hv_pte_get_mode(src_pte) != HV_PTE_MODE_CACHE_TILE_L3)
160 break;
161 if (get_remote_cache_cpu(src_pte) == smp_processor_id())
162 break;
163 src_page = pfn_to_page(pte_pfn(src_pte));
164 get_page(src_page);
165 if (pte_val(src_pte) != pte_val(*src_ptep)) {
166 put_page(src_page);
167 goto retry_source;
168 }
169 if (pte_huge(src_pte)) {
170 /* Adjust the PTE to correspond to a small page */
171 int pfn = pte_pfn(src_pte);
172 pfn += (((unsigned long)source & (HPAGE_SIZE-1))
173 >> PAGE_SHIFT);
174 src_pte = pfn_pte(pfn, src_pte);
175 src_pte = pte_mksmall(src_pte);
176 }
177
178 /* Is the destination page writable? */
179retry_dest:
180 dst_ptep = virt_to_pte(current->mm, (unsigned long)dest);
181 if (dst_ptep == NULL) {
182 put_page(src_page);
183 break;
184 }
185 dst_pte = *dst_ptep;
186 if (!hv_pte_get_present(dst_pte) ||
187 !hv_pte_get_writable(dst_pte)) {
188 put_page(src_page);
189 break;
190 }
191 dst_page = pfn_to_page(pte_pfn(dst_pte));
192 if (dst_page == src_page) {
193 /*
194 * Source and dest are on the same page; this
195 * potentially exposes us to incoherence if any
196 * part of src and dest overlap on a cache line.
197 * Just give up rather than trying to be precise.
198 */
199 put_page(src_page);
200 break;
201 }
202 get_page(dst_page);
203 if (pte_val(dst_pte) != pte_val(*dst_ptep)) {
204 put_page(dst_page);
205 goto retry_dest;
206 }
207 if (pte_huge(dst_pte)) {
208 /* Adjust the PTE to correspond to a small page */
209 int pfn = pte_pfn(dst_pte);
210 pfn += (((unsigned long)dest & (HPAGE_SIZE-1))
211 >> PAGE_SHIFT);
212 dst_pte = pfn_pte(pfn, dst_pte);
213 dst_pte = pte_mksmall(dst_pte);
214 }
215
216 /* All looks good: create a cachable PTE and copy from it */
217 copy_size = len;
218 bytes_left_on_page =
219 PAGE_SIZE - (((int)source) & (PAGE_SIZE-1));
220 if (copy_size > bytes_left_on_page)
221 copy_size = bytes_left_on_page;
222 bytes_left_on_page =
223 PAGE_SIZE - (((int)dest) & (PAGE_SIZE-1));
224 if (copy_size > bytes_left_on_page)
225 copy_size = bytes_left_on_page;
226 memcpy_multicache(dest, source, dst_pte, src_pte, copy_size);
227
228 /* Release the pages */
229 put_page(dst_page);
230 put_page(src_page);
231
232 /* Continue on the next page */
233 dest += copy_size;
234 source += copy_size;
235 len -= copy_size;
236 }
237
238 return func(dest, source, len);
239}
240
241void *memcpy(void *to, const void *from, __kernel_size_t n)
242{
243 if (n < LARGE_COPY_CUTOFF)
244 return (void *)__memcpy_asm(to, from, n);
245 else
246 return (void *)fast_copy(to, from, n, __memcpy_asm);
247}
248
249unsigned long __copy_to_user_inatomic(void __user *to, const void *from,
250 unsigned long n)
251{
252 if (n < LARGE_COPY_CUTOFF)
253 return __copy_to_user_inatomic_asm(to, from, n);
254 else
255 return fast_copy(to, from, n, __copy_to_user_inatomic_asm);
256}
257
258unsigned long __copy_from_user_inatomic(void *to, const void __user *from,
259 unsigned long n)
260{
261 if (n < LARGE_COPY_CUTOFF)
262 return __copy_from_user_inatomic_asm(to, from, n);
263 else
264 return fast_copy(to, from, n, __copy_from_user_inatomic_asm);
265}
266
267unsigned long __copy_from_user_zeroing(void *to, const void __user *from,
268 unsigned long n)
269{
270 if (n < LARGE_COPY_CUTOFF)
271 return __copy_from_user_zeroing_asm(to, from, n);
272 else
273 return fast_copy(to, from, n, __copy_from_user_zeroing_asm);
274}
275
276#endif /* !CHIP_HAS_COHERENT_LOCAL_CACHE() */
diff --git a/arch/tile/lib/memcpy_user_64.c b/arch/tile/lib/memcpy_user_64.c
index 37440caa7370..88c7016492c4 100644
--- a/arch/tile/lib/memcpy_user_64.c
+++ b/arch/tile/lib/memcpy_user_64.c
@@ -31,6 +31,7 @@
31 ".pushsection .coldtext.memcpy,\"ax\";" \ 31 ".pushsection .coldtext.memcpy,\"ax\";" \
32 "2: { move r0, %2; jrp lr };" \ 32 "2: { move r0, %2; jrp lr };" \
33 ".section __ex_table,\"a\";" \ 33 ".section __ex_table,\"a\";" \
34 ".align 8;" \
34 ".quad 1b, 2b;" \ 35 ".quad 1b, 2b;" \
35 ".popsection" \ 36 ".popsection" \
36 : "=m" (*(p)) : "r" (v), "r" (n)); \ 37 : "=m" (*(p)) : "r" (v), "r" (n)); \
@@ -43,6 +44,7 @@
43 ".pushsection .coldtext.memcpy,\"ax\";" \ 44 ".pushsection .coldtext.memcpy,\"ax\";" \
44 "2: { move r0, %2; jrp lr };" \ 45 "2: { move r0, %2; jrp lr };" \
45 ".section __ex_table,\"a\";" \ 46 ".section __ex_table,\"a\";" \
47 ".align 8;" \
46 ".quad 1b, 2b;" \ 48 ".quad 1b, 2b;" \
47 ".popsection" \ 49 ".popsection" \
48 : "=r" (__v) : "m" (*(p)), "r" (n)); \ 50 : "=r" (__v) : "m" (*(p)), "r" (n)); \
diff --git a/arch/tile/lib/memset_32.c b/arch/tile/lib/memset_32.c
index 57dbb3a5bff8..2042bfe6595f 100644
--- a/arch/tile/lib/memset_32.c
+++ b/arch/tile/lib/memset_32.c
@@ -12,13 +12,10 @@
12 * more details. 12 * more details.
13 */ 13 */
14 14
15#include <arch/chip.h>
16
17#include <linux/types.h> 15#include <linux/types.h>
18#include <linux/string.h> 16#include <linux/string.h>
19#include <linux/module.h> 17#include <linux/module.h>
20 18#include <arch/chip.h>
21#undef memset
22 19
23void *memset(void *s, int c, size_t n) 20void *memset(void *s, int c, size_t n)
24{ 21{
@@ -26,11 +23,7 @@ void *memset(void *s, int c, size_t n)
26 int n32; 23 int n32;
27 uint32_t v16, v32; 24 uint32_t v16, v32;
28 uint8_t *out8 = s; 25 uint8_t *out8 = s;
29#if !CHIP_HAS_WH64()
30 int ahead32;
31#else
32 int to_align32; 26 int to_align32;
33#endif
34 27
35 /* Experimentation shows that a trivial tight loop is a win up until 28 /* Experimentation shows that a trivial tight loop is a win up until
36 * around a size of 20, where writing a word at a time starts to win. 29 * around a size of 20, where writing a word at a time starts to win.
@@ -61,21 +54,6 @@ void *memset(void *s, int c, size_t n)
61 return s; 54 return s;
62 } 55 }
63 56
64#if !CHIP_HAS_WH64()
65 /* Use a spare issue slot to start prefetching the first cache
66 * line early. This instruction is free as the store can be buried
67 * in otherwise idle issue slots doing ALU ops.
68 */
69 __insn_prefetch(out8);
70
71 /* We prefetch the end so that a short memset that spans two cache
72 * lines gets some prefetching benefit. Again we believe this is free
73 * to issue.
74 */
75 __insn_prefetch(&out8[n - 1]);
76#endif /* !CHIP_HAS_WH64() */
77
78
79 /* Align 'out8'. We know n >= 3 so this won't write past the end. */ 57 /* Align 'out8'. We know n >= 3 so this won't write past the end. */
80 while (((uintptr_t) out8 & 3) != 0) { 58 while (((uintptr_t) out8 & 3) != 0) {
81 *out8++ = c; 59 *out8++ = c;
@@ -96,90 +74,6 @@ void *memset(void *s, int c, size_t n)
96 /* This must be at least 8 or the following loop doesn't work. */ 74 /* This must be at least 8 or the following loop doesn't work. */
97#define CACHE_LINE_SIZE_IN_WORDS (CHIP_L2_LINE_SIZE() / 4) 75#define CACHE_LINE_SIZE_IN_WORDS (CHIP_L2_LINE_SIZE() / 4)
98 76
99#if !CHIP_HAS_WH64()
100
101 ahead32 = CACHE_LINE_SIZE_IN_WORDS;
102
103 /* We already prefetched the first and last cache lines, so
104 * we only need to do more prefetching if we are storing
105 * to more than two cache lines.
106 */
107 if (n32 > CACHE_LINE_SIZE_IN_WORDS * 2) {
108 int i;
109
110 /* Prefetch the next several cache lines.
111 * This is the setup code for the software-pipelined
112 * loop below.
113 */
114#define MAX_PREFETCH 5
115 ahead32 = n32 & -CACHE_LINE_SIZE_IN_WORDS;
116 if (ahead32 > MAX_PREFETCH * CACHE_LINE_SIZE_IN_WORDS)
117 ahead32 = MAX_PREFETCH * CACHE_LINE_SIZE_IN_WORDS;
118
119 for (i = CACHE_LINE_SIZE_IN_WORDS;
120 i < ahead32; i += CACHE_LINE_SIZE_IN_WORDS)
121 __insn_prefetch(&out32[i]);
122 }
123
124 if (n32 > ahead32) {
125 while (1) {
126 int j;
127
128 /* Prefetch by reading one word several cache lines
129 * ahead. Since loads are non-blocking this will
130 * cause the full cache line to be read while we are
131 * finishing earlier cache lines. Using a store
132 * here causes microarchitectural performance
133 * problems where a victimizing store miss goes to
134 * the head of the retry FIFO and locks the pipe for
135 * a few cycles. So a few subsequent stores in this
136 * loop go into the retry FIFO, and then later
137 * stores see other stores to the same cache line
138 * are already in the retry FIFO and themselves go
139 * into the retry FIFO, filling it up and grinding
140 * to a halt waiting for the original miss to be
141 * satisfied.
142 */
143 __insn_prefetch(&out32[ahead32]);
144
145#if CACHE_LINE_SIZE_IN_WORDS % 4 != 0
146#error "Unhandled CACHE_LINE_SIZE_IN_WORDS"
147#endif
148
149 n32 -= CACHE_LINE_SIZE_IN_WORDS;
150
151 /* Save icache space by only partially unrolling
152 * this loop.
153 */
154 for (j = CACHE_LINE_SIZE_IN_WORDS / 4; j > 0; j--) {
155 *out32++ = v32;
156 *out32++ = v32;
157 *out32++ = v32;
158 *out32++ = v32;
159 }
160
161 /* To save compiled code size, reuse this loop even
162 * when we run out of prefetching to do by dropping
163 * ahead32 down.
164 */
165 if (n32 <= ahead32) {
166 /* Not even a full cache line left,
167 * so stop now.
168 */
169 if (n32 < CACHE_LINE_SIZE_IN_WORDS)
170 break;
171
172 /* Choose a small enough value that we don't
173 * prefetch past the end. There's no sense
174 * in touching cache lines we don't have to.
175 */
176 ahead32 = CACHE_LINE_SIZE_IN_WORDS - 1;
177 }
178 }
179 }
180
181#else /* CHIP_HAS_WH64() */
182
183 /* Determine how many words we need to emit before the 'out32' 77 /* Determine how many words we need to emit before the 'out32'
184 * pointer becomes aligned modulo the cache line size. 78 * pointer becomes aligned modulo the cache line size.
185 */ 79 */
@@ -236,8 +130,6 @@ void *memset(void *s, int c, size_t n)
236 n32 &= CACHE_LINE_SIZE_IN_WORDS - 1; 130 n32 &= CACHE_LINE_SIZE_IN_WORDS - 1;
237 } 131 }
238 132
239#endif /* CHIP_HAS_WH64() */
240
241 /* Now handle any leftover values. */ 133 /* Now handle any leftover values. */
242 if (n32 != 0) { 134 if (n32 != 0) {
243 do { 135 do {
diff --git a/arch/tile/lib/memset_64.c b/arch/tile/lib/memset_64.c
index 3873085711d5..03ef69cd73de 100644
--- a/arch/tile/lib/memset_64.c
+++ b/arch/tile/lib/memset_64.c
@@ -12,13 +12,11 @@
12 * more details. 12 * more details.
13 */ 13 */
14 14
15#include <arch/chip.h>
16
17#include <linux/types.h> 15#include <linux/types.h>
18#include <linux/string.h> 16#include <linux/string.h>
19#include <linux/module.h> 17#include <linux/module.h>
20 18#include <arch/chip.h>
21#undef memset 19#include "string-endian.h"
22 20
23void *memset(void *s, int c, size_t n) 21void *memset(void *s, int c, size_t n)
24{ 22{
@@ -70,8 +68,7 @@ void *memset(void *s, int c, size_t n)
70 n64 = n >> 3; 68 n64 = n >> 3;
71 69
72 /* Tile input byte out to 64 bits. */ 70 /* Tile input byte out to 64 bits. */
73 /* KLUDGE */ 71 v64 = copy_byte(c);
74 v64 = 0x0101010101010101ULL * (uint8_t)c;
75 72
76 /* This must be at least 8 or the following loop doesn't work. */ 73 /* This must be at least 8 or the following loop doesn't work. */
77#define CACHE_LINE_SIZE_IN_DOUBLEWORDS (CHIP_L2_LINE_SIZE() / 8) 74#define CACHE_LINE_SIZE_IN_DOUBLEWORDS (CHIP_L2_LINE_SIZE() / 8)
diff --git a/arch/tile/lib/strchr_32.c b/arch/tile/lib/strchr_32.c
index c94e6f7ae7b5..841fe6963019 100644
--- a/arch/tile/lib/strchr_32.c
+++ b/arch/tile/lib/strchr_32.c
@@ -16,8 +16,6 @@
16#include <linux/string.h> 16#include <linux/string.h>
17#include <linux/module.h> 17#include <linux/module.h>
18 18
19#undef strchr
20
21char *strchr(const char *s, int c) 19char *strchr(const char *s, int c)
22{ 20{
23 int z, g; 21 int z, g;
diff --git a/arch/tile/lib/strchr_64.c b/arch/tile/lib/strchr_64.c
index f39f9dc422b0..fe6e31c06f8d 100644
--- a/arch/tile/lib/strchr_64.c
+++ b/arch/tile/lib/strchr_64.c
@@ -26,7 +26,7 @@ char *strchr(const char *s, int c)
26 const uint64_t *p = (const uint64_t *)(s_int & -8); 26 const uint64_t *p = (const uint64_t *)(s_int & -8);
27 27
28 /* Create eight copies of the byte for which we are looking. */ 28 /* Create eight copies of the byte for which we are looking. */
29 const uint64_t goal = 0x0101010101010101ULL * (uint8_t) c; 29 const uint64_t goal = copy_byte(c);
30 30
31 /* Read the first aligned word, but force bytes before the string to 31 /* Read the first aligned word, but force bytes before the string to
32 * match neither zero nor goal (we make sure the high bit of each 32 * match neither zero nor goal (we make sure the high bit of each
diff --git a/arch/tile/lib/string-endian.h b/arch/tile/lib/string-endian.h
index c0eed7ce69c3..2e49cbfe9371 100644
--- a/arch/tile/lib/string-endian.h
+++ b/arch/tile/lib/string-endian.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright 2011 Tilera Corporation. All Rights Reserved. 2 * Copyright 2013 Tilera Corporation. All Rights Reserved.
3 * 3 *
4 * This program is free software; you can redistribute it and/or 4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License 5 * modify it under the terms of the GNU General Public License
@@ -31,3 +31,14 @@
31#define CFZ(x) __insn_clz(x) 31#define CFZ(x) __insn_clz(x)
32#define REVCZ(x) __insn_ctz(x) 32#define REVCZ(x) __insn_ctz(x)
33#endif 33#endif
34
35/*
36 * Create eight copies of the byte in a uint64_t. Byte Shuffle uses
37 * the bytes of srcB as the index into the dest vector to select a
38 * byte. With all indices of zero, the first byte is copied into all
39 * the other bytes.
40 */
41static inline uint64_t copy_byte(uint8_t byte)
42{
43 return __insn_shufflebytes(byte, 0, 0);
44}
diff --git a/arch/tile/lib/strlen_32.c b/arch/tile/lib/strlen_32.c
index 4974292a5534..f26f88e11e4a 100644
--- a/arch/tile/lib/strlen_32.c
+++ b/arch/tile/lib/strlen_32.c
@@ -16,8 +16,6 @@
16#include <linux/string.h> 16#include <linux/string.h>
17#include <linux/module.h> 17#include <linux/module.h>
18 18
19#undef strlen
20
21size_t strlen(const char *s) 19size_t strlen(const char *s)
22{ 20{
23 /* Get an aligned pointer. */ 21 /* Get an aligned pointer. */
diff --git a/arch/tile/lib/strnlen_32.c b/arch/tile/lib/strnlen_32.c
new file mode 100644
index 000000000000..1434141d9e01
--- /dev/null
+++ b/arch/tile/lib/strnlen_32.c
@@ -0,0 +1,47 @@
1/*
2 * Copyright 2013 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 strnlen(const char *s, size_t count)
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 size_t bytes_read = sizeof(*p) - (s_int & (sizeof(*p) - 1));
25 size_t len;
26 uint32_t v, bits;
27
28 /* Avoid page fault risk by not reading any bytes when count is 0. */
29 if (count == 0)
30 return 0;
31
32 /* Read first word, but force bytes before the string to be nonzero. */
33 v = *p | ((1 << ((s_int << 3) & 31)) - 1);
34
35 while ((bits = __insn_seqb(v, 0)) == 0) {
36 if (bytes_read >= count) {
37 /* Read COUNT bytes and didn't find the terminator. */
38 return count;
39 }
40 v = *++p;
41 bytes_read += sizeof(v);
42 }
43
44 len = ((const char *) p) + (__insn_ctz(bits) >> 3) - s;
45 return (len < count ? len : count);
46}
47EXPORT_SYMBOL(strnlen);
diff --git a/arch/tile/lib/strnlen_64.c b/arch/tile/lib/strnlen_64.c
new file mode 100644
index 000000000000..2e8de6a5136f
--- /dev/null
+++ b/arch/tile/lib/strnlen_64.c
@@ -0,0 +1,48 @@
1/*
2 * Copyright 2013 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#include "string-endian.h"
19
20size_t strnlen(const char *s, size_t count)
21{
22 /* Get an aligned pointer. */
23 const uintptr_t s_int = (uintptr_t) s;
24 const uint64_t *p = (const uint64_t *)(s_int & -8);
25 size_t bytes_read = sizeof(*p) - (s_int & (sizeof(*p) - 1));
26 size_t len;
27 uint64_t v, bits;
28
29 /* Avoid page fault risk by not reading any bytes when count is 0. */
30 if (count == 0)
31 return 0;
32
33 /* Read and MASK the first word. */
34 v = *p | MASK(s_int);
35
36 while ((bits = __insn_v1cmpeqi(v, 0)) == 0) {
37 if (bytes_read >= count) {
38 /* Read COUNT bytes and didn't find the terminator. */
39 return count;
40 }
41 v = *++p;
42 bytes_read += sizeof(v);
43 }
44
45 len = ((const char *) p) + (CFZ(bits) >> 3) - s;
46 return (len < count ? len : count);
47}
48EXPORT_SYMBOL(strnlen);
diff --git a/arch/tile/lib/usercopy_32.S b/arch/tile/lib/usercopy_32.S
index b62d002af009..1bc162224638 100644
--- a/arch/tile/lib/usercopy_32.S
+++ b/arch/tile/lib/usercopy_32.S
@@ -36,6 +36,7 @@ strnlen_user_fault:
36 { move r0, zero; jrp lr } 36 { move r0, zero; jrp lr }
37 ENDPROC(strnlen_user_fault) 37 ENDPROC(strnlen_user_fault)
38 .section __ex_table,"a" 38 .section __ex_table,"a"
39 .align 4
39 .word 1b, strnlen_user_fault 40 .word 1b, strnlen_user_fault
40 .popsection 41 .popsection
41 42
@@ -47,18 +48,20 @@ strnlen_user_fault:
47 */ 48 */
48STD_ENTRY(strncpy_from_user_asm) 49STD_ENTRY(strncpy_from_user_asm)
49 { bz r2, 2f; move r3, r0 } 50 { bz r2, 2f; move r3, r0 }
501: { lb_u r4, r1; addi r1, r1, 1; addi r2, r2, -1 } 511: { lb_u r4, r1; addi r1, r1, 1; addi r2, r2, -1 }
51 { sb r0, r4; addi r0, r0, 1 } 52 { sb r0, r4; addi r0, r0, 1 }
52 bz r2, 2f 53 bz r4, 2f
53 bnzt r4, 1b 54 bnzt r2, 1b
54 addi r0, r0, -1 /* don't count the trailing NUL */ 55 { sub r0, r0, r3; jrp lr }
552: { sub r0, r0, r3; jrp lr } 562: addi r0, r0, -1 /* don't count the trailing NUL */
57 { sub r0, r0, r3; jrp lr }
56 STD_ENDPROC(strncpy_from_user_asm) 58 STD_ENDPROC(strncpy_from_user_asm)
57 .pushsection .fixup,"ax" 59 .pushsection .fixup,"ax"
58strncpy_from_user_fault: 60strncpy_from_user_fault:
59 { movei r0, -EFAULT; jrp lr } 61 { movei r0, -EFAULT; jrp lr }
60 ENDPROC(strncpy_from_user_fault) 62 ENDPROC(strncpy_from_user_fault)
61 .section __ex_table,"a" 63 .section __ex_table,"a"
64 .align 4
62 .word 1b, strncpy_from_user_fault 65 .word 1b, strncpy_from_user_fault
63 .popsection 66 .popsection
64 67
@@ -77,6 +80,7 @@ STD_ENTRY(clear_user_asm)
77 bnzt r1, 1b 80 bnzt r1, 1b
782: { move r0, r1; jrp lr } 812: { move r0, r1; jrp lr }
79 .pushsection __ex_table,"a" 82 .pushsection __ex_table,"a"
83 .align 4
80 .word 1b, 2b 84 .word 1b, 2b
81 .popsection 85 .popsection
82 86
@@ -86,6 +90,7 @@ STD_ENTRY(clear_user_asm)
862: { move r0, r1; jrp lr } 902: { move r0, r1; jrp lr }
87 STD_ENDPROC(clear_user_asm) 91 STD_ENDPROC(clear_user_asm)
88 .pushsection __ex_table,"a" 92 .pushsection __ex_table,"a"
93 .align 4
89 .word 1b, 2b 94 .word 1b, 2b
90 .popsection 95 .popsection
91 96
@@ -105,25 +110,7 @@ STD_ENTRY(flush_user_asm)
1052: { move r0, r1; jrp lr } 1102: { move r0, r1; jrp lr }
106 STD_ENDPROC(flush_user_asm) 111 STD_ENDPROC(flush_user_asm)
107 .pushsection __ex_table,"a" 112 .pushsection __ex_table,"a"
108 .word 1b, 2b 113 .align 4
109 .popsection
110
111/*
112 * inv_user_asm takes the user target address in r0 and the
113 * number of bytes to invalidate in r1.
114 * It returns the number of not inv'able bytes (hopefully zero) in r0.
115 */
116STD_ENTRY(inv_user_asm)
117 bz r1, 2f
118 { movei r2, L2_CACHE_BYTES; add r1, r0, r1 }
119 { sub r2, zero, r2; addi r1, r1, L2_CACHE_BYTES-1 }
120 { and r0, r0, r2; and r1, r1, r2 }
121 { sub r1, r1, r0 }
1221: { inv r0; addi r1, r1, -CHIP_INV_STRIDE() }
123 { addi r0, r0, CHIP_INV_STRIDE(); bnzt r1, 1b }
1242: { move r0, r1; jrp lr }
125 STD_ENDPROC(inv_user_asm)
126 .pushsection __ex_table,"a"
127 .word 1b, 2b 114 .word 1b, 2b
128 .popsection 115 .popsection
129 116
@@ -143,5 +130,6 @@ STD_ENTRY(finv_user_asm)
1432: { move r0, r1; jrp lr } 1302: { move r0, r1; jrp lr }
144 STD_ENDPROC(finv_user_asm) 131 STD_ENDPROC(finv_user_asm)
145 .pushsection __ex_table,"a" 132 .pushsection __ex_table,"a"
133 .align 4
146 .word 1b, 2b 134 .word 1b, 2b
147 .popsection 135 .popsection
diff --git a/arch/tile/lib/usercopy_64.S b/arch/tile/lib/usercopy_64.S
index adb2dbbc70cd..b3b31a3306f8 100644
--- a/arch/tile/lib/usercopy_64.S
+++ b/arch/tile/lib/usercopy_64.S
@@ -36,6 +36,7 @@ strnlen_user_fault:
36 { move r0, zero; jrp lr } 36 { move r0, zero; jrp lr }
37 ENDPROC(strnlen_user_fault) 37 ENDPROC(strnlen_user_fault)
38 .section __ex_table,"a" 38 .section __ex_table,"a"
39 .align 8
39 .quad 1b, strnlen_user_fault 40 .quad 1b, strnlen_user_fault
40 .popsection 41 .popsection
41 42
@@ -47,18 +48,20 @@ strnlen_user_fault:
47 */ 48 */
48STD_ENTRY(strncpy_from_user_asm) 49STD_ENTRY(strncpy_from_user_asm)
49 { beqz r2, 2f; move r3, r0 } 50 { beqz r2, 2f; move r3, r0 }
501: { ld1u r4, r1; addi r1, r1, 1; addi r2, r2, -1 } 511: { ld1u r4, r1; addi r1, r1, 1; addi r2, r2, -1 }
51 { st1 r0, r4; addi r0, r0, 1 } 52 { st1 r0, r4; addi r0, r0, 1 }
52 beqz r2, 2f 53 beqz r4, 2f
53 bnezt r4, 1b 54 bnezt r2, 1b
54 addi r0, r0, -1 /* don't count the trailing NUL */ 55 { sub r0, r0, r3; jrp lr }
552: { sub r0, r0, r3; jrp lr } 562: addi r0, r0, -1 /* don't count the trailing NUL */
57 { sub r0, r0, r3; jrp lr }
56 STD_ENDPROC(strncpy_from_user_asm) 58 STD_ENDPROC(strncpy_from_user_asm)
57 .pushsection .fixup,"ax" 59 .pushsection .fixup,"ax"
58strncpy_from_user_fault: 60strncpy_from_user_fault:
59 { movei r0, -EFAULT; jrp lr } 61 { movei r0, -EFAULT; jrp lr }
60 ENDPROC(strncpy_from_user_fault) 62 ENDPROC(strncpy_from_user_fault)
61 .section __ex_table,"a" 63 .section __ex_table,"a"
64 .align 8
62 .quad 1b, strncpy_from_user_fault 65 .quad 1b, strncpy_from_user_fault
63 .popsection 66 .popsection
64 67
@@ -77,6 +80,7 @@ STD_ENTRY(clear_user_asm)
77 bnezt r1, 1b 80 bnezt r1, 1b
782: { move r0, r1; jrp lr } 812: { move r0, r1; jrp lr }
79 .pushsection __ex_table,"a" 82 .pushsection __ex_table,"a"
83 .align 8
80 .quad 1b, 2b 84 .quad 1b, 2b
81 .popsection 85 .popsection
82 86
@@ -86,6 +90,7 @@ STD_ENTRY(clear_user_asm)
862: { move r0, r1; jrp lr } 902: { move r0, r1; jrp lr }
87 STD_ENDPROC(clear_user_asm) 91 STD_ENDPROC(clear_user_asm)
88 .pushsection __ex_table,"a" 92 .pushsection __ex_table,"a"
93 .align 8
89 .quad 1b, 2b 94 .quad 1b, 2b
90 .popsection 95 .popsection
91 96
@@ -105,25 +110,7 @@ STD_ENTRY(flush_user_asm)
1052: { move r0, r1; jrp lr } 1102: { move r0, r1; jrp lr }
106 STD_ENDPROC(flush_user_asm) 111 STD_ENDPROC(flush_user_asm)
107 .pushsection __ex_table,"a" 112 .pushsection __ex_table,"a"
108 .quad 1b, 2b 113 .align 8
109 .popsection
110
111/*
112 * inv_user_asm takes the user target address in r0 and the
113 * number of bytes to invalidate in r1.
114 * It returns the number of not inv'able bytes (hopefully zero) in r0.
115 */
116STD_ENTRY(inv_user_asm)
117 beqz r1, 2f
118 { movei r2, L2_CACHE_BYTES; add r1, r0, r1 }
119 { sub r2, zero, r2; addi r1, r1, L2_CACHE_BYTES-1 }
120 { and r0, r0, r2; and r1, r1, r2 }
121 { sub r1, r1, r0 }
1221: { inv r0; addi r1, r1, -CHIP_INV_STRIDE() }
123 { addi r0, r0, CHIP_INV_STRIDE(); bnezt r1, 1b }
1242: { move r0, r1; jrp lr }
125 STD_ENDPROC(inv_user_asm)
126 .pushsection __ex_table,"a"
127 .quad 1b, 2b 114 .quad 1b, 2b
128 .popsection 115 .popsection
129 116
@@ -143,5 +130,6 @@ STD_ENTRY(finv_user_asm)
1432: { move r0, r1; jrp lr } 1302: { move r0, r1; jrp lr }
144 STD_ENDPROC(finv_user_asm) 131 STD_ENDPROC(finv_user_asm)
145 .pushsection __ex_table,"a" 132 .pushsection __ex_table,"a"
133 .align 8
146 .quad 1b, 2b 134 .quad 1b, 2b
147 .popsection 135 .popsection
diff --git a/arch/tile/mm/elf.c b/arch/tile/mm/elf.c
index 743c951c61b0..23f044e8a7ab 100644
--- a/arch/tile/mm/elf.c
+++ b/arch/tile/mm/elf.c
@@ -21,7 +21,8 @@
21#include <asm/pgtable.h> 21#include <asm/pgtable.h>
22#include <asm/pgalloc.h> 22#include <asm/pgalloc.h>
23#include <asm/sections.h> 23#include <asm/sections.h>
24#include <arch/sim_def.h> 24#include <asm/vdso.h>
25#include <arch/sim.h>
25 26
26/* Notify a running simulator, if any, that an exec just occurred. */ 27/* Notify a running simulator, if any, that an exec just occurred. */
27static void sim_notify_exec(const char *binary_name) 28static void sim_notify_exec(const char *binary_name)
@@ -38,21 +39,55 @@ static void sim_notify_exec(const char *binary_name)
38 39
39static int notify_exec(struct mm_struct *mm) 40static int notify_exec(struct mm_struct *mm)
40{ 41{
41 int retval = 0; /* failure */ 42 char *buf, *path;
42 43 struct vm_area_struct *vma;
43 if (mm->exe_file) { 44
44 char *buf = (char *) __get_free_page(GFP_KERNEL); 45 if (!sim_is_simulator())
45 if (buf) { 46 return 1;
46 char *path = d_path(&mm->exe_file->f_path, 47
47 buf, PAGE_SIZE); 48 if (mm->exe_file == NULL)
48 if (!IS_ERR(path)) { 49 return 0;
49 sim_notify_exec(path); 50
50 retval = 1; 51 for (vma = current->mm->mmap; ; vma = vma->vm_next) {
51 } 52 if (vma == NULL)
52 free_page((unsigned long)buf); 53 return 0;
54 if (vma->vm_file == mm->exe_file)
55 break;
56 }
57
58 buf = (char *) __get_free_page(GFP_KERNEL);
59 if (buf == NULL)
60 return 0;
61
62 path = d_path(&mm->exe_file->f_path, buf, PAGE_SIZE);
63 if (IS_ERR(path)) {
64 free_page((unsigned long)buf);
65 return 0;
66 }
67
68 /*
69 * Notify simulator of an ET_DYN object so we know the load address.
70 * The somewhat cryptic overuse of SIM_CONTROL_DLOPEN allows us
71 * to be backward-compatible with older simulator releases.
72 */
73 if (vma->vm_start == (ELF_ET_DYN_BASE & PAGE_MASK)) {
74 char buf[64];
75 int i;
76
77 snprintf(buf, sizeof(buf), "0x%lx:@", vma->vm_start);
78 for (i = 0; ; ++i) {
79 char c = buf[i];
80 __insn_mtspr(SPR_SIM_CONTROL,
81 (SIM_CONTROL_DLOPEN
82 | (c << _SIM_CONTROL_OPERATOR_BITS)));
83 if (c == '\0')
84 break;
53 } 85 }
54 } 86 }
55 return retval; 87
88 sim_notify_exec(path);
89 free_page((unsigned long)buf);
90 return 1;
56} 91}
57 92
58/* Notify a running simulator, if any, that we loaded an interpreter. */ 93/* Notify a running simulator, if any, that we loaded an interpreter. */
@@ -68,37 +103,10 @@ static void sim_notify_interp(unsigned long load_addr)
68} 103}
69 104
70 105
71/* Kernel address of page used to map read-only kernel data into userspace. */
72static void *vdso_page;
73
74/* One-entry array used for install_special_mapping. */
75static struct page *vdso_pages[1];
76
77static int __init vdso_setup(void)
78{
79 vdso_page = (void *)get_zeroed_page(GFP_ATOMIC);
80 memcpy(vdso_page, __rt_sigreturn, __rt_sigreturn_end - __rt_sigreturn);
81 vdso_pages[0] = virt_to_page(vdso_page);
82 return 0;
83}
84device_initcall(vdso_setup);
85
86const char *arch_vma_name(struct vm_area_struct *vma)
87{
88 if (vma->vm_private_data == vdso_pages)
89 return "[vdso]";
90#ifndef __tilegx__
91 if (vma->vm_start == MEM_USER_INTRPT)
92 return "[intrpt]";
93#endif
94 return NULL;
95}
96
97int arch_setup_additional_pages(struct linux_binprm *bprm, 106int arch_setup_additional_pages(struct linux_binprm *bprm,
98 int executable_stack) 107 int executable_stack)
99{ 108{
100 struct mm_struct *mm = current->mm; 109 struct mm_struct *mm = current->mm;
101 unsigned long vdso_base;
102 int retval = 0; 110 int retval = 0;
103 111
104 down_write(&mm->mmap_sem); 112 down_write(&mm->mmap_sem);
@@ -111,14 +119,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm,
111 if (!notify_exec(mm)) 119 if (!notify_exec(mm))
112 sim_notify_exec(bprm->filename); 120 sim_notify_exec(bprm->filename);
113 121
114 /* 122 retval = setup_vdso_pages();
115 * MAYWRITE to allow gdb to COW and set breakpoints
116 */
117 vdso_base = VDSO_BASE;
118 retval = install_special_mapping(mm, vdso_base, PAGE_SIZE,
119 VM_READ|VM_EXEC|
120 VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC,
121 vdso_pages);
122 123
123#ifndef __tilegx__ 124#ifndef __tilegx__
124 /* 125 /*
diff --git a/arch/tile/mm/fault.c b/arch/tile/mm/fault.c
index f7f99f90cbe0..111d5a9b76f1 100644
--- a/arch/tile/mm/fault.c
+++ b/arch/tile/mm/fault.c
@@ -34,6 +34,7 @@
34#include <linux/hugetlb.h> 34#include <linux/hugetlb.h>
35#include <linux/syscalls.h> 35#include <linux/syscalls.h>
36#include <linux/uaccess.h> 36#include <linux/uaccess.h>
37#include <linux/kdebug.h>
37 38
38#include <asm/pgalloc.h> 39#include <asm/pgalloc.h>
39#include <asm/sections.h> 40#include <asm/sections.h>
@@ -122,10 +123,9 @@ static inline pmd_t *vmalloc_sync_one(pgd_t *pgd, unsigned long address)
122 pmd_k = pmd_offset(pud_k, address); 123 pmd_k = pmd_offset(pud_k, address);
123 if (!pmd_present(*pmd_k)) 124 if (!pmd_present(*pmd_k))
124 return NULL; 125 return NULL;
125 if (!pmd_present(*pmd)) { 126 if (!pmd_present(*pmd))
126 set_pmd(pmd, *pmd_k); 127 set_pmd(pmd, *pmd_k);
127 arch_flush_lazy_mmu_mode(); 128 else
128 } else
129 BUG_ON(pmd_ptfn(*pmd) != pmd_ptfn(*pmd_k)); 129 BUG_ON(pmd_ptfn(*pmd) != pmd_ptfn(*pmd_k));
130 return pmd_k; 130 return pmd_k;
131} 131}
@@ -283,7 +283,7 @@ static int handle_page_fault(struct pt_regs *regs,
283 flags = (FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE | 283 flags = (FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE |
284 (write ? FAULT_FLAG_WRITE : 0)); 284 (write ? FAULT_FLAG_WRITE : 0));
285 285
286 is_kernel_mode = (EX1_PL(regs->ex1) != USER_PL); 286 is_kernel_mode = !user_mode(regs);
287 287
288 tsk = validate_current(); 288 tsk = validate_current();
289 289
@@ -466,28 +466,15 @@ good_area:
466 } 466 }
467 } 467 }
468 468
469#if CHIP_HAS_TILE_DMA() || CHIP_HAS_SN_PROC()
470 /*
471 * If this was an asynchronous fault,
472 * restart the appropriate engine.
473 */
474 switch (fault_num) {
475#if CHIP_HAS_TILE_DMA() 469#if CHIP_HAS_TILE_DMA()
470 /* If this was a DMA TLB fault, restart the DMA engine. */
471 switch (fault_num) {
476 case INT_DMATLB_MISS: 472 case INT_DMATLB_MISS:
477 case INT_DMATLB_MISS_DWNCL: 473 case INT_DMATLB_MISS_DWNCL:
478 case INT_DMATLB_ACCESS: 474 case INT_DMATLB_ACCESS:
479 case INT_DMATLB_ACCESS_DWNCL: 475 case INT_DMATLB_ACCESS_DWNCL:
480 __insn_mtspr(SPR_DMA_CTR, SPR_DMA_CTR__REQUEST_MASK); 476 __insn_mtspr(SPR_DMA_CTR, SPR_DMA_CTR__REQUEST_MASK);
481 break; 477 break;
482#endif
483#if CHIP_HAS_SN_PROC()
484 case INT_SNITLB_MISS:
485 case INT_SNITLB_MISS_DWNCL:
486 __insn_mtspr(SPR_SNCTL,
487 __insn_mfspr(SPR_SNCTL) &
488 ~SPR_SNCTL__FRZPROC_MASK);
489 break;
490#endif
491 } 478 }
492#endif 479#endif
493 480
@@ -722,8 +709,60 @@ void do_page_fault(struct pt_regs *regs, int fault_num,
722{ 709{
723 int is_page_fault; 710 int is_page_fault;
724 711
712#ifdef CONFIG_KPROBES
713 /*
714 * This is to notify the fault handler of the kprobes. The
715 * exception code is redundant as it is also carried in REGS,
716 * but we pass it anyhow.
717 */
718 if (notify_die(DIE_PAGE_FAULT, "page fault", regs, -1,
719 regs->faultnum, SIGSEGV) == NOTIFY_STOP)
720 return;
721#endif
722
723#ifdef __tilegx__
724 /*
725 * We don't need early do_page_fault_ics() support, since unlike
726 * Pro we don't need to worry about unlocking the atomic locks.
727 * There is only one current case in GX where we touch any memory
728 * under ICS other than our own kernel stack, and we handle that
729 * here. (If we crash due to trying to touch our own stack,
730 * we're in too much trouble for C code to help out anyway.)
731 */
732 if (write & ~1) {
733 unsigned long pc = write & ~1;
734 if (pc >= (unsigned long) __start_unalign_asm_code &&
735 pc < (unsigned long) __end_unalign_asm_code) {
736 struct thread_info *ti = current_thread_info();
737 /*
738 * Our EX_CONTEXT is still what it was from the
739 * initial unalign exception, but now we've faulted
740 * on the JIT page. We would like to complete the
741 * page fault however is appropriate, and then retry
742 * the instruction that caused the unalign exception.
743 * Our state has been "corrupted" by setting the low
744 * bit in "sp", and stashing r0..r3 in the
745 * thread_info area, so we revert all of that, then
746 * continue as if this were a normal page fault.
747 */
748 regs->sp &= ~1UL;
749 regs->regs[0] = ti->unalign_jit_tmp[0];
750 regs->regs[1] = ti->unalign_jit_tmp[1];
751 regs->regs[2] = ti->unalign_jit_tmp[2];
752 regs->regs[3] = ti->unalign_jit_tmp[3];
753 write &= 1;
754 } else {
755 pr_alert("%s/%d: ICS set at page fault at %#lx: %#lx\n",
756 current->comm, current->pid, pc, address);
757 show_regs(regs);
758 do_group_exit(SIGKILL);
759 return;
760 }
761 }
762#else
725 /* This case should have been handled by do_page_fault_ics(). */ 763 /* This case should have been handled by do_page_fault_ics(). */
726 BUG_ON(write & ~1); 764 BUG_ON(write & ~1);
765#endif
727 766
728#if CHIP_HAS_TILE_DMA() 767#if CHIP_HAS_TILE_DMA()
729 /* 768 /*
@@ -752,10 +791,6 @@ void do_page_fault(struct pt_regs *regs, int fault_num,
752 case INT_DMATLB_MISS: 791 case INT_DMATLB_MISS:
753 case INT_DMATLB_MISS_DWNCL: 792 case INT_DMATLB_MISS_DWNCL:
754#endif 793#endif
755#if CHIP_HAS_SN_PROC()
756 case INT_SNITLB_MISS:
757 case INT_SNITLB_MISS_DWNCL:
758#endif
759 is_page_fault = 1; 794 is_page_fault = 1;
760 break; 795 break;
761 796
@@ -771,8 +806,8 @@ void do_page_fault(struct pt_regs *regs, int fault_num,
771 panic("Bad fault number %d in do_page_fault", fault_num); 806 panic("Bad fault number %d in do_page_fault", fault_num);
772 } 807 }
773 808
774#if CHIP_HAS_TILE_DMA() || CHIP_HAS_SN_PROC() 809#if CHIP_HAS_TILE_DMA()
775 if (EX1_PL(regs->ex1) != USER_PL) { 810 if (!user_mode(regs)) {
776 struct async_tlb *async; 811 struct async_tlb *async;
777 switch (fault_num) { 812 switch (fault_num) {
778#if CHIP_HAS_TILE_DMA() 813#if CHIP_HAS_TILE_DMA()
@@ -783,12 +818,6 @@ void do_page_fault(struct pt_regs *regs, int fault_num,
783 async = &current->thread.dma_async_tlb; 818 async = &current->thread.dma_async_tlb;
784 break; 819 break;
785#endif 820#endif
786#if CHIP_HAS_SN_PROC()
787 case INT_SNITLB_MISS:
788 case INT_SNITLB_MISS_DWNCL:
789 async = &current->thread.sn_async_tlb;
790 break;
791#endif
792 default: 821 default:
793 async = NULL; 822 async = NULL;
794 } 823 }
@@ -821,14 +850,22 @@ void do_page_fault(struct pt_regs *regs, int fault_num,
821} 850}
822 851
823 852
824#if CHIP_HAS_TILE_DMA() || CHIP_HAS_SN_PROC() 853#if CHIP_HAS_TILE_DMA()
825/* 854/*
826 * Check an async_tlb structure to see if a deferred fault is waiting, 855 * This routine effectively re-issues asynchronous page faults
827 * and if so pass it to the page-fault code. 856 * when we are returning to user space.
828 */ 857 */
829static void handle_async_page_fault(struct pt_regs *regs, 858void do_async_page_fault(struct pt_regs *regs)
830 struct async_tlb *async)
831{ 859{
860 struct async_tlb *async = &current->thread.dma_async_tlb;
861
862 /*
863 * Clear thread flag early. If we re-interrupt while processing
864 * code here, we will reset it and recall this routine before
865 * returning to user space.
866 */
867 clear_thread_flag(TIF_ASYNC_TLB);
868
832 if (async->fault_num) { 869 if (async->fault_num) {
833 /* 870 /*
834 * Clear async->fault_num before calling the page-fault 871 * Clear async->fault_num before calling the page-fault
@@ -842,35 +879,15 @@ static void handle_async_page_fault(struct pt_regs *regs,
842 async->address, async->is_write); 879 async->address, async->is_write);
843 } 880 }
844} 881}
845 882#endif /* CHIP_HAS_TILE_DMA() */
846/*
847 * This routine effectively re-issues asynchronous page faults
848 * when we are returning to user space.
849 */
850void do_async_page_fault(struct pt_regs *regs)
851{
852 /*
853 * Clear thread flag early. If we re-interrupt while processing
854 * code here, we will reset it and recall this routine before
855 * returning to user space.
856 */
857 clear_thread_flag(TIF_ASYNC_TLB);
858
859#if CHIP_HAS_TILE_DMA()
860 handle_async_page_fault(regs, &current->thread.dma_async_tlb);
861#endif
862#if CHIP_HAS_SN_PROC()
863 handle_async_page_fault(regs, &current->thread.sn_async_tlb);
864#endif
865}
866#endif /* CHIP_HAS_TILE_DMA() || CHIP_HAS_SN_PROC() */
867 883
868 884
869void vmalloc_sync_all(void) 885void vmalloc_sync_all(void)
870{ 886{
871#ifdef __tilegx__ 887#ifdef __tilegx__
872 /* Currently all L1 kernel pmd's are static and shared. */ 888 /* Currently all L1 kernel pmd's are static and shared. */
873 BUG_ON(pgd_index(VMALLOC_END) != pgd_index(VMALLOC_START)); 889 BUILD_BUG_ON(pgd_index(VMALLOC_END - PAGE_SIZE) !=
890 pgd_index(VMALLOC_START));
874#else 891#else
875 /* 892 /*
876 * Note that races in the updates of insync and start aren't 893 * Note that races in the updates of insync and start aren't
diff --git a/arch/tile/mm/highmem.c b/arch/tile/mm/highmem.c
index 347d123b14be..0dc218294770 100644
--- a/arch/tile/mm/highmem.c
+++ b/arch/tile/mm/highmem.c
@@ -114,7 +114,6 @@ static void kmap_atomic_register(struct page *page, int type,
114 114
115 list_add(&amp->list, &amp_list); 115 list_add(&amp->list, &amp_list);
116 set_pte(ptep, pteval); 116 set_pte(ptep, pteval);
117 arch_flush_lazy_mmu_mode();
118 117
119 spin_unlock(&amp_lock); 118 spin_unlock(&amp_lock);
120 homecache_kpte_unlock(flags); 119 homecache_kpte_unlock(flags);
@@ -259,7 +258,6 @@ void __kunmap_atomic(void *kvaddr)
259 BUG_ON(vaddr >= (unsigned long)high_memory); 258 BUG_ON(vaddr >= (unsigned long)high_memory);
260 } 259 }
261 260
262 arch_flush_lazy_mmu_mode();
263 pagefault_enable(); 261 pagefault_enable();
264} 262}
265EXPORT_SYMBOL(__kunmap_atomic); 263EXPORT_SYMBOL(__kunmap_atomic);
diff --git a/arch/tile/mm/homecache.c b/arch/tile/mm/homecache.c
index 1ae911939a18..004ba568d93f 100644
--- a/arch/tile/mm/homecache.c
+++ b/arch/tile/mm/homecache.c
@@ -43,12 +43,9 @@
43#include "migrate.h" 43#include "migrate.h"
44 44
45 45
46#if CHIP_HAS_COHERENT_LOCAL_CACHE()
47
48/* 46/*
49 * The noallocl2 option suppresses all use of the L2 cache to cache 47 * The noallocl2 option suppresses all use of the L2 cache to cache
50 * locally from a remote home. There's no point in using it if we 48 * locally from a remote home.
51 * don't have coherent local caching, though.
52 */ 49 */
53static int __write_once noallocl2; 50static int __write_once noallocl2;
54static int __init set_noallocl2(char *str) 51static int __init set_noallocl2(char *str)
@@ -58,12 +55,6 @@ static int __init set_noallocl2(char *str)
58} 55}
59early_param("noallocl2", set_noallocl2); 56early_param("noallocl2", set_noallocl2);
60 57
61#else
62
63#define noallocl2 0
64
65#endif
66
67 58
68/* 59/*
69 * Update the irq_stat for cpus that we are going to interrupt 60 * Update the irq_stat for cpus that we are going to interrupt
@@ -172,7 +163,8 @@ void flush_remote(unsigned long cache_pfn, unsigned long cache_control,
172 163
173static void homecache_finv_page_va(void* va, int home) 164static void homecache_finv_page_va(void* va, int home)
174{ 165{
175 if (home == smp_processor_id()) { 166 int cpu = get_cpu();
167 if (home == cpu) {
176 finv_buffer_local(va, PAGE_SIZE); 168 finv_buffer_local(va, PAGE_SIZE);
177 } else if (home == PAGE_HOME_HASH) { 169 } else if (home == PAGE_HOME_HASH) {
178 finv_buffer_remote(va, PAGE_SIZE, 1); 170 finv_buffer_remote(va, PAGE_SIZE, 1);
@@ -180,6 +172,7 @@ static void homecache_finv_page_va(void* va, int home)
180 BUG_ON(home < 0 || home >= NR_CPUS); 172 BUG_ON(home < 0 || home >= NR_CPUS);
181 finv_buffer_remote(va, PAGE_SIZE, 0); 173 finv_buffer_remote(va, PAGE_SIZE, 0);
182 } 174 }
175 put_cpu();
183} 176}
184 177
185void homecache_finv_map_page(struct page *page, int home) 178void homecache_finv_map_page(struct page *page, int home)
@@ -198,7 +191,7 @@ void homecache_finv_map_page(struct page *page, int home)
198#else 191#else
199 va = __fix_to_virt(FIX_HOMECACHE_BEGIN + smp_processor_id()); 192 va = __fix_to_virt(FIX_HOMECACHE_BEGIN + smp_processor_id());
200#endif 193#endif
201 ptep = virt_to_pte(NULL, (unsigned long)va); 194 ptep = virt_to_kpte(va);
202 pte = pfn_pte(page_to_pfn(page), PAGE_KERNEL); 195 pte = pfn_pte(page_to_pfn(page), PAGE_KERNEL);
203 __set_pte(ptep, pte_set_home(pte, home)); 196 __set_pte(ptep, pte_set_home(pte, home));
204 homecache_finv_page_va((void *)va, home); 197 homecache_finv_page_va((void *)va, home);
@@ -263,10 +256,8 @@ static int pte_to_home(pte_t pte)
263 return PAGE_HOME_INCOHERENT; 256 return PAGE_HOME_INCOHERENT;
264 case HV_PTE_MODE_UNCACHED: 257 case HV_PTE_MODE_UNCACHED:
265 return PAGE_HOME_UNCACHED; 258 return PAGE_HOME_UNCACHED;
266#if CHIP_HAS_CBOX_HOME_MAP()
267 case HV_PTE_MODE_CACHE_HASH_L3: 259 case HV_PTE_MODE_CACHE_HASH_L3:
268 return PAGE_HOME_HASH; 260 return PAGE_HOME_HASH;
269#endif
270 } 261 }
271 panic("Bad PTE %#llx\n", pte.val); 262 panic("Bad PTE %#llx\n", pte.val);
272} 263}
@@ -323,20 +314,16 @@ pte_t pte_set_home(pte_t pte, int home)
323 HV_PTE_MODE_CACHE_NO_L3); 314 HV_PTE_MODE_CACHE_NO_L3);
324 } 315 }
325 } else 316 } else
326#if CHIP_HAS_CBOX_HOME_MAP()
327 if (hash_default) 317 if (hash_default)
328 pte = hv_pte_set_mode(pte, HV_PTE_MODE_CACHE_HASH_L3); 318 pte = hv_pte_set_mode(pte, HV_PTE_MODE_CACHE_HASH_L3);
329 else 319 else
330#endif
331 pte = hv_pte_set_mode(pte, HV_PTE_MODE_CACHE_NO_L3); 320 pte = hv_pte_set_mode(pte, HV_PTE_MODE_CACHE_NO_L3);
332 pte = hv_pte_set_nc(pte); 321 pte = hv_pte_set_nc(pte);
333 break; 322 break;
334 323
335#if CHIP_HAS_CBOX_HOME_MAP()
336 case PAGE_HOME_HASH: 324 case PAGE_HOME_HASH:
337 pte = hv_pte_set_mode(pte, HV_PTE_MODE_CACHE_HASH_L3); 325 pte = hv_pte_set_mode(pte, HV_PTE_MODE_CACHE_HASH_L3);
338 break; 326 break;
339#endif
340 327
341 default: 328 default:
342 BUG_ON(home < 0 || home >= NR_CPUS || 329 BUG_ON(home < 0 || home >= NR_CPUS ||
@@ -346,7 +333,6 @@ pte_t pte_set_home(pte_t pte, int home)
346 break; 333 break;
347 } 334 }
348 335
349#if CHIP_HAS_NC_AND_NOALLOC_BITS()
350 if (noallocl2) 336 if (noallocl2)
351 pte = hv_pte_set_no_alloc_l2(pte); 337 pte = hv_pte_set_no_alloc_l2(pte);
352 338
@@ -355,7 +341,6 @@ pte_t pte_set_home(pte_t pte, int home)
355 hv_pte_get_mode(pte) == HV_PTE_MODE_CACHE_NO_L3) { 341 hv_pte_get_mode(pte) == HV_PTE_MODE_CACHE_NO_L3) {
356 pte = hv_pte_set_mode(pte, HV_PTE_MODE_UNCACHED); 342 pte = hv_pte_set_mode(pte, HV_PTE_MODE_UNCACHED);
357 } 343 }
358#endif
359 344
360 /* Checking this case here gives a better panic than from the hv. */ 345 /* Checking this case here gives a better panic than from the hv. */
361 BUG_ON(hv_pte_get_mode(pte) == 0); 346 BUG_ON(hv_pte_get_mode(pte) == 0);
@@ -371,19 +356,13 @@ EXPORT_SYMBOL(pte_set_home);
371 * so they're not suitable for anything but infrequent use. 356 * so they're not suitable for anything but infrequent use.
372 */ 357 */
373 358
374#if CHIP_HAS_CBOX_HOME_MAP()
375static inline int initial_page_home(void) { return PAGE_HOME_HASH; }
376#else
377static inline int initial_page_home(void) { return 0; }
378#endif
379
380int page_home(struct page *page) 359int page_home(struct page *page)
381{ 360{
382 if (PageHighMem(page)) { 361 if (PageHighMem(page)) {
383 return initial_page_home(); 362 return PAGE_HOME_HASH;
384 } else { 363 } else {
385 unsigned long kva = (unsigned long)page_address(page); 364 unsigned long kva = (unsigned long)page_address(page);
386 return pte_to_home(*virt_to_pte(NULL, kva)); 365 return pte_to_home(*virt_to_kpte(kva));
387 } 366 }
388} 367}
389EXPORT_SYMBOL(page_home); 368EXPORT_SYMBOL(page_home);
@@ -402,7 +381,7 @@ void homecache_change_page_home(struct page *page, int order, int home)
402 NULL, 0); 381 NULL, 0);
403 382
404 for (i = 0; i < pages; ++i, kva += PAGE_SIZE) { 383 for (i = 0; i < pages; ++i, kva += PAGE_SIZE) {
405 pte_t *ptep = virt_to_pte(NULL, kva); 384 pte_t *ptep = virt_to_kpte(kva);
406 pte_t pteval = *ptep; 385 pte_t pteval = *ptep;
407 BUG_ON(!pte_present(pteval) || pte_huge(pteval)); 386 BUG_ON(!pte_present(pteval) || pte_huge(pteval));
408 __set_pte(ptep, pte_set_home(pteval, home)); 387 __set_pte(ptep, pte_set_home(pteval, home));
@@ -436,7 +415,7 @@ struct page *homecache_alloc_pages_node(int nid, gfp_t gfp_mask,
436void __homecache_free_pages(struct page *page, unsigned int order) 415void __homecache_free_pages(struct page *page, unsigned int order)
437{ 416{
438 if (put_page_testzero(page)) { 417 if (put_page_testzero(page)) {
439 homecache_change_page_home(page, order, initial_page_home()); 418 homecache_change_page_home(page, order, PAGE_HOME_HASH);
440 if (order == 0) { 419 if (order == 0) {
441 free_hot_cold_page(page, 0); 420 free_hot_cold_page(page, 0);
442 } else { 421 } else {
diff --git a/arch/tile/mm/hugetlbpage.c b/arch/tile/mm/hugetlbpage.c
index 650ccff8378c..e514899e1100 100644
--- a/arch/tile/mm/hugetlbpage.c
+++ b/arch/tile/mm/hugetlbpage.c
@@ -49,38 +49,6 @@ int huge_shift[HUGE_SHIFT_ENTRIES] = {
49#endif 49#endif
50}; 50};
51 51
52/*
53 * This routine is a hybrid of pte_alloc_map() and pte_alloc_kernel().
54 * It assumes that L2 PTEs are never in HIGHMEM (we don't support that).
55 * It locks the user pagetable, and bumps up the mm->nr_ptes field,
56 * but otherwise allocate the page table using the kernel versions.
57 */
58static pte_t *pte_alloc_hugetlb(struct mm_struct *mm, pmd_t *pmd,
59 unsigned long address)
60{
61 pte_t *new;
62
63 if (pmd_none(*pmd)) {
64 new = pte_alloc_one_kernel(mm, address);
65 if (!new)
66 return NULL;
67
68 smp_wmb(); /* See comment in __pte_alloc */
69
70 spin_lock(&mm->page_table_lock);
71 if (likely(pmd_none(*pmd))) { /* Has another populated it ? */
72 mm->nr_ptes++;
73 pmd_populate_kernel(mm, pmd, new);
74 new = NULL;
75 } else
76 VM_BUG_ON(pmd_trans_splitting(*pmd));
77 spin_unlock(&mm->page_table_lock);
78 if (new)
79 pte_free_kernel(mm, new);
80 }
81
82 return pte_offset_kernel(pmd, address);
83}
84#endif 52#endif
85 53
86pte_t *huge_pte_alloc(struct mm_struct *mm, 54pte_t *huge_pte_alloc(struct mm_struct *mm,
@@ -109,7 +77,7 @@ pte_t *huge_pte_alloc(struct mm_struct *mm,
109 else { 77 else {
110 if (sz != PAGE_SIZE << huge_shift[HUGE_SHIFT_PAGE]) 78 if (sz != PAGE_SIZE << huge_shift[HUGE_SHIFT_PAGE])
111 panic("Unexpected page size %#lx\n", sz); 79 panic("Unexpected page size %#lx\n", sz);
112 return pte_alloc_hugetlb(mm, pmd, addr); 80 return pte_alloc_map(mm, NULL, pmd, addr);
113 } 81 }
114 } 82 }
115#else 83#else
@@ -144,14 +112,14 @@ pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr)
144 112
145 /* Get the top-level page table entry. */ 113 /* Get the top-level page table entry. */
146 pgd = (pgd_t *)get_pte((pte_t *)mm->pgd, pgd_index(addr), 0); 114 pgd = (pgd_t *)get_pte((pte_t *)mm->pgd, pgd_index(addr), 0);
147 if (!pgd_present(*pgd))
148 return NULL;
149 115
150 /* We don't have four levels. */ 116 /* We don't have four levels. */
151 pud = pud_offset(pgd, addr); 117 pud = pud_offset(pgd, addr);
152#ifndef __PAGETABLE_PUD_FOLDED 118#ifndef __PAGETABLE_PUD_FOLDED
153# error support fourth page table level 119# error support fourth page table level
154#endif 120#endif
121 if (!pud_present(*pud))
122 return NULL;
155 123
156 /* Check for an L0 huge PTE, if we have three levels. */ 124 /* Check for an L0 huge PTE, if we have three levels. */
157#ifndef __PAGETABLE_PMD_FOLDED 125#ifndef __PAGETABLE_PMD_FOLDED
diff --git a/arch/tile/mm/init.c b/arch/tile/mm/init.c
index e182958c707d..4e316deb92fd 100644
--- a/arch/tile/mm/init.c
+++ b/arch/tile/mm/init.c
@@ -106,10 +106,8 @@ pte_t *get_prealloc_pte(unsigned long pfn)
106 */ 106 */
107static int initial_heap_home(void) 107static int initial_heap_home(void)
108{ 108{
109#if CHIP_HAS_CBOX_HOME_MAP()
110 if (hash_default) 109 if (hash_default)
111 return PAGE_HOME_HASH; 110 return PAGE_HOME_HASH;
112#endif
113 return smp_processor_id(); 111 return smp_processor_id();
114} 112}
115 113
@@ -190,14 +188,11 @@ static void __init page_table_range_init(unsigned long start,
190} 188}
191 189
192 190
193#if CHIP_HAS_CBOX_HOME_MAP()
194
195static int __initdata ktext_hash = 1; /* .text pages */ 191static int __initdata ktext_hash = 1; /* .text pages */
196static int __initdata kdata_hash = 1; /* .data and .bss pages */ 192static int __initdata kdata_hash = 1; /* .data and .bss pages */
197int __write_once hash_default = 1; /* kernel allocator pages */ 193int __write_once hash_default = 1; /* kernel allocator pages */
198EXPORT_SYMBOL(hash_default); 194EXPORT_SYMBOL(hash_default);
199int __write_once kstack_hash = 1; /* if no homecaching, use h4h */ 195int __write_once kstack_hash = 1; /* if no homecaching, use h4h */
200#endif /* CHIP_HAS_CBOX_HOME_MAP */
201 196
202/* 197/*
203 * CPUs to use to for striping the pages of kernel data. If hash-for-home 198 * CPUs to use to for striping the pages of kernel data. If hash-for-home
@@ -215,14 +210,12 @@ int __write_once kdata_huge; /* if no homecaching, small pages */
215static pgprot_t __init construct_pgprot(pgprot_t prot, int home) 210static pgprot_t __init construct_pgprot(pgprot_t prot, int home)
216{ 211{
217 prot = pte_set_home(prot, home); 212 prot = pte_set_home(prot, home);
218#if CHIP_HAS_CBOX_HOME_MAP()
219 if (home == PAGE_HOME_IMMUTABLE) { 213 if (home == PAGE_HOME_IMMUTABLE) {
220 if (ktext_hash) 214 if (ktext_hash)
221 prot = hv_pte_set_mode(prot, HV_PTE_MODE_CACHE_HASH_L3); 215 prot = hv_pte_set_mode(prot, HV_PTE_MODE_CACHE_HASH_L3);
222 else 216 else
223 prot = hv_pte_set_mode(prot, HV_PTE_MODE_CACHE_NO_L3); 217 prot = hv_pte_set_mode(prot, HV_PTE_MODE_CACHE_NO_L3);
224 } 218 }
225#endif
226 return prot; 219 return prot;
227} 220}
228 221
@@ -234,22 +227,17 @@ static pgprot_t __init init_pgprot(ulong address)
234{ 227{
235 int cpu; 228 int cpu;
236 unsigned long page; 229 unsigned long page;
237 enum { CODE_DELTA = MEM_SV_INTRPT - PAGE_OFFSET }; 230 enum { CODE_DELTA = MEM_SV_START - PAGE_OFFSET };
238 231
239#if CHIP_HAS_CBOX_HOME_MAP()
240 /* For kdata=huge, everything is just hash-for-home. */ 232 /* For kdata=huge, everything is just hash-for-home. */
241 if (kdata_huge) 233 if (kdata_huge)
242 return construct_pgprot(PAGE_KERNEL, PAGE_HOME_HASH); 234 return construct_pgprot(PAGE_KERNEL, PAGE_HOME_HASH);
243#endif
244 235
245 /* We map the aliased pages of permanent text inaccessible. */ 236 /* We map the aliased pages of permanent text inaccessible. */
246 if (address < (ulong) _sinittext - CODE_DELTA) 237 if (address < (ulong) _sinittext - CODE_DELTA)
247 return PAGE_NONE; 238 return PAGE_NONE;
248 239
249 /* 240 /* We map read-only data non-coherent for performance. */
250 * We map read-only data non-coherent for performance. We could
251 * use neighborhood caching on TILE64, but it's not clear it's a win.
252 */
253 if ((address >= (ulong) __start_rodata && 241 if ((address >= (ulong) __start_rodata &&
254 address < (ulong) __end_rodata) || 242 address < (ulong) __end_rodata) ||
255 address == (ulong) empty_zero_page) { 243 address == (ulong) empty_zero_page) {
@@ -257,12 +245,10 @@ static pgprot_t __init init_pgprot(ulong address)
257 } 245 }
258 246
259#ifndef __tilegx__ 247#ifndef __tilegx__
260#if !ATOMIC_LOCKS_FOUND_VIA_TABLE()
261 /* Force the atomic_locks[] array page to be hash-for-home. */ 248 /* Force the atomic_locks[] array page to be hash-for-home. */
262 if (address == (ulong) atomic_locks) 249 if (address == (ulong) atomic_locks)
263 return construct_pgprot(PAGE_KERNEL, PAGE_HOME_HASH); 250 return construct_pgprot(PAGE_KERNEL, PAGE_HOME_HASH);
264#endif 251#endif
265#endif
266 252
267 /* 253 /*
268 * Everything else that isn't data or bss is heap, so mark it 254 * Everything else that isn't data or bss is heap, so mark it
@@ -280,19 +266,9 @@ static pgprot_t __init init_pgprot(ulong address)
280 if (address >= (ulong) _end || address < (ulong) _einitdata) 266 if (address >= (ulong) _end || address < (ulong) _einitdata)
281 return construct_pgprot(PAGE_KERNEL, initial_heap_home()); 267 return construct_pgprot(PAGE_KERNEL, initial_heap_home());
282 268
283#if CHIP_HAS_CBOX_HOME_MAP()
284 /* Use hash-for-home if requested for data/bss. */ 269 /* Use hash-for-home if requested for data/bss. */
285 if (kdata_hash) 270 if (kdata_hash)
286 return construct_pgprot(PAGE_KERNEL, PAGE_HOME_HASH); 271 return construct_pgprot(PAGE_KERNEL, PAGE_HOME_HASH);
287#endif
288
289 /*
290 * Make the w1data homed like heap to start with, to avoid
291 * making it part of the page-striped data area when we're just
292 * going to convert it to read-only soon anyway.
293 */
294 if (address >= (ulong)__w1data_begin && address < (ulong)__w1data_end)
295 return construct_pgprot(PAGE_KERNEL, initial_heap_home());
296 272
297 /* 273 /*
298 * Otherwise we just hand out consecutive cpus. To avoid 274 * Otherwise we just hand out consecutive cpus. To avoid
@@ -301,7 +277,7 @@ static pgprot_t __init init_pgprot(ulong address)
301 * the requested address, while walking cpu home around kdata_mask. 277 * the requested address, while walking cpu home around kdata_mask.
302 * This is typically no more than a dozen or so iterations. 278 * This is typically no more than a dozen or so iterations.
303 */ 279 */
304 page = (((ulong)__w1data_end) + PAGE_SIZE - 1) & PAGE_MASK; 280 page = (((ulong)__end_rodata) + PAGE_SIZE - 1) & PAGE_MASK;
305 BUG_ON(address < page || address >= (ulong)_end); 281 BUG_ON(address < page || address >= (ulong)_end);
306 cpu = cpumask_first(&kdata_mask); 282 cpu = cpumask_first(&kdata_mask);
307 for (; page < address; page += PAGE_SIZE) { 283 for (; page < address; page += PAGE_SIZE) {
@@ -311,11 +287,9 @@ static pgprot_t __init init_pgprot(ulong address)
311 if (page == (ulong)empty_zero_page) 287 if (page == (ulong)empty_zero_page)
312 continue; 288 continue;
313#ifndef __tilegx__ 289#ifndef __tilegx__
314#if !ATOMIC_LOCKS_FOUND_VIA_TABLE()
315 if (page == (ulong)atomic_locks) 290 if (page == (ulong)atomic_locks)
316 continue; 291 continue;
317#endif 292#endif
318#endif
319 cpu = cpumask_next(cpu, &kdata_mask); 293 cpu = cpumask_next(cpu, &kdata_mask);
320 if (cpu == NR_CPUS) 294 if (cpu == NR_CPUS)
321 cpu = cpumask_first(&kdata_mask); 295 cpu = cpumask_first(&kdata_mask);
@@ -358,7 +332,7 @@ static int __init setup_ktext(char *str)
358 332
359 ktext_arg_seen = 1; 333 ktext_arg_seen = 1;
360 334
361 /* Default setting on Tile64: use a huge page */ 335 /* Default setting: use a huge page */
362 if (strcmp(str, "huge") == 0) 336 if (strcmp(str, "huge") == 0)
363 pr_info("ktext: using one huge locally cached page\n"); 337 pr_info("ktext: using one huge locally cached page\n");
364 338
@@ -404,10 +378,8 @@ static inline pgprot_t ktext_set_nocache(pgprot_t prot)
404{ 378{
405 if (!ktext_nocache) 379 if (!ktext_nocache)
406 prot = hv_pte_set_nc(prot); 380 prot = hv_pte_set_nc(prot);
407#if CHIP_HAS_NC_AND_NOALLOC_BITS()
408 else 381 else
409 prot = hv_pte_set_no_alloc_l2(prot); 382 prot = hv_pte_set_no_alloc_l2(prot);
410#endif
411 return prot; 383 return prot;
412} 384}
413 385
@@ -440,7 +412,6 @@ static void __init kernel_physical_mapping_init(pgd_t *pgd_base)
440 struct cpumask kstripe_mask; 412 struct cpumask kstripe_mask;
441 int rc, i; 413 int rc, i;
442 414
443#if CHIP_HAS_CBOX_HOME_MAP()
444 if (ktext_arg_seen && ktext_hash) { 415 if (ktext_arg_seen && ktext_hash) {
445 pr_warning("warning: \"ktext\" boot argument ignored" 416 pr_warning("warning: \"ktext\" boot argument ignored"
446 " if \"kcache_hash\" sets up text hash-for-home\n"); 417 " if \"kcache_hash\" sets up text hash-for-home\n");
@@ -457,7 +428,6 @@ static void __init kernel_physical_mapping_init(pgd_t *pgd_base)
457 " kcache_hash=all or =allbutstack\n"); 428 " kcache_hash=all or =allbutstack\n");
458 kdata_huge = 0; 429 kdata_huge = 0;
459 } 430 }
460#endif
461 431
462 /* 432 /*
463 * Set up a mask for cpus to use for kernel striping. 433 * Set up a mask for cpus to use for kernel striping.
@@ -538,7 +508,7 @@ static void __init kernel_physical_mapping_init(pgd_t *pgd_base)
538 } 508 }
539 } 509 }
540 510
541 address = MEM_SV_INTRPT; 511 address = MEM_SV_START;
542 pmd = get_pmd(pgtables, address); 512 pmd = get_pmd(pgtables, address);
543 pfn = 0; /* code starts at PA 0 */ 513 pfn = 0; /* code starts at PA 0 */
544 if (ktext_small) { 514 if (ktext_small) {
@@ -585,13 +555,11 @@ static void __init kernel_physical_mapping_init(pgd_t *pgd_base)
585 } else { 555 } else {
586 pte_t pteval = pfn_pte(0, PAGE_KERNEL_EXEC); 556 pte_t pteval = pfn_pte(0, PAGE_KERNEL_EXEC);
587 pteval = pte_mkhuge(pteval); 557 pteval = pte_mkhuge(pteval);
588#if CHIP_HAS_CBOX_HOME_MAP()
589 if (ktext_hash) { 558 if (ktext_hash) {
590 pteval = hv_pte_set_mode(pteval, 559 pteval = hv_pte_set_mode(pteval,
591 HV_PTE_MODE_CACHE_HASH_L3); 560 HV_PTE_MODE_CACHE_HASH_L3);
592 pteval = ktext_set_nocache(pteval); 561 pteval = ktext_set_nocache(pteval);
593 } else 562 } else
594#endif /* CHIP_HAS_CBOX_HOME_MAP() */
595 if (cpumask_weight(&ktext_mask) == 1) { 563 if (cpumask_weight(&ktext_mask) == 1) {
596 pteval = set_remote_cache_cpu(pteval, 564 pteval = set_remote_cache_cpu(pteval,
597 cpumask_first(&ktext_mask)); 565 cpumask_first(&ktext_mask));
@@ -777,10 +745,7 @@ void __init paging_init(void)
777 745
778 kernel_physical_mapping_init(pgd_base); 746 kernel_physical_mapping_init(pgd_base);
779 747
780 /* 748 /* Fixed mappings, only the page table structure has to be created. */
781 * Fixed mappings, only the page table structure has to be
782 * created - mappings will be set by set_fixmap():
783 */
784 page_table_range_init(fix_to_virt(__end_of_fixed_addresses - 1), 749 page_table_range_init(fix_to_virt(__end_of_fixed_addresses - 1),
785 FIXADDR_TOP, pgd_base); 750 FIXADDR_TOP, pgd_base);
786 751
@@ -941,26 +906,6 @@ void __init pgtable_cache_init(void)
941 panic("pgtable_cache_init(): Cannot create pgd cache"); 906 panic("pgtable_cache_init(): Cannot create pgd cache");
942} 907}
943 908
944#if !CHIP_HAS_COHERENT_LOCAL_CACHE()
945/*
946 * The __w1data area holds data that is only written during initialization,
947 * and is read-only and thus freely cacheable thereafter. Fix the page
948 * table entries that cover that region accordingly.
949 */
950static void mark_w1data_ro(void)
951{
952 /* Loop over page table entries */
953 unsigned long addr = (unsigned long)__w1data_begin;
954 BUG_ON((addr & (PAGE_SIZE-1)) != 0);
955 for (; addr <= (unsigned long)__w1data_end - 1; addr += PAGE_SIZE) {
956 unsigned long pfn = kaddr_to_pfn((void *)addr);
957 pte_t *ptep = virt_to_pte(NULL, addr);
958 BUG_ON(pte_huge(*ptep)); /* not relevant for kdata_huge */
959 set_pte_at(&init_mm, addr, ptep, pfn_pte(pfn, PAGE_KERNEL_RO));
960 }
961}
962#endif
963
964#ifdef CONFIG_DEBUG_PAGEALLOC 909#ifdef CONFIG_DEBUG_PAGEALLOC
965static long __write_once initfree; 910static long __write_once initfree;
966#else 911#else
@@ -1000,7 +945,7 @@ static void free_init_pages(char *what, unsigned long begin, unsigned long end)
1000 */ 945 */
1001 int pfn = kaddr_to_pfn((void *)addr); 946 int pfn = kaddr_to_pfn((void *)addr);
1002 struct page *page = pfn_to_page(pfn); 947 struct page *page = pfn_to_page(pfn);
1003 pte_t *ptep = virt_to_pte(NULL, addr); 948 pte_t *ptep = virt_to_kpte(addr);
1004 if (!initfree) { 949 if (!initfree) {
1005 /* 950 /*
1006 * If debugging page accesses then do not free 951 * If debugging page accesses then do not free
@@ -1024,15 +969,11 @@ static void free_init_pages(char *what, unsigned long begin, unsigned long end)
1024 969
1025void free_initmem(void) 970void free_initmem(void)
1026{ 971{
1027 const unsigned long text_delta = MEM_SV_INTRPT - PAGE_OFFSET; 972 const unsigned long text_delta = MEM_SV_START - PAGE_OFFSET;
1028 973
1029 /* 974 /*
1030 * Evict the dirty initdata on the boot cpu, evict the w1data 975 * Evict the cache on all cores to avoid incoherence.
1031 * wherever it's homed, and evict all the init code everywhere. 976 * We are guaranteed that no one will touch the init pages any more.
1032 * We are guaranteed that no one will touch the init pages any
1033 * more, and although other cpus may be touching the w1data,
1034 * we only actually change the caching on tile64, which won't
1035 * be keeping local copies in the other tiles' caches anyway.
1036 */ 977 */
1037 homecache_evict(&cpu_cacheable_map); 978 homecache_evict(&cpu_cacheable_map);
1038 979
@@ -1043,26 +984,11 @@ void free_initmem(void)
1043 984
1044 /* 985 /*
1045 * Free the pages mapped from 0xc0000000 that correspond to code 986 * Free the pages mapped from 0xc0000000 that correspond to code
1046 * pages from MEM_SV_INTRPT that we won't use again after init. 987 * pages from MEM_SV_START that we won't use again after init.
1047 */ 988 */
1048 free_init_pages("unused kernel text", 989 free_init_pages("unused kernel text",
1049 (unsigned long)_sinittext - text_delta, 990 (unsigned long)_sinittext - text_delta,
1050 (unsigned long)_einittext - text_delta); 991 (unsigned long)_einittext - text_delta);
1051
1052#if !CHIP_HAS_COHERENT_LOCAL_CACHE()
1053 /*
1054 * Upgrade the .w1data section to globally cached.
1055 * We don't do this on tilepro, since the cache architecture
1056 * pretty much makes it irrelevant, and in any case we end
1057 * up having racing issues with other tiles that may touch
1058 * the data after we flush the cache but before we update
1059 * the PTEs and flush the TLBs, causing sharer shootdowns
1060 * later. Even though this is to clean data, it seems like
1061 * an unnecessary complication.
1062 */
1063 mark_w1data_ro();
1064#endif
1065
1066 /* Do a global TLB flush so everyone sees the changes. */ 992 /* Do a global TLB flush so everyone sees the changes. */
1067 flush_tlb_all(); 993 flush_tlb_all();
1068} 994}
diff --git a/arch/tile/mm/migrate_32.S b/arch/tile/mm/migrate_32.S
index 5305814bf187..772085491bf9 100644
--- a/arch/tile/mm/migrate_32.S
+++ b/arch/tile/mm/migrate_32.S
@@ -136,7 +136,7 @@ STD_ENTRY(flush_and_install_context)
136 move r8, zero /* asids */ 136 move r8, zero /* asids */
137 move r9, zero /* asidcount */ 137 move r9, zero /* asidcount */
138 } 138 }
139 jal hv_flush_remote 139 jal _hv_flush_remote
140 bnz r0, .Ldone 140 bnz r0, .Ldone
141 141
142 /* Now install the new page table. */ 142 /* Now install the new page table. */
@@ -152,7 +152,7 @@ STD_ENTRY(flush_and_install_context)
152 move r4, r_asid 152 move r4, r_asid
153 moveli r5, HV_CTX_DIRECTIO | CTX_PAGE_FLAG 153 moveli r5, HV_CTX_DIRECTIO | CTX_PAGE_FLAG
154 } 154 }
155 jal hv_install_context 155 jal _hv_install_context
156 bnz r0, .Ldone 156 bnz r0, .Ldone
157 157
158 /* Finally, flush the TLB. */ 158 /* Finally, flush the TLB. */
diff --git a/arch/tile/mm/migrate_64.S b/arch/tile/mm/migrate_64.S
index 1d15b10833d1..a49eee38f872 100644
--- a/arch/tile/mm/migrate_64.S
+++ b/arch/tile/mm/migrate_64.S
@@ -123,7 +123,7 @@ STD_ENTRY(flush_and_install_context)
123 } 123 }
124 { 124 {
125 move r8, zero /* asidcount */ 125 move r8, zero /* asidcount */
126 jal hv_flush_remote 126 jal _hv_flush_remote
127 } 127 }
128 bnez r0, 1f 128 bnez r0, 1f
129 129
@@ -136,7 +136,7 @@ STD_ENTRY(flush_and_install_context)
136 move r2, r_asid 136 move r2, r_asid
137 moveli r3, HV_CTX_DIRECTIO | CTX_PAGE_FLAG 137 moveli r3, HV_CTX_DIRECTIO | CTX_PAGE_FLAG
138 } 138 }
139 jal hv_install_context 139 jal _hv_install_context
140 bnez r0, 1f 140 bnez r0, 1f
141 141
142 /* Finally, flush the TLB. */ 142 /* Finally, flush the TLB. */
diff --git a/arch/tile/mm/mmap.c b/arch/tile/mm/mmap.c
index d67d91ebf63e..851a94e6ae58 100644
--- a/arch/tile/mm/mmap.c
+++ b/arch/tile/mm/mmap.c
@@ -58,16 +58,36 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
58#else 58#else
59 int is_32bit = 0; 59 int is_32bit = 0;
60#endif 60#endif
61 unsigned long random_factor = 0UL;
62
63 /*
64 * 8 bits of randomness in 32bit mmaps, 24 address space bits
65 * 12 bits of randomness in 64bit mmaps, 28 address space bits
66 */
67 if (current->flags & PF_RANDOMIZE) {
68 if (is_32bit)
69 random_factor = get_random_int() % (1<<8);
70 else
71 random_factor = get_random_int() % (1<<12);
72
73 random_factor <<= PAGE_SHIFT;
74 }
61 75
62 /* 76 /*
63 * Use standard layout if the expected stack growth is unlimited 77 * Use standard layout if the expected stack growth is unlimited
64 * or we are running native 64 bits. 78 * or we are running native 64 bits.
65 */ 79 */
66 if (!is_32bit || rlimit(RLIMIT_STACK) == RLIM_INFINITY) { 80 if (rlimit(RLIMIT_STACK) == RLIM_INFINITY) {
67 mm->mmap_base = TASK_UNMAPPED_BASE; 81 mm->mmap_base = TASK_UNMAPPED_BASE + random_factor;
68 mm->get_unmapped_area = arch_get_unmapped_area; 82 mm->get_unmapped_area = arch_get_unmapped_area;
69 } else { 83 } else {
70 mm->mmap_base = mmap_base(mm); 84 mm->mmap_base = mmap_base(mm);
71 mm->get_unmapped_area = arch_get_unmapped_area_topdown; 85 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
72 } 86 }
73} 87}
88
89unsigned long arch_randomize_brk(struct mm_struct *mm)
90{
91 unsigned long range_end = mm->brk + 0x02000000;
92 return randomize_range(mm->brk, range_end, 0) ? : mm->brk;
93}
diff --git a/arch/tile/mm/pgtable.c b/arch/tile/mm/pgtable.c
index dfd63ce87327..2deaddf3e01f 100644
--- a/arch/tile/mm/pgtable.c
+++ b/arch/tile/mm/pgtable.c
@@ -83,55 +83,6 @@ void show_mem(unsigned int filter)
83 } 83 }
84} 84}
85 85
86/*
87 * Associate a virtual page frame with a given physical page frame
88 * and protection flags for that frame.
89 */
90static void set_pte_pfn(unsigned long vaddr, unsigned long pfn, pgprot_t flags)
91{
92 pgd_t *pgd;
93 pud_t *pud;
94 pmd_t *pmd;
95 pte_t *pte;
96
97 pgd = swapper_pg_dir + pgd_index(vaddr);
98 if (pgd_none(*pgd)) {
99 BUG();
100 return;
101 }
102 pud = pud_offset(pgd, vaddr);
103 if (pud_none(*pud)) {
104 BUG();
105 return;
106 }
107 pmd = pmd_offset(pud, vaddr);
108 if (pmd_none(*pmd)) {
109 BUG();
110 return;
111 }
112 pte = pte_offset_kernel(pmd, vaddr);
113 /* <pfn,flags> stored as-is, to permit clearing entries */
114 set_pte(pte, pfn_pte(pfn, flags));
115
116 /*
117 * It's enough to flush this one mapping.
118 * This appears conservative since it is only called
119 * from __set_fixmap.
120 */
121 local_flush_tlb_page(NULL, vaddr, PAGE_SIZE);
122}
123
124void __set_fixmap(enum fixed_addresses idx, unsigned long phys, pgprot_t flags)
125{
126 unsigned long address = __fix_to_virt(idx);
127
128 if (idx >= __end_of_fixed_addresses) {
129 BUG();
130 return;
131 }
132 set_pte_pfn(address, phys >> PAGE_SHIFT, flags);
133}
134
135/** 86/**
136 * shatter_huge_page() - ensure a given address is mapped by a small page. 87 * shatter_huge_page() - ensure a given address is mapped by a small page.
137 * 88 *
@@ -374,6 +325,17 @@ void ptep_set_wrprotect(struct mm_struct *mm,
374 325
375#endif 326#endif
376 327
328/*
329 * Return a pointer to the PTE that corresponds to the given
330 * address in the given page table. A NULL page table just uses
331 * the standard kernel page table; the preferred API in this case
332 * is virt_to_kpte().
333 *
334 * The returned pointer can point to a huge page in other levels
335 * of the page table than the bottom, if the huge page is present
336 * in the page table. For bottom-level PTEs, the returned pointer
337 * can point to a PTE that is either present or not.
338 */
377pte_t *virt_to_pte(struct mm_struct* mm, unsigned long addr) 339pte_t *virt_to_pte(struct mm_struct* mm, unsigned long addr)
378{ 340{
379 pgd_t *pgd; 341 pgd_t *pgd;
@@ -387,13 +349,23 @@ pte_t *virt_to_pte(struct mm_struct* mm, unsigned long addr)
387 pud = pud_offset(pgd, addr); 349 pud = pud_offset(pgd, addr);
388 if (!pud_present(*pud)) 350 if (!pud_present(*pud))
389 return NULL; 351 return NULL;
352 if (pud_huge_page(*pud))
353 return (pte_t *)pud;
390 pmd = pmd_offset(pud, addr); 354 pmd = pmd_offset(pud, addr);
391 if (pmd_huge_page(*pmd))
392 return (pte_t *)pmd;
393 if (!pmd_present(*pmd)) 355 if (!pmd_present(*pmd))
394 return NULL; 356 return NULL;
357 if (pmd_huge_page(*pmd))
358 return (pte_t *)pmd;
395 return pte_offset_kernel(pmd, addr); 359 return pte_offset_kernel(pmd, addr);
396} 360}
361EXPORT_SYMBOL(virt_to_pte);
362
363pte_t *virt_to_kpte(unsigned long kaddr)
364{
365 BUG_ON(kaddr < PAGE_OFFSET);
366 return virt_to_pte(NULL, kaddr);
367}
368EXPORT_SYMBOL(virt_to_kpte);
397 369
398pgprot_t set_remote_cache_cpu(pgprot_t prot, int cpu) 370pgprot_t set_remote_cache_cpu(pgprot_t prot, int cpu)
399{ 371{
@@ -568,7 +540,7 @@ void __iomem *ioremap_prot(resource_size_t phys_addr, unsigned long size,
568 addr = area->addr; 540 addr = area->addr;
569 if (ioremap_page_range((unsigned long)addr, (unsigned long)addr + size, 541 if (ioremap_page_range((unsigned long)addr, (unsigned long)addr + size,
570 phys_addr, pgprot)) { 542 phys_addr, pgprot)) {
571 remove_vm_area((void *)(PAGE_MASK & (unsigned long) addr)); 543 free_vm_area(area);
572 return NULL; 544 return NULL;
573 } 545 }
574 return (__force void __iomem *) (offset + (char *)addr); 546 return (__force void __iomem *) (offset + (char *)addr);
diff --git a/drivers/edac/tile_edac.c b/drivers/edac/tile_edac.c
index a0820536b7d9..578f915ee195 100644
--- a/drivers/edac/tile_edac.c
+++ b/drivers/edac/tile_edac.c
@@ -257,7 +257,6 @@ static void __exit tile_edac_exit(void)
257 if (!pdev) 257 if (!pdev)
258 continue; 258 continue;
259 259
260 platform_set_drvdata(pdev, NULL);
261 platform_device_unregister(pdev); 260 platform_device_unregister(pdev);
262 } 261 }
263 platform_driver_unregister(&tile_edac_mc_driver); 262 platform_driver_unregister(&tile_edac_mc_driver);
diff --git a/drivers/tty/hvc/hvc_tile.c b/drivers/tty/hvc/hvc_tile.c
index 7a84a0595477..af8cdaa1dcb9 100644
--- a/drivers/tty/hvc/hvc_tile.c
+++ b/drivers/tty/hvc/hvc_tile.c
@@ -18,16 +18,46 @@
18#include <linux/delay.h> 18#include <linux/delay.h>
19#include <linux/err.h> 19#include <linux/err.h>
20#include <linux/init.h> 20#include <linux/init.h>
21#include <linux/interrupt.h>
22#include <linux/irq.h>
21#include <linux/moduleparam.h> 23#include <linux/moduleparam.h>
24#include <linux/platform_device.h>
22#include <linux/types.h> 25#include <linux/types.h>
23 26
27#include <asm/setup.h>
28#include <arch/sim_def.h>
29
24#include <hv/hypervisor.h> 30#include <hv/hypervisor.h>
25 31
26#include "hvc_console.h" 32#include "hvc_console.h"
27 33
34static int use_sim_console;
35static int __init sim_console(char *str)
36{
37 use_sim_console = 1;
38 return 0;
39}
40early_param("sim_console", sim_console);
41
42int tile_console_write(const char *buf, int count)
43{
44 if (unlikely(use_sim_console)) {
45 int i;
46 for (i = 0; i < count; ++i)
47 __insn_mtspr(SPR_SIM_CONTROL, SIM_CONTROL_PUTC |
48 (buf[i] << _SIM_CONTROL_OPERATOR_BITS));
49 __insn_mtspr(SPR_SIM_CONTROL, SIM_CONTROL_PUTC |
50 (SIM_PUTC_FLUSH_BINARY <<
51 _SIM_CONTROL_OPERATOR_BITS));
52 return 0;
53 } else {
54 return hv_console_write((HV_VirtAddr)buf, count);
55 }
56}
57
28static int hvc_tile_put_chars(uint32_t vt, const char *buf, int count) 58static int hvc_tile_put_chars(uint32_t vt, const char *buf, int count)
29{ 59{
30 return hv_console_write((HV_VirtAddr)buf, count); 60 return tile_console_write(buf, count);
31} 61}
32 62
33static int hvc_tile_get_chars(uint32_t vt, char *buf, int count) 63static int hvc_tile_get_chars(uint32_t vt, char *buf, int count)
@@ -44,25 +74,132 @@ static int hvc_tile_get_chars(uint32_t vt, char *buf, int count)
44 return i; 74 return i;
45} 75}
46 76
77#ifdef __tilegx__
78/*
79 * IRQ based callbacks.
80 */
81static int hvc_tile_notifier_add_irq(struct hvc_struct *hp, int irq)
82{
83 int rc;
84 int cpu = raw_smp_processor_id(); /* Choose an arbitrary cpu */
85 HV_Coord coord = { .x = cpu_x(cpu), .y = cpu_y(cpu) };
86
87 rc = notifier_add_irq(hp, irq);
88 if (rc)
89 return rc;
90
91 /*
92 * Request that the hypervisor start sending us interrupts.
93 * If the hypervisor returns an error, we still return 0, so that
94 * we can fall back to polling.
95 */
96 if (hv_console_set_ipi(KERNEL_PL, irq, coord) < 0)
97 notifier_del_irq(hp, irq);
98
99 return 0;
100}
101
102static void hvc_tile_notifier_del_irq(struct hvc_struct *hp, int irq)
103{
104 HV_Coord coord = { 0, 0 };
105
106 /* Tell the hypervisor to stop sending us interrupts. */
107 hv_console_set_ipi(KERNEL_PL, -1, coord);
108
109 notifier_del_irq(hp, irq);
110}
111
112static void hvc_tile_notifier_hangup_irq(struct hvc_struct *hp, int irq)
113{
114 hvc_tile_notifier_del_irq(hp, irq);
115}
116#endif
117
47static const struct hv_ops hvc_tile_get_put_ops = { 118static const struct hv_ops hvc_tile_get_put_ops = {
48 .get_chars = hvc_tile_get_chars, 119 .get_chars = hvc_tile_get_chars,
49 .put_chars = hvc_tile_put_chars, 120 .put_chars = hvc_tile_put_chars,
121#ifdef __tilegx__
122 .notifier_add = hvc_tile_notifier_add_irq,
123 .notifier_del = hvc_tile_notifier_del_irq,
124 .notifier_hangup = hvc_tile_notifier_hangup_irq,
125#endif
126};
127
128
129#ifdef __tilegx__
130static int hvc_tile_probe(struct platform_device *pdev)
131{
132 struct hvc_struct *hp;
133 int tile_hvc_irq;
134
135 /* Create our IRQ and register it. */
136 tile_hvc_irq = create_irq();
137 if (tile_hvc_irq < 0)
138 return -ENXIO;
139
140 tile_irq_activate(tile_hvc_irq, TILE_IRQ_PERCPU);
141 hp = hvc_alloc(0, tile_hvc_irq, &hvc_tile_get_put_ops, 128);
142 if (IS_ERR(hp)) {
143 destroy_irq(tile_hvc_irq);
144 return PTR_ERR(hp);
145 }
146 dev_set_drvdata(&pdev->dev, hp);
147
148 return 0;
149}
150
151static int hvc_tile_remove(struct platform_device *pdev)
152{
153 int rc;
154 struct hvc_struct *hp = dev_get_drvdata(&pdev->dev);
155
156 rc = hvc_remove(hp);
157 if (rc == 0)
158 destroy_irq(hp->data);
159
160 return rc;
161}
162
163static void hvc_tile_shutdown(struct platform_device *pdev)
164{
165 struct hvc_struct *hp = dev_get_drvdata(&pdev->dev);
166
167 hvc_tile_notifier_del_irq(hp, hp->data);
168}
169
170static struct platform_device hvc_tile_pdev = {
171 .name = "hvc-tile",
172 .id = 0,
173};
174
175static struct platform_driver hvc_tile_driver = {
176 .probe = hvc_tile_probe,
177 .remove = hvc_tile_remove,
178 .shutdown = hvc_tile_shutdown,
179 .driver = {
180 .name = "hvc-tile",
181 .owner = THIS_MODULE,
182 }
50}; 183};
184#endif
51 185
52static int __init hvc_tile_console_init(void) 186static int __init hvc_tile_console_init(void)
53{ 187{
54 extern void disable_early_printk(void);
55 hvc_instantiate(0, 0, &hvc_tile_get_put_ops); 188 hvc_instantiate(0, 0, &hvc_tile_get_put_ops);
56 add_preferred_console("hvc", 0, NULL); 189 add_preferred_console("hvc", 0, NULL);
57 disable_early_printk();
58 return 0; 190 return 0;
59} 191}
60console_initcall(hvc_tile_console_init); 192console_initcall(hvc_tile_console_init);
61 193
62static int __init hvc_tile_init(void) 194static int __init hvc_tile_init(void)
63{ 195{
64 struct hvc_struct *s; 196#ifndef __tilegx__
65 s = hvc_alloc(0, 0, &hvc_tile_get_put_ops, 128); 197 struct hvc_struct *hp;
66 return IS_ERR(s) ? PTR_ERR(s) : 0; 198 hp = hvc_alloc(0, 0, &hvc_tile_get_put_ops, 128);
199 return IS_ERR(hp) ? PTR_ERR(hp) : 0;
200#else
201 platform_device_register(&hvc_tile_pdev);
202 return platform_driver_register(&hvc_tile_driver);
203#endif
67} 204}
68device_initcall(hvc_tile_init); 205device_initcall(hvc_tile_init);
diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
index cc4c8682b47b..47c6e7b9e150 100644
--- a/drivers/tty/serial/Kconfig
+++ b/drivers/tty/serial/Kconfig
@@ -1439,6 +1439,15 @@ config SERIAL_EFM32_UART_CONSOLE
1439 depends on SERIAL_EFM32_UART=y 1439 depends on SERIAL_EFM32_UART=y
1440 select SERIAL_CORE_CONSOLE 1440 select SERIAL_CORE_CONSOLE
1441 1441
1442config SERIAL_TILEGX
1443 tristate "TILE-Gx on-chip serial port support"
1444 depends on TILEGX
1445 select TILE_GXIO_UART
1446 select SERIAL_CORE
1447 ---help---
1448 This device provides access to the on-chip UARTs on the TILE-Gx
1449 processor.
1450
1442config SERIAL_ARC 1451config SERIAL_ARC
1443 tristate "ARC UART driver support" 1452 tristate "ARC UART driver support"
1444 select SERIAL_CORE 1453 select SERIAL_CORE
diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile
index 47b679c547e9..3068c7722087 100644
--- a/drivers/tty/serial/Makefile
+++ b/drivers/tty/serial/Makefile
@@ -66,6 +66,7 @@ obj-$(CONFIG_SERIAL_KS8695) += serial_ks8695.o
66obj-$(CONFIG_SERIAL_OMAP) += omap-serial.o 66obj-$(CONFIG_SERIAL_OMAP) += omap-serial.o
67obj-$(CONFIG_SERIAL_ALTERA_UART) += altera_uart.o 67obj-$(CONFIG_SERIAL_ALTERA_UART) += altera_uart.o
68obj-$(CONFIG_SERIAL_ST_ASC) += st-asc.o 68obj-$(CONFIG_SERIAL_ST_ASC) += st-asc.o
69obj-$(CONFIG_SERIAL_TILEGX) += tilegx.o
69obj-$(CONFIG_KGDB_SERIAL_CONSOLE) += kgdboc.o 70obj-$(CONFIG_KGDB_SERIAL_CONSOLE) += kgdboc.o
70obj-$(CONFIG_SERIAL_QE) += ucc_uart.o 71obj-$(CONFIG_SERIAL_QE) += ucc_uart.o
71obj-$(CONFIG_SERIAL_TIMBERDALE) += timbuart.o 72obj-$(CONFIG_SERIAL_TIMBERDALE) += timbuart.o
diff --git a/drivers/tty/serial/tilegx.c b/drivers/tty/serial/tilegx.c
new file mode 100644
index 000000000000..f92d7e6bd876
--- /dev/null
+++ b/drivers/tty/serial/tilegx.c
@@ -0,0 +1,708 @@
1/*
2 * Copyright 2013 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 * TILEGx UART driver.
15 */
16
17#include <linux/delay.h>
18#include <linux/init.h>
19#include <linux/interrupt.h>
20#include <linux/io.h>
21#include <linux/irq.h>
22#include <linux/module.h>
23#include <linux/serial_core.h>
24#include <linux/tty.h>
25#include <linux/tty_flip.h>
26
27#include <gxio/common.h>
28#include <gxio/iorpc_globals.h>
29#include <gxio/iorpc_uart.h>
30#include <gxio/kiorpc.h>
31
32#include <hv/drv_uart_intf.h>
33
34/*
35 * Use device name ttyS, major 4, minor 64-65.
36 * This is the usual serial port name, 8250 conventional range.
37 */
38#define TILEGX_UART_MAJOR TTY_MAJOR
39#define TILEGX_UART_MINOR 64
40#define TILEGX_UART_NAME "ttyS"
41#define DRIVER_NAME_STRING "TILEGx_Serial"
42#define TILEGX_UART_REF_CLK 125000000; /* REF_CLK is always 125 MHz. */
43
44struct tile_uart_port {
45 /* UART port. */
46 struct uart_port uart;
47
48 /* GXIO device context. */
49 gxio_uart_context_t context;
50
51 /* UART access mutex. */
52 struct mutex mutex;
53
54 /* CPU receiving interrupts. */
55 int irq_cpu;
56};
57
58static struct tile_uart_port tile_uart_ports[TILEGX_UART_NR];
59static struct uart_driver tilegx_uart_driver;
60
61
62/*
63 * Read UART rx fifo, and insert the chars into tty buffer.
64 */
65static void receive_chars(struct tile_uart_port *tile_uart,
66 struct tty_struct *tty)
67{
68 int i;
69 char c;
70 UART_FIFO_COUNT_t count;
71 gxio_uart_context_t *context = &tile_uart->context;
72 struct tty_port *port = tty->port;
73
74 count.word = gxio_uart_read(context, UART_FIFO_COUNT);
75 for (i = 0; i < count.rfifo_count; i++) {
76 c = (char)gxio_uart_read(context, UART_RECEIVE_DATA);
77 tty_insert_flip_char(port, c, TTY_NORMAL);
78 }
79}
80
81
82/*
83 * Drain the Rx FIFO, called by interrupt handler.
84 */
85static void handle_receive(struct tile_uart_port *tile_uart)
86{
87 struct tty_port *port = &tile_uart->uart.state->port;
88 struct tty_struct *tty = tty_port_tty_get(port);
89 gxio_uart_context_t *context = &tile_uart->context;
90
91 if (!tty)
92 return;
93
94 /* First read UART rx fifo. */
95 receive_chars(tile_uart, tty);
96
97 /* Reset RFIFO_WE interrupt. */
98 gxio_uart_write(context, UART_INTERRUPT_STATUS,
99 UART_INTERRUPT_MASK__RFIFO_WE_MASK);
100
101 /* Final read, if any chars comes between the first read and
102 * the interrupt reset.
103 */
104 receive_chars(tile_uart, tty);
105
106 spin_unlock(&tile_uart->uart.lock);
107 tty_flip_buffer_push(port);
108 spin_lock(&tile_uart->uart.lock);
109 tty_kref_put(tty);
110}
111
112
113/*
114 * Push one char to UART Write FIFO.
115 * Return 0 on success, -1 if write filo is full.
116 */
117static int tilegx_putchar(gxio_uart_context_t *context, char c)
118{
119 UART_FLAG_t flag;
120 flag.word = gxio_uart_read(context, UART_FLAG);
121 if (flag.wfifo_full)
122 return -1;
123
124 gxio_uart_write(context, UART_TRANSMIT_DATA, (unsigned long)c);
125 return 0;
126}
127
128
129/*
130 * Send chars to UART Write FIFO; called by interrupt handler.
131 */
132static void handle_transmit(struct tile_uart_port *tile_uart)
133{
134 unsigned char ch;
135 struct uart_port *port;
136 struct circ_buf *xmit;
137 gxio_uart_context_t *context = &tile_uart->context;
138
139 /* First reset WFIFO_RE interrupt. */
140 gxio_uart_write(context, UART_INTERRUPT_STATUS,
141 UART_INTERRUPT_MASK__WFIFO_RE_MASK);
142
143 port = &tile_uart->uart;
144 xmit = &port->state->xmit;
145 if (port->x_char) {
146 if (tilegx_putchar(context, port->x_char))
147 return;
148 port->x_char = 0;
149 port->icount.tx++;
150 }
151
152 if (uart_circ_empty(xmit) || uart_tx_stopped(port))
153 return;
154
155 while (!uart_circ_empty(xmit)) {
156 ch = xmit->buf[xmit->tail];
157 if (tilegx_putchar(context, ch))
158 break;
159 xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
160 port->icount.tx++;
161 }
162
163 /* Reset WFIFO_RE interrupt. */
164 gxio_uart_write(context, UART_INTERRUPT_STATUS,
165 UART_INTERRUPT_MASK__WFIFO_RE_MASK);
166
167 if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
168 uart_write_wakeup(port);
169}
170
171
172/*
173 * UART Interrupt handler.
174 */
175static irqreturn_t tilegx_interrupt(int irq, void *dev_id)
176{
177 unsigned long flags;
178 UART_INTERRUPT_STATUS_t intr_stat;
179 struct tile_uart_port *tile_uart;
180 gxio_uart_context_t *context;
181 struct uart_port *port = dev_id;
182 irqreturn_t ret = IRQ_NONE;
183
184 spin_lock_irqsave(&port->lock, flags);
185
186 tile_uart = container_of(port, struct tile_uart_port, uart);
187 context = &tile_uart->context;
188 intr_stat.word = gxio_uart_read(context, UART_INTERRUPT_STATUS);
189
190 if (intr_stat.rfifo_we) {
191 handle_receive(tile_uart);
192 ret = IRQ_HANDLED;
193 }
194 if (intr_stat.wfifo_re) {
195 handle_transmit(tile_uart);
196 ret = IRQ_HANDLED;
197 }
198
199 spin_unlock_irqrestore(&port->lock, flags);
200 return ret;
201}
202
203
204/*
205 * Return TIOCSER_TEMT when transmitter FIFO is empty.
206 */
207static u_int tilegx_tx_empty(struct uart_port *port)
208{
209 int ret;
210 UART_FLAG_t flag;
211 struct tile_uart_port *tile_uart;
212 gxio_uart_context_t *context;
213
214 tile_uart = container_of(port, struct tile_uart_port, uart);
215 if (!mutex_trylock(&tile_uart->mutex))
216 return 0;
217 context = &tile_uart->context;
218
219 flag.word = gxio_uart_read(context, UART_FLAG);
220 ret = (flag.wfifo_empty) ? TIOCSER_TEMT : 0;
221 mutex_unlock(&tile_uart->mutex);
222
223 return ret;
224}
225
226
227/*
228 * Set state of the modem control output lines.
229 */
230static void tilegx_set_mctrl(struct uart_port *port, u_int mctrl)
231{
232 /* N/A */
233}
234
235
236/*
237 * Get state of the modem control input lines.
238 */
239static u_int tilegx_get_mctrl(struct uart_port *port)
240{
241 return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR;
242}
243
244
245/*
246 * Stop transmitting.
247 */
248static void tilegx_stop_tx(struct uart_port *port)
249{
250 /* N/A */
251}
252
253
254/*
255 * Start transmitting.
256 */
257static void tilegx_start_tx(struct uart_port *port)
258{
259 unsigned char ch;
260 struct circ_buf *xmit;
261 struct tile_uart_port *tile_uart;
262 gxio_uart_context_t *context;
263
264 tile_uart = container_of(port, struct tile_uart_port, uart);
265 if (!mutex_trylock(&tile_uart->mutex))
266 return;
267 context = &tile_uart->context;
268 xmit = &port->state->xmit;
269 if (port->x_char) {
270 if (tilegx_putchar(context, port->x_char))
271 return;
272 port->x_char = 0;
273 port->icount.tx++;
274 }
275
276 if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
277 mutex_unlock(&tile_uart->mutex);
278 return;
279 }
280
281 while (!uart_circ_empty(xmit)) {
282 ch = xmit->buf[xmit->tail];
283 if (tilegx_putchar(context, ch))
284 break;
285 xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
286 port->icount.tx++;
287 }
288
289 if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
290 uart_write_wakeup(port);
291
292 mutex_unlock(&tile_uart->mutex);
293}
294
295
296/*
297 * Stop receiving - port is in process of being closed.
298 */
299static void tilegx_stop_rx(struct uart_port *port)
300{
301 int err;
302 struct tile_uart_port *tile_uart;
303 gxio_uart_context_t *context;
304 int cpu;
305
306 tile_uart = container_of(port, struct tile_uart_port, uart);
307 if (!mutex_trylock(&tile_uart->mutex))
308 return;
309
310 context = &tile_uart->context;
311 cpu = tile_uart->irq_cpu;
312 err = gxio_uart_cfg_interrupt(context, cpu_x(cpu), cpu_y(cpu),
313 KERNEL_PL, -1);
314 mutex_unlock(&tile_uart->mutex);
315}
316
317
318/*
319 * Enable modem status interrupts.
320 */
321static void tilegx_enable_ms(struct uart_port *port)
322{
323 /* N/A */
324}
325
326/*
327 * Control the transmission of a break signal.
328 */
329static void tilegx_break_ctl(struct uart_port *port, int break_state)
330{
331 /* N/A */
332}
333
334
335/*
336 * Perform initialization and enable port for reception.
337 */
338static int tilegx_startup(struct uart_port *port)
339{
340 struct tile_uart_port *tile_uart;
341 gxio_uart_context_t *context;
342 int ret = 0;
343 int cpu = raw_smp_processor_id(); /* pick an arbitrary cpu */
344
345 tile_uart = container_of(port, struct tile_uart_port, uart);
346 if (mutex_lock_interruptible(&tile_uart->mutex))
347 return -EBUSY;
348 context = &tile_uart->context;
349
350 /* Now open the hypervisor device if we haven't already. */
351 if (context->fd < 0) {
352 UART_INTERRUPT_MASK_t intr_mask;
353
354 /* Initialize UART device. */
355 ret = gxio_uart_init(context, port->line);
356 if (ret) {
357 ret = -ENXIO;
358 goto err;
359 }
360
361 /* Create our IRQs. */
362 port->irq = create_irq();
363 if (port->irq < 0)
364 goto err_uart_dest;
365 tile_irq_activate(port->irq, TILE_IRQ_PERCPU);
366
367 /* Register our IRQs. */
368 ret = request_irq(port->irq, tilegx_interrupt, 0,
369 tilegx_uart_driver.driver_name, port);
370 if (ret)
371 goto err_dest_irq;
372
373 /* Request that the hardware start sending us interrupts. */
374 tile_uart->irq_cpu = cpu;
375 ret = gxio_uart_cfg_interrupt(context, cpu_x(cpu), cpu_y(cpu),
376 KERNEL_PL, port->irq);
377 if (ret)
378 goto err_free_irq;
379
380 /* Enable UART Tx/Rx Interrupt. */
381 intr_mask.word = gxio_uart_read(context, UART_INTERRUPT_MASK);
382 intr_mask.wfifo_re = 0;
383 intr_mask.rfifo_we = 0;
384 gxio_uart_write(context, UART_INTERRUPT_MASK, intr_mask.word);
385
386 /* Reset the Tx/Rx interrupt in case it's set. */
387 gxio_uart_write(context, UART_INTERRUPT_STATUS,
388 UART_INTERRUPT_MASK__WFIFO_RE_MASK |
389 UART_INTERRUPT_MASK__RFIFO_WE_MASK);
390 }
391
392 mutex_unlock(&tile_uart->mutex);
393 return ret;
394
395err_free_irq:
396 free_irq(port->irq, port);
397err_dest_irq:
398 destroy_irq(port->irq);
399err_uart_dest:
400 gxio_uart_destroy(context);
401 ret = -ENXIO;
402err:
403 mutex_unlock(&tile_uart->mutex);
404 return ret;
405}
406
407
408/*
409 * Release kernel resources if it is the last close, disable the port,
410 * free IRQ and close the port.
411 */
412static void tilegx_shutdown(struct uart_port *port)
413{
414 int err;
415 UART_INTERRUPT_MASK_t intr_mask;
416 struct tile_uart_port *tile_uart;
417 gxio_uart_context_t *context;
418 int cpu;
419
420 tile_uart = container_of(port, struct tile_uart_port, uart);
421 if (mutex_lock_interruptible(&tile_uart->mutex))
422 return;
423 context = &tile_uart->context;
424
425 /* Disable UART Tx/Rx Interrupt. */
426 intr_mask.word = gxio_uart_read(context, UART_INTERRUPT_MASK);
427 intr_mask.wfifo_re = 1;
428 intr_mask.rfifo_we = 1;
429 gxio_uart_write(context, UART_INTERRUPT_MASK, intr_mask.word);
430
431 /* Request that the hardware stop sending us interrupts. */
432 cpu = tile_uart->irq_cpu;
433 err = gxio_uart_cfg_interrupt(context, cpu_x(cpu), cpu_y(cpu),
434 KERNEL_PL, -1);
435
436 if (port->irq > 0) {
437 free_irq(port->irq, port);
438 destroy_irq(port->irq);
439 port->irq = 0;
440 }
441
442 gxio_uart_destroy(context);
443
444 mutex_unlock(&tile_uart->mutex);
445}
446
447
448/*
449 * Flush the buffer.
450 */
451static void tilegx_flush_buffer(struct uart_port *port)
452{
453 /* N/A */
454}
455
456
457/*
458 * Change the port parameters.
459 */
460static void tilegx_set_termios(struct uart_port *port,
461 struct ktermios *termios, struct ktermios *old)
462{
463 int err;
464 UART_DIVISOR_t divisor;
465 UART_TYPE_t type;
466 unsigned int baud;
467 struct tile_uart_port *tile_uart;
468 gxio_uart_context_t *context;
469
470 tile_uart = container_of(port, struct tile_uart_port, uart);
471 if (!mutex_trylock(&tile_uart->mutex))
472 return;
473 context = &tile_uart->context;
474
475 /* Open the hypervisor device if we haven't already. */
476 if (context->fd < 0) {
477 err = gxio_uart_init(context, port->line);
478 if (err) {
479 mutex_unlock(&tile_uart->mutex);
480 return;
481 }
482 }
483
484 divisor.word = gxio_uart_read(context, UART_DIVISOR);
485 type.word = gxio_uart_read(context, UART_TYPE);
486
487 /* Divisor. */
488 baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 16);
489 divisor.divisor = uart_get_divisor(port, baud);
490
491 /* Byte size. */
492 if ((termios->c_cflag & CSIZE) == CS7)
493 type.dbits = UART_TYPE__DBITS_VAL_SEVEN_DBITS;
494 else
495 type.dbits = UART_TYPE__DBITS_VAL_EIGHT_DBITS;
496
497 /* Parity. */
498 if (termios->c_cflag & PARENB) {
499 /* Mark or Space parity. */
500 if (termios->c_cflag & CMSPAR)
501 if (termios->c_cflag & PARODD)
502 type.ptype = UART_TYPE__PTYPE_VAL_MARK;
503 else
504 type.ptype = UART_TYPE__PTYPE_VAL_SPACE;
505 else if (termios->c_cflag & PARODD)
506 type.ptype = UART_TYPE__PTYPE_VAL_ODD;
507 else
508 type.ptype = UART_TYPE__PTYPE_VAL_EVEN;
509 } else
510 type.ptype = UART_TYPE__PTYPE_VAL_NONE;
511
512 /* Stop bits. */
513 if (termios->c_cflag & CSTOPB)
514 type.sbits = UART_TYPE__SBITS_VAL_TWO_SBITS;
515 else
516 type.sbits = UART_TYPE__SBITS_VAL_ONE_SBITS;
517
518 /* Set the uart paramters. */
519 gxio_uart_write(context, UART_DIVISOR, divisor.word);
520 gxio_uart_write(context, UART_TYPE, type.word);
521
522 mutex_unlock(&tile_uart->mutex);
523}
524
525
526/*
527 * Return string describing the specified port.
528 */
529static const char *tilegx_type(struct uart_port *port)
530{
531 return port->type == PORT_TILEGX ? DRIVER_NAME_STRING : NULL;
532}
533
534
535/*
536 * Release the resources being used by 'port'.
537 */
538static void tilegx_release_port(struct uart_port *port)
539{
540 /* Nothing to release. */
541}
542
543
544/*
545 * Request the resources being used by 'port'.
546 */
547static int tilegx_request_port(struct uart_port *port)
548{
549 /* Always present. */
550 return 0;
551}
552
553
554/*
555 * Configure/autoconfigure the port.
556 */
557static void tilegx_config_port(struct uart_port *port, int flags)
558{
559 if (flags & UART_CONFIG_TYPE)
560 port->type = PORT_TILEGX;
561}
562
563
564/*
565 * Verify the new serial_struct (for TIOCSSERIAL).
566 */
567static int tilegx_verify_port(struct uart_port *port,
568 struct serial_struct *ser)
569{
570 if ((ser->type != PORT_UNKNOWN) && (ser->type != PORT_TILEGX))
571 return -EINVAL;
572
573 return 0;
574}
575
576#ifdef CONFIG_CONSOLE_POLL
577
578/*
579 * Console polling routines for writing and reading from the uart while
580 * in an interrupt or debug context.
581 */
582
583static int tilegx_poll_get_char(struct uart_port *port)
584{
585 UART_FIFO_COUNT_t count;
586 gxio_uart_context_t *context;
587 struct tile_uart_port *tile_uart;
588
589 tile_uart = container_of(port, struct tile_uart_port, uart);
590 context = &tile_uart->context;
591 count.word = gxio_uart_read(context, UART_FIFO_COUNT);
592 if (count.rfifo_count == 0)
593 return NO_POLL_CHAR;
594 return (char)gxio_uart_read(context, UART_RECEIVE_DATA);
595}
596
597static void tilegx_poll_put_char(struct uart_port *port, unsigned char c)
598{
599 gxio_uart_context_t *context;
600 struct tile_uart_port *tile_uart;
601
602 tile_uart = container_of(port, struct tile_uart_port, uart);
603 context = &tile_uart->context;
604 gxio_uart_write(context, UART_TRANSMIT_DATA, (unsigned long)c);
605}
606
607#endif /* CONFIG_CONSOLE_POLL */
608
609
610static const struct uart_ops tilegx_ops = {
611 .tx_empty = tilegx_tx_empty,
612 .set_mctrl = tilegx_set_mctrl,
613 .get_mctrl = tilegx_get_mctrl,
614 .stop_tx = tilegx_stop_tx,
615 .start_tx = tilegx_start_tx,
616 .stop_rx = tilegx_stop_rx,
617 .enable_ms = tilegx_enable_ms,
618 .break_ctl = tilegx_break_ctl,
619 .startup = tilegx_startup,
620 .shutdown = tilegx_shutdown,
621 .flush_buffer = tilegx_flush_buffer,
622 .set_termios = tilegx_set_termios,
623 .type = tilegx_type,
624 .release_port = tilegx_release_port,
625 .request_port = tilegx_request_port,
626 .config_port = tilegx_config_port,
627 .verify_port = tilegx_verify_port,
628#ifdef CONFIG_CONSOLE_POLL
629 .poll_get_char = tilegx_poll_get_char,
630 .poll_put_char = tilegx_poll_put_char,
631#endif
632};
633
634
635static void tilegx_init_ports(void)
636{
637 int i;
638 struct uart_port *port;
639
640 for (i = 0; i < TILEGX_UART_NR; i++) {
641 port = &tile_uart_ports[i].uart;
642 port->ops = &tilegx_ops;
643 port->line = i;
644 port->type = PORT_TILEGX;
645 port->uartclk = TILEGX_UART_REF_CLK;
646 port->flags = UPF_BOOT_AUTOCONF;
647
648 tile_uart_ports[i].context.fd = -1;
649 mutex_init(&tile_uart_ports[i].mutex);
650 }
651}
652
653
654static struct uart_driver tilegx_uart_driver = {
655 .owner = THIS_MODULE,
656 .driver_name = DRIVER_NAME_STRING,
657 .dev_name = TILEGX_UART_NAME,
658 .major = TILEGX_UART_MAJOR,
659 .minor = TILEGX_UART_MINOR,
660 .nr = TILEGX_UART_NR,
661};
662
663
664static int __init tilegx_init(void)
665{
666 int i;
667 int ret;
668 struct tty_driver *tty_drv;
669
670 ret = uart_register_driver(&tilegx_uart_driver);
671 if (ret)
672 return ret;
673 tty_drv = tilegx_uart_driver.tty_driver;
674 tty_drv->init_termios.c_cflag = B115200 | CS8 | CREAD | HUPCL | CLOCAL;
675 tty_drv->init_termios.c_ispeed = 115200;
676 tty_drv->init_termios.c_ospeed = 115200;
677
678 tilegx_init_ports();
679
680 for (i = 0; i < TILEGX_UART_NR; i++) {
681 struct uart_port *port = &tile_uart_ports[i].uart;
682 ret = uart_add_one_port(&tilegx_uart_driver, port);
683 }
684
685 return 0;
686}
687
688
689static void __exit tilegx_exit(void)
690{
691 int i;
692 struct uart_port *port;
693
694 for (i = 0; i < TILEGX_UART_NR; i++) {
695 port = &tile_uart_ports[i].uart;
696 uart_remove_one_port(&tilegx_uart_driver, port);
697 }
698
699 uart_unregister_driver(&tilegx_uart_driver);
700}
701
702
703module_init(tilegx_init);
704module_exit(tilegx_exit);
705
706MODULE_AUTHOR("Tilera Corporation");
707MODULE_DESCRIPTION("TILEGx serial port driver");
708MODULE_LICENSE("GPL");
diff --git a/include/uapi/linux/serial_core.h b/include/uapi/linux/serial_core.h
index e40ebe124ced..b47dba2c1e6f 100644
--- a/include/uapi/linux/serial_core.h
+++ b/include/uapi/linux/serial_core.h
@@ -235,4 +235,7 @@
235/* ST ASC type numbers */ 235/* ST ASC type numbers */
236#define PORT_ASC 105 236#define PORT_ASC 105
237 237
238/* Tilera TILE-Gx UART */
239#define PORT_TILEGX 106
240
238#endif /* _UAPILINUX_SERIAL_CORE_H */ 241#endif /* _UAPILINUX_SERIAL_CORE_H */
diff --git a/samples/kprobes/kprobe_example.c b/samples/kprobes/kprobe_example.c
index ebf5e0c368ea..366db1a9fb65 100644
--- a/samples/kprobes/kprobe_example.c
+++ b/samples/kprobes/kprobe_example.c
@@ -37,6 +37,11 @@ static int handler_pre(struct kprobe *p, struct pt_regs *regs)
37 " status = 0x%lx\n", 37 " status = 0x%lx\n",
38 p->addr, regs->cp0_epc, regs->cp0_status); 38 p->addr, regs->cp0_epc, regs->cp0_status);
39#endif 39#endif
40#ifdef CONFIG_TILEGX
41 printk(KERN_INFO "pre_handler: p->addr = 0x%p, pc = 0x%lx,"
42 " ex1 = 0x%lx\n",
43 p->addr, regs->pc, regs->ex1);
44#endif
40 45
41 /* A dump_stack() here will give a stack backtrace */ 46 /* A dump_stack() here will give a stack backtrace */
42 return 0; 47 return 0;
@@ -58,6 +63,10 @@ static void handler_post(struct kprobe *p, struct pt_regs *regs,
58 printk(KERN_INFO "post_handler: p->addr = 0x%p, status = 0x%lx\n", 63 printk(KERN_INFO "post_handler: p->addr = 0x%p, status = 0x%lx\n",
59 p->addr, regs->cp0_status); 64 p->addr, regs->cp0_status);
60#endif 65#endif
66#ifdef CONFIG_TILEGX
67 printk(KERN_INFO "post_handler: p->addr = 0x%p, ex1 = 0x%lx\n",
68 p->addr, regs->ex1);
69#endif
61} 70}
62 71
63/* 72/*
diff --git a/scripts/recordmcount.pl b/scripts/recordmcount.pl
index 858966ab019c..a674fd5507c1 100755
--- a/scripts/recordmcount.pl
+++ b/scripts/recordmcount.pl
@@ -364,6 +364,10 @@ if ($arch eq "x86_64") {
364} elsif ($arch eq "blackfin") { 364} elsif ($arch eq "blackfin") {
365 $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\s__mcount\$"; 365 $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\s__mcount\$";
366 $mcount_adjust = -4; 366 $mcount_adjust = -4;
367} elsif ($arch eq "tilegx") {
368 $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\s__mcount\$";
369 $type = ".quad";
370 $alignment = 8;
367} else { 371} else {
368 die "Arch $arch is not supported with CONFIG_FTRACE_MCOUNT_RECORD"; 372 die "Arch $arch is not supported with CONFIG_FTRACE_MCOUNT_RECORD";
369} 373}