Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge git://git.kernel.org/pub/scm/linux/kernel/git/cmetcalf/linux-tile

Pull Tile arch updates from Chris Metcalf:
"These changes bring in a bunch of new functionality that has been
maintained internally at Tilera over the last year, plus other stray
bits of work that I've taken into the tile tree from other folks.

The changes include some PCI root complex work, interrupt-driven
console support, support for performing fast-path unaligned data
fixups by kernel-based JIT code generation, CONFIG_PREEMPT support,
vDSO support for gettimeofday(), a serial driver for the tilegx
on-chip UART, KGDB support, more optimized string routines, support
for ftrace and kprobes, improved ASLR, and many bug fixes.

We also remove support for the old TILE64 chip, which is no longer
buildable"

* git://git.kernel.org/pub/scm/linux/kernel/git/cmetcalf/linux-tile: (85 commits)
tile: refresh tile defconfig files
tile: rework <asm/cmpxchg.h>
tile PCI RC: make default consistent DMA mask 32-bit
tile: add null check for kzalloc in tile/kernel/setup.c
tile: make __write_once a synonym for __read_mostly
tile: remove support for TILE64
tile: use asm-generic/bitops/builtin-*.h
tile: eliminate no-op "noatomichash" boot argument
tile: use standard tile_bundle_bits type in traps.c
tile: simplify code referencing hypervisor API addresses
tile: change <asm/system.h> to <asm/switch_to.h> in comments
tile: mark pcibios_init() as __init
tile: check for correct compiler earlier in asm-offsets.c
tile: use standard 'generic-y' model for <asm/hw_irq.h>
tile: use asm-generic version of <asm/local64.h>
tile PCI RC: add comment about "PCI hole" problem
tile: remove DEBUG_EXTRA_FLAGS kernel config option
tile: add virt_to_kpte() API and clean up and document behavior
tile: support FRAME_POINTER
tile: support reporting Tilera hypervisor statistics
...

+8711 -2896
+7 -2
MAINTAINERS
··· 8373 8373 W: http://www.tilera.com/scm/ 8374 8374 S: Supported 8375 8375 F: arch/tile/ 8376 - F: drivers/tty/hvc/hvc_tile.c 8377 - F: drivers/net/ethernet/tile/ 8376 + F: drivers/char/tile-srom.c 8378 8377 F: drivers/edac/tile_edac.c 8378 + F: drivers/net/ethernet/tile/ 8379 + F: drivers/rtc/rtc-tile.c 8380 + F: drivers/tty/hvc/hvc_tile.c 8381 + F: drivers/tty/serial/tilegx.c 8382 + F: drivers/usb/host/*-tilegx.c 8383 + F: include/linux/usb/tilegx.h 8379 8384 8380 8385 TLAN NETWORK DRIVER 8381 8386 M: Samuel Chessman <chessman@tux.org>
+29 -2
arch/tile/Kconfig
··· 26 26 select HAVE_SYSCALL_TRACEPOINTS 27 27 select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE 28 28 select HAVE_DEBUG_STACKOVERFLOW 29 + select ARCH_WANT_FRAME_POINTERS 29 30 30 31 # FIXME: investigate whether we need/want these options. 31 32 # select HAVE_IOREMAP_PROT ··· 63 62 # larger than the default HPAGE_SIZE. 64 63 config HUGETLB_SUPER_PAGES 65 64 depends on HUGETLB_PAGE && TILEGX 65 + def_bool y 66 + 67 + config GENERIC_TIME_VSYSCALL 66 68 def_bool y 67 69 68 70 # FIXME: tilegx can implement a more efficient rwsem. ··· 116 112 config HVC_TILE 117 113 depends on TTY 118 114 select HVC_DRIVER 115 + select HVC_IRQ if TILEGX 119 116 def_bool y 120 117 121 118 config TILEGX 122 - bool "Building with TILE-Gx (64-bit) compiler and toolchain" 119 + bool "Building for TILE-Gx (64-bit) processor" 120 + select HAVE_FUNCTION_TRACER 121 + select HAVE_FUNCTION_TRACE_MCOUNT_TEST 122 + select HAVE_FUNCTION_GRAPH_TRACER 123 + select HAVE_DYNAMIC_FTRACE 124 + select HAVE_FTRACE_MCOUNT_RECORD 125 + select HAVE_KPROBES 126 + select HAVE_KRETPROBES 127 + select HAVE_ARCH_KGDB 123 128 124 129 config TILEPRO 125 130 def_bool !TILEGX ··· 207 194 def_bool y 208 195 depends on COMPAT && SYSVIPC 209 196 210 - # We do not currently support disabling HIGHMEM on tile64 and tilepro. 197 + # We do not currently support disabling HIGHMEM on tilepro. 211 198 config HIGHMEM 212 199 bool # "Support for more than 512 MB of RAM" 213 200 default !TILEGX ··· 313 300 314 301 source "mm/Kconfig" 315 302 303 + source "kernel/Kconfig.preempt" 304 + 316 305 config CMDLINE_BOOL 317 306 bool "Built-in kernel command line" 318 307 default n ··· 411 396 config NO_IOPORT 412 397 def_bool !PCI 413 398 399 + config TILE_PCI_IO 400 + bool "PCI I/O space support" 401 + default n 402 + depends on PCI 403 + depends on TILEGX 404 + ---help--- 405 + Enable PCI I/O space support on TILEGx. Since the PCI I/O space 406 + is used by few modern PCIe endpoint devices, its support is disabled 407 + by default to save the TRIO PIO Region resource for other purposes. 408 + 414 409 source "drivers/pci/Kconfig" 410 + 411 + source "drivers/pci/pcie/Kconfig" 415 412 416 413 config TILE_USB 417 414 tristate "Tilera USB host adapter support"
+6 -8
arch/tile/Kconfig.debug
··· 14 14 with klogd/syslogd. You should normally N here, 15 15 unless you want to debug such a crash. 16 16 17 - config DEBUG_EXTRA_FLAGS 18 - string "Additional compiler arguments when building with '-g'" 19 - depends on DEBUG_INFO 20 - default "" 17 + config TILE_HVGLUE_TRACE 18 + bool "Provide wrapper functions for hypervisor ABI calls" 19 + default n 21 20 help 22 - Debug info can be large, and flags like 23 - `-femit-struct-debug-baseonly' can reduce the kernel file 24 - size and build time noticeably. Such flags are often 25 - helpful if the main use of debug info is line number info. 21 + Provide wrapper functions for the hypervisor ABI calls 22 + defined in arch/tile/kernel/hvglue.S. This allows tracing 23 + mechanisms, etc., to have visibility into those calls. 26 24 27 25 endmenu
-4
arch/tile/Makefile
··· 30 30 # In kernel modules, this causes load failures due to unsupported relocations. 31 31 KBUILD_CFLAGS += -fno-asynchronous-unwind-tables 32 32 33 - ifneq ($(CONFIG_DEBUG_EXTRA_FLAGS),"") 34 - KBUILD_CFLAGS += $(CONFIG_DEBUG_EXTRA_FLAGS) 35 - endif 36 - 37 33 LIBGCC_PATH := \ 38 34 $(shell $(CC) $(KBUILD_CFLAGS) $(KCFLAGS) -print-libgcc-file-name) 39 35
+38 -203
arch/tile/configs/tilegx_defconfig
··· 1 1 CONFIG_TILEGX=y 2 - CONFIG_EXPERIMENTAL=y 3 - # CONFIG_LOCALVERSION_AUTO is not set 4 2 CONFIG_SYSVIPC=y 5 3 CONFIG_POSIX_MQUEUE=y 4 + CONFIG_FHANDLE=y 5 + CONFIG_AUDIT=y 6 + CONFIG_NO_HZ=y 6 7 CONFIG_BSD_PROCESS_ACCT=y 7 8 CONFIG_BSD_PROCESS_ACCT_V3=y 8 - CONFIG_FHANDLE=y 9 9 CONFIG_TASKSTATS=y 10 10 CONFIG_TASK_DELAY_ACCT=y 11 11 CONFIG_TASK_XACCT=y 12 12 CONFIG_TASK_IO_ACCOUNTING=y 13 - CONFIG_AUDIT=y 14 13 CONFIG_LOG_BUF_SHIFT=19 15 14 CONFIG_CGROUPS=y 16 15 CONFIG_CGROUP_DEBUG=y ··· 17 18 CONFIG_CPUSETS=y 18 19 CONFIG_CGROUP_CPUACCT=y 19 20 CONFIG_RESOURCE_COUNTERS=y 20 - CONFIG_CGROUP_MEMCG=y 21 - CONFIG_CGROUP_MEMCG_SWAP=y 22 21 CONFIG_CGROUP_SCHED=y 23 22 CONFIG_RT_GROUP_SCHED=y 24 23 CONFIG_BLK_CGROUP=y 25 24 CONFIG_NAMESPACES=y 26 25 CONFIG_RELAY=y 27 26 CONFIG_BLK_DEV_INITRD=y 27 + CONFIG_RD_XZ=y 28 28 CONFIG_SYSCTL_SYSCALL=y 29 29 CONFIG_EMBEDDED=y 30 30 # CONFIG_COMPAT_BRK is not set 31 31 CONFIG_PROFILING=y 32 + CONFIG_KPROBES=y 32 33 CONFIG_MODULES=y 33 34 CONFIG_MODULE_FORCE_LOAD=y 34 35 CONFIG_MODULE_UNLOAD=y ··· 44 45 CONFIG_SGI_PARTITION=y 45 46 CONFIG_SUN_PARTITION=y 46 47 CONFIG_KARMA_PARTITION=y 47 - CONFIG_EFI_PARTITION=y 48 48 CONFIG_CFQ_GROUP_IOSCHED=y 49 49 CONFIG_NR_CPUS=100 50 - CONFIG_NO_HZ=y 51 - CONFIG_HIGH_RES_TIMERS=y 52 50 CONFIG_HZ_100=y 51 + # CONFIG_COMPACTION is not set 52 + CONFIG_PREEMPT_VOLUNTARY=y 53 + CONFIG_TILE_PCI_IO=y 53 54 CONFIG_PCI_DEBUG=y 54 55 # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set 55 56 CONFIG_BINFMT_MISC=y ··· 107 108 CONFIG_IPV6_MROUTE=y 108 109 CONFIG_IPV6_PIMSM_V2=y 109 110 CONFIG_NETLABEL=y 110 - CONFIG_NETFILTER=y 111 - CONFIG_NF_CONNTRACK=m 112 - CONFIG_NF_CONNTRACK_SECMARK=y 113 - CONFIG_NF_CONNTRACK_ZONES=y 114 - CONFIG_NF_CONNTRACK_EVENTS=y 115 - CONFIG_NF_CT_PROTO_DCCP=m 116 - CONFIG_NF_CT_PROTO_UDPLITE=m 117 - CONFIG_NF_CONNTRACK_AMANDA=m 118 - CONFIG_NF_CONNTRACK_FTP=m 119 - CONFIG_NF_CONNTRACK_H323=m 120 - CONFIG_NF_CONNTRACK_IRC=m 121 - CONFIG_NF_CONNTRACK_NETBIOS_NS=m 122 - CONFIG_NF_CONNTRACK_PPTP=m 123 - CONFIG_NF_CONNTRACK_SANE=m 124 - CONFIG_NF_CONNTRACK_SIP=m 125 - CONFIG_NF_CONNTRACK_TFTP=m 126 - CONFIG_NETFILTER_TPROXY=m 127 - CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m 128 - CONFIG_NETFILTER_XT_TARGET_CONNMARK=m 129 - CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m 130 - CONFIG_NETFILTER_XT_TARGET_CT=m 131 - CONFIG_NETFILTER_XT_TARGET_DSCP=m 132 - CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m 133 - CONFIG_NETFILTER_XT_TARGET_MARK=m 134 - CONFIG_NETFILTER_XT_TARGET_NFLOG=m 135 - CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m 136 - CONFIG_NETFILTER_XT_TARGET_TEE=m 137 - CONFIG_NETFILTER_XT_TARGET_TPROXY=m 138 - CONFIG_NETFILTER_XT_TARGET_TRACE=m 139 - CONFIG_NETFILTER_XT_TARGET_SECMARK=m 140 - CONFIG_NETFILTER_XT_TARGET_TCPMSS=m 141 - CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m 142 - CONFIG_NETFILTER_XT_MATCH_CLUSTER=m 143 - CONFIG_NETFILTER_XT_MATCH_COMMENT=m 144 - CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m 145 - CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m 146 - CONFIG_NETFILTER_XT_MATCH_CONNMARK=m 147 - CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m 148 - CONFIG_NETFILTER_XT_MATCH_DCCP=m 149 - CONFIG_NETFILTER_XT_MATCH_DSCP=m 150 - CONFIG_NETFILTER_XT_MATCH_ESP=m 151 - CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m 152 - CONFIG_NETFILTER_XT_MATCH_HELPER=m 153 - CONFIG_NETFILTER_XT_MATCH_IPRANGE=m 154 - CONFIG_NETFILTER_XT_MATCH_IPVS=m 155 - CONFIG_NETFILTER_XT_MATCH_LENGTH=m 156 - CONFIG_NETFILTER_XT_MATCH_LIMIT=m 157 - CONFIG_NETFILTER_XT_MATCH_MAC=m 158 - CONFIG_NETFILTER_XT_MATCH_MARK=m 159 - CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m 160 - CONFIG_NETFILTER_XT_MATCH_OSF=m 161 - CONFIG_NETFILTER_XT_MATCH_OWNER=m 162 - CONFIG_NETFILTER_XT_MATCH_POLICY=m 163 - CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m 164 - CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m 165 - CONFIG_NETFILTER_XT_MATCH_QUOTA=m 166 - CONFIG_NETFILTER_XT_MATCH_RATEEST=m 167 - CONFIG_NETFILTER_XT_MATCH_REALM=m 168 - CONFIG_NETFILTER_XT_MATCH_RECENT=m 169 - CONFIG_NETFILTER_XT_MATCH_SOCKET=m 170 - CONFIG_NETFILTER_XT_MATCH_STATE=m 171 - CONFIG_NETFILTER_XT_MATCH_STATISTIC=m 172 - CONFIG_NETFILTER_XT_MATCH_STRING=m 173 - CONFIG_NETFILTER_XT_MATCH_TCPMSS=m 174 - CONFIG_NETFILTER_XT_MATCH_TIME=m 175 - CONFIG_NETFILTER_XT_MATCH_U32=m 176 - CONFIG_IP_VS=m 177 - CONFIG_IP_VS_IPV6=y 178 - CONFIG_IP_VS_PROTO_TCP=y 179 - CONFIG_IP_VS_PROTO_UDP=y 180 - CONFIG_IP_VS_PROTO_ESP=y 181 - CONFIG_IP_VS_PROTO_AH=y 182 - CONFIG_IP_VS_PROTO_SCTP=y 183 - CONFIG_IP_VS_RR=m 184 - CONFIG_IP_VS_WRR=m 185 - CONFIG_IP_VS_LC=m 186 - CONFIG_IP_VS_WLC=m 187 - CONFIG_IP_VS_LBLC=m 188 - CONFIG_IP_VS_LBLCR=m 189 - CONFIG_IP_VS_SED=m 190 - CONFIG_IP_VS_NQ=m 191 - CONFIG_NF_CONNTRACK_IPV4=m 192 - # CONFIG_NF_CONNTRACK_PROC_COMPAT is not set 193 - CONFIG_IP_NF_QUEUE=m 194 - CONFIG_IP_NF_IPTABLES=y 195 - CONFIG_IP_NF_MATCH_AH=m 196 - CONFIG_IP_NF_MATCH_ECN=m 197 - CONFIG_IP_NF_MATCH_TTL=m 198 - CONFIG_IP_NF_FILTER=y 199 - CONFIG_IP_NF_TARGET_REJECT=y 200 - CONFIG_IP_NF_TARGET_LOG=m 201 - CONFIG_IP_NF_TARGET_ULOG=m 202 - CONFIG_IP_NF_MANGLE=m 203 - CONFIG_IP_NF_TARGET_ECN=m 204 - CONFIG_IP_NF_TARGET_TTL=m 205 - CONFIG_IP_NF_RAW=m 206 - CONFIG_IP_NF_SECURITY=m 207 - CONFIG_IP_NF_ARPTABLES=m 208 - CONFIG_IP_NF_ARPFILTER=m 209 - CONFIG_IP_NF_ARP_MANGLE=m 210 - CONFIG_NF_CONNTRACK_IPV6=m 211 - CONFIG_IP6_NF_QUEUE=m 212 - CONFIG_IP6_NF_IPTABLES=m 213 - CONFIG_IP6_NF_MATCH_AH=m 214 - CONFIG_IP6_NF_MATCH_EUI64=m 215 - CONFIG_IP6_NF_MATCH_FRAG=m 216 - CONFIG_IP6_NF_MATCH_OPTS=m 217 - CONFIG_IP6_NF_MATCH_HL=m 218 - CONFIG_IP6_NF_MATCH_IPV6HEADER=m 219 - CONFIG_IP6_NF_MATCH_MH=m 220 - CONFIG_IP6_NF_MATCH_RT=m 221 - CONFIG_IP6_NF_TARGET_HL=m 222 - CONFIG_IP6_NF_TARGET_LOG=m 223 - CONFIG_IP6_NF_FILTER=m 224 - CONFIG_IP6_NF_TARGET_REJECT=m 225 - CONFIG_IP6_NF_MANGLE=m 226 - CONFIG_IP6_NF_RAW=m 227 - CONFIG_IP6_NF_SECURITY=m 228 - CONFIG_BRIDGE_NF_EBTABLES=m 229 - CONFIG_BRIDGE_EBT_BROUTE=m 230 - CONFIG_BRIDGE_EBT_T_FILTER=m 231 - CONFIG_BRIDGE_EBT_T_NAT=m 232 - CONFIG_BRIDGE_EBT_802_3=m 233 - CONFIG_BRIDGE_EBT_AMONG=m 234 - CONFIG_BRIDGE_EBT_ARP=m 235 - CONFIG_BRIDGE_EBT_IP=m 236 - CONFIG_BRIDGE_EBT_IP6=m 237 - CONFIG_BRIDGE_EBT_LIMIT=m 238 - CONFIG_BRIDGE_EBT_MARK=m 239 - CONFIG_BRIDGE_EBT_PKTTYPE=m 240 - CONFIG_BRIDGE_EBT_STP=m 241 - CONFIG_BRIDGE_EBT_VLAN=m 242 - CONFIG_BRIDGE_EBT_ARPREPLY=m 243 - CONFIG_BRIDGE_EBT_DNAT=m 244 - CONFIG_BRIDGE_EBT_MARK_T=m 245 - CONFIG_BRIDGE_EBT_REDIRECT=m 246 - CONFIG_BRIDGE_EBT_SNAT=m 247 - CONFIG_BRIDGE_EBT_LOG=m 248 - CONFIG_BRIDGE_EBT_ULOG=m 249 - CONFIG_BRIDGE_EBT_NFLOG=m 250 111 CONFIG_RDS=m 251 112 CONFIG_RDS_TCP=m 252 113 CONFIG_BRIDGE=m 253 - CONFIG_NET_DSA=y 254 114 CONFIG_VLAN_8021Q=m 255 115 CONFIG_VLAN_8021Q_GVRP=y 256 116 CONFIG_PHONET=m ··· 150 292 CONFIG_NET_ACT_GACT=m 151 293 CONFIG_GACT_PROB=y 152 294 CONFIG_NET_ACT_MIRRED=m 153 - CONFIG_NET_ACT_IPT=m 154 295 CONFIG_NET_ACT_NAT=m 155 296 CONFIG_NET_ACT_PEDIT=m 156 297 CONFIG_NET_ACT_SIMP=m 157 298 CONFIG_NET_ACT_SKBEDIT=m 158 299 CONFIG_NET_CLS_IND=y 159 300 CONFIG_DCB=y 301 + CONFIG_DNS_RESOLVER=y 160 302 # CONFIG_WIRELESS is not set 161 303 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" 162 304 CONFIG_DEVTMPFS=y ··· 175 317 CONFIG_SCSI_CONSTANTS=y 176 318 CONFIG_SCSI_LOGGING=y 177 319 CONFIG_SCSI_SAS_ATA=y 320 + CONFIG_ISCSI_TCP=m 178 321 CONFIG_SCSI_MVSAS=y 179 322 # CONFIG_SCSI_MVSAS_DEBUG is not set 180 323 CONFIG_SCSI_MVSAS_TASKLET=y 181 324 CONFIG_ATA=y 325 + CONFIG_SATA_AHCI=y 182 326 CONFIG_SATA_SIL24=y 183 327 # CONFIG_ATA_SFF is not set 184 328 CONFIG_MD=y ··· 203 343 CONFIG_DM_MULTIPATH_ST=m 204 344 CONFIG_DM_DELAY=m 205 345 CONFIG_DM_UEVENT=y 346 + CONFIG_TARGET_CORE=m 347 + CONFIG_TCM_IBLOCK=m 348 + CONFIG_TCM_FILEIO=m 349 + CONFIG_TCM_PSCSI=m 350 + CONFIG_LOOPBACK_TARGET=m 351 + CONFIG_ISCSI_TARGET=m 206 352 CONFIG_FUSION=y 207 353 CONFIG_FUSION_SAS=y 208 354 CONFIG_NETDEVICES=y ··· 225 359 CONFIG_NET_DSA_MV88E6060=y 226 360 CONFIG_NET_DSA_MV88E6131=y 227 361 CONFIG_NET_DSA_MV88E6123_61_65=y 228 - # CONFIG_NET_VENDOR_3COM is not set 229 - # CONFIG_NET_VENDOR_ADAPTEC is not set 230 - # CONFIG_NET_VENDOR_ALTEON is not set 231 - # CONFIG_NET_VENDOR_AMD is not set 232 - # CONFIG_NET_VENDOR_ATHEROS is not set 233 - # CONFIG_NET_VENDOR_BROADCOM is not set 234 - # CONFIG_NET_VENDOR_BROCADE is not set 235 - # CONFIG_NET_VENDOR_CHELSIO is not set 236 - # CONFIG_NET_VENDOR_CISCO is not set 237 - # CONFIG_NET_VENDOR_DEC is not set 238 - # CONFIG_NET_VENDOR_DLINK is not set 239 - # CONFIG_NET_VENDOR_EMULEX is not set 240 - # CONFIG_NET_VENDOR_EXAR is not set 241 - # CONFIG_NET_VENDOR_HP is not set 242 - # CONFIG_NET_VENDOR_INTEL is not set 243 - # CONFIG_NET_VENDOR_MARVELL is not set 244 - # CONFIG_NET_VENDOR_MELLANOX is not set 245 - # CONFIG_NET_VENDOR_MICREL is not set 246 - # CONFIG_NET_VENDOR_MYRI is not set 247 - # CONFIG_NET_VENDOR_NATSEMI is not set 248 - # CONFIG_NET_VENDOR_NVIDIA is not set 249 - # CONFIG_NET_VENDOR_OKI is not set 250 - # CONFIG_NET_PACKET_ENGINE is not set 251 - # CONFIG_NET_VENDOR_QLOGIC is not set 252 - # CONFIG_NET_VENDOR_REALTEK is not set 253 - # CONFIG_NET_VENDOR_RDC is not set 254 - # CONFIG_NET_VENDOR_SEEQ is not set 255 - # CONFIG_NET_VENDOR_SILAN is not set 256 - # CONFIG_NET_VENDOR_SIS is not set 257 - # CONFIG_NET_VENDOR_SMSC is not set 258 - # CONFIG_NET_VENDOR_STMICRO is not set 259 - # CONFIG_NET_VENDOR_SUN is not set 260 - # CONFIG_NET_VENDOR_TEHUTI is not set 261 - # CONFIG_NET_VENDOR_TI is not set 262 - # CONFIG_TILE_NET is not set 263 - # CONFIG_NET_VENDOR_VIA is not set 362 + CONFIG_SKY2=y 363 + CONFIG_PTP_1588_CLOCK_TILEGX=y 264 364 # CONFIG_WLAN is not set 265 365 # CONFIG_INPUT_MOUSEDEV is not set 266 366 # CONFIG_INPUT_KEYBOARD is not set ··· 234 402 # CONFIG_SERIO is not set 235 403 # CONFIG_VT is not set 236 404 # CONFIG_LEGACY_PTYS is not set 405 + CONFIG_SERIAL_TILEGX=y 237 406 CONFIG_HW_RANDOM=y 238 407 CONFIG_HW_RANDOM_TIMERIOMEM=m 239 408 CONFIG_I2C=y ··· 243 410 CONFIG_WATCHDOG=y 244 411 CONFIG_WATCHDOG_NOWAYOUT=y 245 412 # CONFIG_VGA_ARB is not set 246 - # CONFIG_HID_SUPPORT is not set 413 + CONFIG_DRM=m 414 + CONFIG_DRM_TDFX=m 415 + CONFIG_DRM_R128=m 416 + CONFIG_DRM_MGA=m 417 + CONFIG_DRM_VIA=m 418 + CONFIG_DRM_SAVAGE=m 247 419 CONFIG_USB=y 248 - # CONFIG_USB_DEVICE_CLASS is not set 249 420 CONFIG_USB_EHCI_HCD=y 250 421 CONFIG_USB_OHCI_HCD=y 251 422 CONFIG_USB_STORAGE=y 252 - CONFIG_USB_LIBUSUAL=y 253 423 CONFIG_EDAC=y 254 424 CONFIG_EDAC_MM_EDAC=y 255 425 CONFIG_RTC_CLASS=y ··· 300 464 CONFIG_CRAMFS=m 301 465 CONFIG_SQUASHFS=m 302 466 CONFIG_NFS_FS=m 303 - CONFIG_NFS_V3=y 304 467 CONFIG_NFS_V3_ACL=y 305 - CONFIG_NFS_V4=y 468 + CONFIG_NFS_V4=m 306 469 CONFIG_NFS_V4_1=y 307 470 CONFIG_NFS_FSCACHE=y 308 471 CONFIG_NFSD=m ··· 354 519 CONFIG_NLS_KOI8_R=m 355 520 CONFIG_NLS_KOI8_U=m 356 521 CONFIG_NLS_UTF8=m 522 + CONFIG_DLM=m 357 523 CONFIG_DLM_DEBUG=y 524 + CONFIG_DYNAMIC_DEBUG=y 525 + CONFIG_DEBUG_INFO=y 526 + CONFIG_DEBUG_INFO_REDUCED=y 358 527 # CONFIG_ENABLE_WARN_DEPRECATED is not set 359 - CONFIG_MAGIC_SYSRQ=y 360 528 CONFIG_STRIP_ASM_SYMS=y 361 529 CONFIG_DEBUG_FS=y 362 530 CONFIG_HEADERS_CHECK=y 531 + # CONFIG_FRAME_POINTER is not set 532 + CONFIG_DEBUG_FORCE_WEAK_PER_CPU=y 533 + CONFIG_DEBUG_VM=y 534 + CONFIG_DEBUG_MEMORY_INIT=y 535 + CONFIG_DEBUG_STACKOVERFLOW=y 363 536 CONFIG_LOCKUP_DETECTOR=y 364 537 CONFIG_SCHEDSTATS=y 365 538 CONFIG_TIMER_STATS=y 366 - CONFIG_DEBUG_INFO=y 367 - CONFIG_DEBUG_INFO_REDUCED=y 368 - CONFIG_DEBUG_VM=y 369 - CONFIG_DEBUG_MEMORY_INIT=y 370 539 CONFIG_DEBUG_LIST=y 371 540 CONFIG_DEBUG_CREDENTIALS=y 372 - CONFIG_DEBUG_FORCE_WEAK_PER_CPU=y 373 - CONFIG_DYNAMIC_DEBUG=y 541 + CONFIG_RCU_CPU_STALL_TIMEOUT=60 374 542 CONFIG_ASYNC_RAID6_TEST=m 375 - CONFIG_DEBUG_STACKOVERFLOW=y 543 + CONFIG_KGDB=y 376 544 CONFIG_KEYS_DEBUG_PROC_KEYS=y 377 545 CONFIG_SECURITY=y 378 546 CONFIG_SECURITYFS=y ··· 384 546 CONFIG_SECURITY_SELINUX=y 385 547 CONFIG_SECURITY_SELINUX_BOOTPARAM=y 386 548 CONFIG_SECURITY_SELINUX_DISABLE=y 387 - CONFIG_CRYPTO_NULL=m 388 549 CONFIG_CRYPTO_PCRYPT=m 389 550 CONFIG_CRYPTO_CRYPTD=m 390 551 CONFIG_CRYPTO_TEST=m ··· 396 559 CONFIG_CRYPTO_HMAC=y 397 560 CONFIG_CRYPTO_XCBC=m 398 561 CONFIG_CRYPTO_VMAC=m 399 - CONFIG_CRYPTO_CRC32C=y 400 562 CONFIG_CRYPTO_MICHAEL_MIC=m 401 563 CONFIG_CRYPTO_RMD128=m 402 564 CONFIG_CRYPTO_RMD160=m 403 565 CONFIG_CRYPTO_RMD256=m 404 566 CONFIG_CRYPTO_RMD320=m 405 567 CONFIG_CRYPTO_SHA1=y 406 - CONFIG_CRYPTO_SHA256=m 407 568 CONFIG_CRYPTO_SHA512=m 408 569 CONFIG_CRYPTO_TGR192=m 409 570 CONFIG_CRYPTO_WP512=m
+22 -65
arch/tile/configs/tilepro_defconfig
··· 1 - CONFIG_EXPERIMENTAL=y 2 - # CONFIG_LOCALVERSION_AUTO is not set 3 1 CONFIG_SYSVIPC=y 4 2 CONFIG_POSIX_MQUEUE=y 3 + CONFIG_AUDIT=y 4 + CONFIG_NO_HZ=y 5 + CONFIG_HIGH_RES_TIMERS=y 5 6 CONFIG_BSD_PROCESS_ACCT=y 6 7 CONFIG_BSD_PROCESS_ACCT_V3=y 7 - CONFIG_FHANDLE=y 8 8 CONFIG_TASKSTATS=y 9 9 CONFIG_TASK_DELAY_ACCT=y 10 10 CONFIG_TASK_XACCT=y 11 11 CONFIG_TASK_IO_ACCOUNTING=y 12 - CONFIG_AUDIT=y 13 12 CONFIG_LOG_BUF_SHIFT=19 14 13 CONFIG_CGROUPS=y 15 14 CONFIG_CGROUP_DEBUG=y ··· 16 17 CONFIG_CPUSETS=y 17 18 CONFIG_CGROUP_CPUACCT=y 18 19 CONFIG_RESOURCE_COUNTERS=y 19 - CONFIG_CGROUP_MEMCG=y 20 - CONFIG_CGROUP_MEMCG_SWAP=y 21 20 CONFIG_CGROUP_SCHED=y 22 21 CONFIG_RT_GROUP_SCHED=y 23 22 CONFIG_BLK_CGROUP=y 24 23 CONFIG_NAMESPACES=y 25 24 CONFIG_RELAY=y 26 25 CONFIG_BLK_DEV_INITRD=y 26 + CONFIG_RD_XZ=y 27 27 CONFIG_SYSCTL_SYSCALL=y 28 28 CONFIG_EMBEDDED=y 29 29 # CONFIG_COMPAT_BRK is not set ··· 42 44 CONFIG_SGI_PARTITION=y 43 45 CONFIG_SUN_PARTITION=y 44 46 CONFIG_KARMA_PARTITION=y 45 - CONFIG_EFI_PARTITION=y 46 47 CONFIG_CFQ_GROUP_IOSCHED=y 47 - CONFIG_NO_HZ=y 48 - CONFIG_HIGH_RES_TIMERS=y 49 48 CONFIG_HZ_100=y 49 + # CONFIG_COMPACTION is not set 50 + CONFIG_PREEMPT_VOLUNTARY=y 50 51 CONFIG_PCI_DEBUG=y 51 52 # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set 52 53 CONFIG_BINFMT_MISC=y ··· 119 122 CONFIG_NF_CONNTRACK_SANE=m 120 123 CONFIG_NF_CONNTRACK_SIP=m 121 124 CONFIG_NF_CONNTRACK_TFTP=m 122 - CONFIG_NETFILTER_TPROXY=m 123 125 CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m 124 126 CONFIG_NETFILTER_XT_TARGET_CONNMARK=m 125 127 CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m 126 - CONFIG_NETFILTER_XT_TARGET_CT=m 127 128 CONFIG_NETFILTER_XT_TARGET_DSCP=m 128 129 CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m 129 130 CONFIG_NETFILTER_XT_TARGET_MARK=m 130 131 CONFIG_NETFILTER_XT_TARGET_NFLOG=m 131 132 CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m 133 + CONFIG_NETFILTER_XT_TARGET_NOTRACK=m 132 134 CONFIG_NETFILTER_XT_TARGET_TEE=m 133 135 CONFIG_NETFILTER_XT_TARGET_TPROXY=m 134 136 CONFIG_NETFILTER_XT_TARGET_TRACE=m ··· 185 189 CONFIG_IP_VS_NQ=m 186 190 CONFIG_NF_CONNTRACK_IPV4=m 187 191 # CONFIG_NF_CONNTRACK_PROC_COMPAT is not set 188 - CONFIG_IP_NF_QUEUE=m 189 192 CONFIG_IP_NF_IPTABLES=y 190 193 CONFIG_IP_NF_MATCH_AH=m 191 194 CONFIG_IP_NF_MATCH_ECN=m 192 195 CONFIG_IP_NF_MATCH_TTL=m 193 196 CONFIG_IP_NF_FILTER=y 194 197 CONFIG_IP_NF_TARGET_REJECT=y 195 - CONFIG_IP_NF_TARGET_LOG=m 196 198 CONFIG_IP_NF_TARGET_ULOG=m 197 199 CONFIG_IP_NF_MANGLE=m 198 200 CONFIG_IP_NF_TARGET_ECN=m ··· 201 207 CONFIG_IP_NF_ARPFILTER=m 202 208 CONFIG_IP_NF_ARP_MANGLE=m 203 209 CONFIG_NF_CONNTRACK_IPV6=m 204 - CONFIG_IP6_NF_QUEUE=m 205 - CONFIG_IP6_NF_IPTABLES=m 206 210 CONFIG_IP6_NF_MATCH_AH=m 207 211 CONFIG_IP6_NF_MATCH_EUI64=m 208 212 CONFIG_IP6_NF_MATCH_FRAG=m ··· 210 218 CONFIG_IP6_NF_MATCH_MH=m 211 219 CONFIG_IP6_NF_MATCH_RT=m 212 220 CONFIG_IP6_NF_TARGET_HL=m 213 - CONFIG_IP6_NF_TARGET_LOG=m 214 221 CONFIG_IP6_NF_FILTER=m 215 222 CONFIG_IP6_NF_TARGET_REJECT=m 216 223 CONFIG_IP6_NF_MANGLE=m ··· 240 249 CONFIG_RDS=m 241 250 CONFIG_RDS_TCP=m 242 251 CONFIG_BRIDGE=m 243 - CONFIG_NET_DSA=y 244 252 CONFIG_VLAN_8021Q=m 245 253 CONFIG_VLAN_8021Q_GVRP=y 246 254 CONFIG_PHONET=m ··· 287 297 CONFIG_NET_ACT_SKBEDIT=m 288 298 CONFIG_NET_CLS_IND=y 289 299 CONFIG_DCB=y 300 + CONFIG_DNS_RESOLVER=y 290 301 # CONFIG_WIRELESS is not set 291 302 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" 292 303 CONFIG_DEVTMPFS=y ··· 345 354 CONFIG_NET_DSA_MV88E6131=y 346 355 CONFIG_NET_DSA_MV88E6123_61_65=y 347 356 # CONFIG_NET_VENDOR_3COM is not set 348 - # CONFIG_NET_VENDOR_ADAPTEC is not set 349 - # CONFIG_NET_VENDOR_ALTEON is not set 350 - # CONFIG_NET_VENDOR_AMD is not set 351 - # CONFIG_NET_VENDOR_ATHEROS is not set 352 - # CONFIG_NET_VENDOR_BROADCOM is not set 353 - # CONFIG_NET_VENDOR_BROCADE is not set 354 - # CONFIG_NET_VENDOR_CHELSIO is not set 355 - # CONFIG_NET_VENDOR_CISCO is not set 356 - # CONFIG_NET_VENDOR_DEC is not set 357 - # CONFIG_NET_VENDOR_DLINK is not set 358 - # CONFIG_NET_VENDOR_EMULEX is not set 359 - # CONFIG_NET_VENDOR_EXAR is not set 360 - # CONFIG_NET_VENDOR_HP is not set 361 - # CONFIG_NET_VENDOR_INTEL is not set 362 - # CONFIG_NET_VENDOR_MARVELL is not set 363 - # CONFIG_NET_VENDOR_MELLANOX is not set 364 - # CONFIG_NET_VENDOR_MICREL is not set 365 - # CONFIG_NET_VENDOR_MYRI is not set 366 - # CONFIG_NET_VENDOR_NATSEMI is not set 367 - # CONFIG_NET_VENDOR_NVIDIA is not set 368 - # CONFIG_NET_VENDOR_OKI is not set 369 - # CONFIG_NET_PACKET_ENGINE is not set 370 - # CONFIG_NET_VENDOR_QLOGIC is not set 371 - # CONFIG_NET_VENDOR_REALTEK is not set 372 - # CONFIG_NET_VENDOR_RDC is not set 373 - # CONFIG_NET_VENDOR_SEEQ is not set 374 - # CONFIG_NET_VENDOR_SILAN is not set 375 - # CONFIG_NET_VENDOR_SIS is not set 376 - # CONFIG_NET_VENDOR_SMSC is not set 377 - # CONFIG_NET_VENDOR_STMICRO is not set 378 - # CONFIG_NET_VENDOR_SUN is not set 379 - # CONFIG_NET_VENDOR_TEHUTI is not set 380 - # CONFIG_NET_VENDOR_TI is not set 381 - # CONFIG_NET_VENDOR_VIA is not set 357 + CONFIG_E1000E=y 382 358 # CONFIG_WLAN is not set 383 359 # CONFIG_INPUT_MOUSEDEV is not set 384 360 # CONFIG_INPUT_KEYBOARD is not set ··· 361 403 CONFIG_WATCHDOG=y 362 404 CONFIG_WATCHDOG_NOWAYOUT=y 363 405 # CONFIG_VGA_ARB is not set 364 - # CONFIG_HID_SUPPORT is not set 365 406 # CONFIG_USB_SUPPORT is not set 366 407 CONFIG_EDAC=y 367 408 CONFIG_EDAC_MM_EDAC=y ··· 405 448 CONFIG_TMPFS=y 406 449 CONFIG_TMPFS_POSIX_ACL=y 407 450 CONFIG_HUGETLBFS=y 451 + CONFIG_CONFIGFS_FS=m 408 452 CONFIG_ECRYPT_FS=m 409 453 CONFIG_CRAMFS=m 410 454 CONFIG_SQUASHFS=m 411 455 CONFIG_NFS_FS=m 412 - CONFIG_NFS_V3=y 413 456 CONFIG_NFS_V3_ACL=y 414 - CONFIG_NFS_V4=y 457 + CONFIG_NFS_V4=m 415 458 CONFIG_NFS_V4_1=y 416 459 CONFIG_NFS_FSCACHE=y 417 460 CONFIG_NFSD=m ··· 465 508 CONFIG_NLS_KOI8_R=m 466 509 CONFIG_NLS_KOI8_U=m 467 510 CONFIG_NLS_UTF8=m 511 + CONFIG_DLM=m 468 512 CONFIG_DLM_DEBUG=y 513 + CONFIG_DYNAMIC_DEBUG=y 514 + CONFIG_DEBUG_INFO=y 515 + CONFIG_DEBUG_INFO_REDUCED=y 469 516 # CONFIG_ENABLE_WARN_DEPRECATED is not set 470 517 CONFIG_FRAME_WARN=2048 471 - CONFIG_MAGIC_SYSRQ=y 472 518 CONFIG_STRIP_ASM_SYMS=y 473 519 CONFIG_DEBUG_FS=y 474 520 CONFIG_HEADERS_CHECK=y 521 + # CONFIG_FRAME_POINTER is not set 522 + CONFIG_DEBUG_FORCE_WEAK_PER_CPU=y 523 + CONFIG_MAGIC_SYSRQ=y 524 + CONFIG_DEBUG_VM=y 525 + CONFIG_DEBUG_MEMORY_INIT=y 526 + CONFIG_DEBUG_STACKOVERFLOW=y 475 527 CONFIG_LOCKUP_DETECTOR=y 476 528 CONFIG_SCHEDSTATS=y 477 529 CONFIG_TIMER_STATS=y 478 - CONFIG_DEBUG_INFO=y 479 - CONFIG_DEBUG_INFO_REDUCED=y 480 - CONFIG_DEBUG_VM=y 481 - CONFIG_DEBUG_MEMORY_INIT=y 482 530 CONFIG_DEBUG_LIST=y 483 531 CONFIG_DEBUG_CREDENTIALS=y 484 - CONFIG_DEBUG_FORCE_WEAK_PER_CPU=y 485 - CONFIG_DYNAMIC_DEBUG=y 532 + CONFIG_RCU_CPU_STALL_TIMEOUT=60 486 533 CONFIG_ASYNC_RAID6_TEST=m 487 - CONFIG_DEBUG_STACKOVERFLOW=y 488 534 CONFIG_KEYS_DEBUG_PROC_KEYS=y 489 535 CONFIG_SECURITY=y 490 536 CONFIG_SECURITYFS=y ··· 496 536 CONFIG_SECURITY_SELINUX=y 497 537 CONFIG_SECURITY_SELINUX_BOOTPARAM=y 498 538 CONFIG_SECURITY_SELINUX_DISABLE=y 499 - CONFIG_CRYPTO_NULL=m 500 539 CONFIG_CRYPTO_PCRYPT=m 501 540 CONFIG_CRYPTO_CRYPTD=m 502 541 CONFIG_CRYPTO_TEST=m ··· 508 549 CONFIG_CRYPTO_HMAC=y 509 550 CONFIG_CRYPTO_XCBC=m 510 551 CONFIG_CRYPTO_VMAC=m 511 - CONFIG_CRYPTO_CRC32C=y 512 552 CONFIG_CRYPTO_MICHAEL_MIC=m 513 553 CONFIG_CRYPTO_RMD128=m 514 554 CONFIG_CRYPTO_RMD160=m 515 555 CONFIG_CRYPTO_RMD256=m 516 556 CONFIG_CRYPTO_RMD320=m 517 557 CONFIG_CRYPTO_SHA1=y 518 - CONFIG_CRYPTO_SHA256=m 519 558 CONFIG_CRYPTO_SHA512=m 520 559 CONFIG_CRYPTO_TGR192=m 521 560 CONFIG_CRYPTO_WP512=m
+5
arch/tile/gxio/Kconfig
··· 26 26 config TILE_GXIO_USB_HOST 27 27 bool 28 28 select TILE_GXIO 29 + 30 + # Support direct access to the TILE-Gx UART hardware from kernel space. 31 + config TILE_GXIO_UART 32 + bool 33 + select TILE_GXIO
+1
arch/tile/gxio/Makefile
··· 6 6 obj-$(CONFIG_TILE_GXIO_DMA) += dma_queue.o 7 7 obj-$(CONFIG_TILE_GXIO_MPIPE) += mpipe.o iorpc_mpipe.o iorpc_mpipe_info.o 8 8 obj-$(CONFIG_TILE_GXIO_TRIO) += trio.o iorpc_trio.o 9 + obj-$(CONFIG_TILE_GXIO_UART) += uart.o iorpc_uart.o 9 10 obj-$(CONFIG_TILE_GXIO_USB_HOST) += usb_host.o iorpc_usb_host.o
+23
arch/tile/gxio/iorpc_trio.c
··· 61 61 62 62 EXPORT_SYMBOL(gxio_trio_alloc_memory_maps); 63 63 64 + struct alloc_scatter_queues_param { 65 + unsigned int count; 66 + unsigned int first; 67 + unsigned int flags; 68 + }; 69 + 70 + int 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 + 86 + EXPORT_SYMBOL(gxio_trio_alloc_scatter_queues); 64 87 65 88 struct alloc_pio_regions_param { 66 89 unsigned int count;
+77
arch/tile/gxio/iorpc_uart.c
··· 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 + 18 + struct cfg_interrupt_param { 19 + union iorpc_interrupt interrupt; 20 + }; 21 + 22 + int 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 + 37 + EXPORT_SYMBOL(gxio_uart_cfg_interrupt); 38 + 39 + struct get_mmio_base_param { 40 + HV_PTE base; 41 + }; 42 + 43 + int 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 + 57 + EXPORT_SYMBOL(gxio_uart_get_mmio_base); 58 + 59 + struct check_mmio_offset_param { 60 + unsigned long offset; 61 + unsigned long size; 62 + }; 63 + 64 + int 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 + 77 + EXPORT_SYMBOL(gxio_uart_check_mmio_offset);
+87
arch/tile/gxio/uart.c
··· 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 + 28 + int 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 + 57 + EXPORT_SYMBOL_GPL(gxio_uart_init); 58 + 59 + int 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 + 70 + EXPORT_SYMBOL_GPL(gxio_uart_destroy); 71 + 72 + /* UART register write wrapper. */ 73 + void 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 + 79 + EXPORT_SYMBOL_GPL(gxio_uart_write); 80 + 81 + /* UART register read wrapper. */ 82 + uint64_t gxio_uart_read(gxio_uart_context_t *context, uint64_t offset) 83 + { 84 + return __gxio_mmio_read(context->mmio_base + offset); 85 + } 86 + 87 + EXPORT_SYMBOL_GPL(gxio_uart_read);
+39
arch/tile/include/arch/trio.h
··· 23 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__ 35 + typedef 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 65 * Tile PIO Region Configuration - CFG Address Format. 27 66 * This register describes the address format for PIO accesses when the 28 67 * associated region is setup with TYPE=CFG.
+300
arch/tile/include/arch/uart.h
··· 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__ 28 + typedef 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__ 54 + typedef 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__ 99 + typedef 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__ 142 + typedef 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__ 209 + typedef 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__ 269 + typedef 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__) */
+120
arch/tile/include/arch/uart_def.h
··· 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__) */
+2 -1
arch/tile/include/asm/Kbuild
··· 11 11 generic-y += exec.h 12 12 generic-y += fb.h 13 13 generic-y += fcntl.h 14 + generic-y += hw_irq.h 14 15 generic-y += ioctl.h 15 16 generic-y += ioctls.h 16 17 generic-y += ipcbuf.h 17 18 generic-y += irq_regs.h 18 - generic-y += kdebug.h 19 19 generic-y += local.h 20 + generic-y += local64.h 20 21 generic-y += msgbuf.h 21 22 generic-y += mutex.h 22 23 generic-y += param.h
+52
arch/tile/include/asm/atomic.h
··· 114 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 + */ 123 + static 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 + */ 137 + static inline int atomic_cmpxchg(atomic_t *v, int o, int n) 138 + { 139 + return cmpxchg(&v->counter, o, n); 140 + } 141 + 142 + /** 117 143 * atomic_add_negative - add and test if negative 118 144 * @v: pointer of type atomic_t 119 145 * @i: integer value to add ··· 158 132 #endif 159 133 160 134 #ifndef __ASSEMBLY__ 135 + 136 + /** 137 + * atomic64_xchg - atomically exchange contents of memory with a new value 138 + * @v: pointer of type atomic64_t 139 + * @i: integer value to store in memory 140 + * 141 + * Atomically sets @v to @i and returns old @v 142 + */ 143 + static inline u64 atomic64_xchg(atomic64_t *v, u64 n) 144 + { 145 + return xchg64(&v->counter, n); 146 + } 147 + 148 + /** 149 + * atomic64_cmpxchg - atomically exchange contents of memory if it matches 150 + * @v: pointer of type atomic64_t 151 + * @o: old value that memory should have 152 + * @n: new value to write to memory if it matches 153 + * 154 + * Atomically checks if @v holds @o and replaces it with @n if so. 155 + * Returns the old value at @v. 156 + */ 157 + static inline u64 atomic64_cmpxchg(atomic64_t *v, u64 o, u64 n) 158 + { 159 + return cmpxchg64(&v->counter, o, n); 160 + } 161 161 162 162 static inline long long atomic64_dec_if_positive(atomic64_t *v) 163 163 {
+9 -93
arch/tile/include/asm/atomic_32.h
··· 22 22 23 23 #ifndef __ASSEMBLY__ 24 24 25 - /* Tile-specific routines to support <linux/atomic.h>. */ 26 - int _atomic_xchg(atomic_t *v, int n); 27 - int _atomic_xchg_add(atomic_t *v, int i); 28 - int _atomic_xchg_add_unless(atomic_t *v, int a, int u); 29 - int _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 - */ 38 - static 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 - */ 53 - static 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 26 * atomic_add - add integer to atomic variable 61 27 * @i: integer value to add ··· 31 65 */ 32 66 static inline void atomic_add(int i, atomic_t *v) 33 67 { 34 - _atomic_xchg_add(v, i); 68 + _atomic_xchg_add(&v->counter, i); 35 69 } 36 70 37 71 /** ··· 44 78 static inline int atomic_add_return(int i, atomic_t *v) 45 79 { 46 80 smp_mb(); /* barrier for proper semantics */ 47 - return _atomic_xchg_add(v, i) + i; 81 + return _atomic_xchg_add(&v->counter, i) + i; 48 82 } 49 83 50 84 /** ··· 59 93 static inline int __atomic_add_unless(atomic_t *v, int a, int u) 60 94 { 61 95 smp_mb(); /* barrier for proper semantics */ 62 - return _atomic_xchg_add_unless(v, a, u); 96 + return _atomic_xchg_add_unless(&v->counter, a, u); 63 97 } 64 98 65 99 /** ··· 74 108 */ 75 109 static inline void atomic_set(atomic_t *v, int n) 76 110 { 77 - _atomic_xchg(v, n); 111 + _atomic_xchg(&v->counter, n); 78 112 } 79 113 80 114 /* A 64bit atomic type */ ··· 84 118 } atomic64_t; 85 119 86 120 #define ATOMIC64_INIT(val) { (val) } 87 - 88 - u64 _atomic64_xchg(atomic64_t *v, u64 n); 89 - u64 _atomic64_xchg_add(atomic64_t *v, u64 i); 90 - u64 _atomic64_xchg_add_unless(atomic64_t *v, u64 a, u64 u); 91 - u64 _atomic64_cmpxchg(atomic64_t *v, u64 o, u64 n); 92 121 93 122 /** 94 123 * atomic64_read - read atomic variable ··· 98 137 * Casting away const is safe since the atomic support routines 99 138 * do not write to memory if the value has not been modified. 100 139 */ 101 - return _atomic64_xchg_add((atomic64_t *)v, 0); 102 - } 103 - 104 - /** 105 - * atomic64_xchg - atomically exchange contents of memory with a new value 106 - * @v: pointer of type atomic64_t 107 - * @i: integer value to store in memory 108 - * 109 - * Atomically sets @v to @i and returns old @v 110 - */ 111 - static inline u64 atomic64_xchg(atomic64_t *v, u64 n) 112 - { 113 - smp_mb(); /* barrier for proper semantics */ 114 - return _atomic64_xchg(v, n); 115 - } 116 - 117 - /** 118 - * atomic64_cmpxchg - atomically exchange contents of memory if it matches 119 - * @v: pointer of type atomic64_t 120 - * @o: old value that memory should have 121 - * @n: new value to write to memory if it matches 122 - * 123 - * Atomically checks if @v holds @o and replaces it with @n if so. 124 - * Returns the old value at @v. 125 - */ 126 - static inline u64 atomic64_cmpxchg(atomic64_t *v, u64 o, u64 n) 127 - { 128 - smp_mb(); /* barrier for proper semantics */ 129 - return _atomic64_cmpxchg(v, o, n); 140 + return _atomic64_xchg_add((u64 *)&v->counter, 0); 130 141 } 131 142 132 143 /** ··· 110 177 */ 111 178 static inline void atomic64_add(u64 i, atomic64_t *v) 112 179 { 113 - _atomic64_xchg_add(v, i); 180 + _atomic64_xchg_add(&v->counter, i); 114 181 } 115 182 116 183 /** ··· 123 190 static inline u64 atomic64_add_return(u64 i, atomic64_t *v) 124 191 { 125 192 smp_mb(); /* barrier for proper semantics */ 126 - return _atomic64_xchg_add(v, i) + i; 193 + return _atomic64_xchg_add(&v->counter, i) + i; 127 194 } 128 195 129 196 /** ··· 138 205 static inline u64 atomic64_add_unless(atomic64_t *v, u64 a, u64 u) 139 206 { 140 207 smp_mb(); /* barrier for proper semantics */ 141 - return _atomic64_xchg_add_unless(v, a, u) != u; 208 + return _atomic64_xchg_add_unless(&v->counter, a, u) != u; 142 209 } 143 210 144 211 /** ··· 153 220 */ 154 221 static inline void atomic64_set(atomic64_t *v, u64 n) 155 222 { 156 - _atomic64_xchg(v, n); 223 + _atomic64_xchg(&v->counter, n); 157 224 } 158 225 159 226 #define atomic64_add_negative(a, v) (atomic64_add_return((a), (v)) < 0) ··· 185 252 * Internal definitions only beyond this point. 186 253 */ 187 254 188 - #define ATOMIC_LOCKS_FOUND_VIA_TABLE() \ 189 - (!CHIP_HAS_CBOX_HOME_MAP() && defined(CONFIG_SMP)) 190 - 191 - #if ATOMIC_LOCKS_FOUND_VIA_TABLE() 192 - 193 - /* Number of entries in atomic_lock_ptr[]. */ 194 - #define ATOMIC_HASH_L1_SHIFT 6 195 - #define ATOMIC_HASH_L1_SIZE (1 << ATOMIC_HASH_L1_SHIFT) 196 - 197 - /* Number of locks in each struct pointed to by atomic_lock_ptr[]. */ 198 - #define ATOMIC_HASH_L2_SHIFT (CHIP_L2_LOG_LINE_SIZE() - 2) 199 - #define ATOMIC_HASH_L2_SIZE (1 << ATOMIC_HASH_L2_SHIFT) 200 - 201 - #else /* ATOMIC_LOCKS_FOUND_VIA_TABLE() */ 202 - 203 255 /* 204 256 * Number of atomic locks in atomic_locks[]. Must be a power of two. 205 257 * There is no reason for more than PAGE_SIZE / 8 entries, since that ··· 198 280 #ifndef __ASSEMBLY__ 199 281 extern int atomic_locks[]; 200 282 #endif 201 - 202 - #endif /* ATOMIC_LOCKS_FOUND_VIA_TABLE() */ 203 283 204 284 /* 205 285 * All the code that may fault while holding an atomic lock must
+2 -40
arch/tile/include/asm/atomic_64.h
··· 32 32 * on any routine which updates memory and returns a value. 33 33 */ 34 34 35 - static 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 - 45 - static 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 - 54 35 static inline void atomic_add(int i, atomic_t *v) 55 36 { 56 37 __insn_fetchadd4((void *)&v->counter, i); ··· 53 72 if (oldval == u) 54 73 break; 55 74 guess = oldval; 56 - oldval = atomic_cmpxchg(v, guess, guess + a); 75 + oldval = cmpxchg(&v->counter, guess, guess + a); 57 76 } while (guess != oldval); 58 77 return oldval; 59 78 } ··· 64 83 65 84 #define atomic64_read(v) ((v)->counter) 66 85 #define atomic64_set(v, i) ((v)->counter = (i)) 67 - 68 - static inline long atomic64_cmpxchg(atomic64_t *v, long o, long n) 69 - { 70 - long val; 71 - smp_mb(); /* barrier for proper semantics */ 72 - __insn_mtspr(SPR_CMPEXCH_VALUE, o); 73 - val = __insn_cmpexch((void *)&v->counter, n); 74 - smp_mb(); /* barrier for proper semantics */ 75 - return val; 76 - } 77 - 78 - static inline long atomic64_xchg(atomic64_t *v, long n) 79 - { 80 - long val; 81 - smp_mb(); /* barrier for proper semantics */ 82 - val = __insn_exch((void *)&v->counter, n); 83 - smp_mb(); /* barrier for proper semantics */ 84 - return val; 85 - } 86 86 87 87 static inline void atomic64_add(long i, atomic64_t *v) 88 88 { ··· 86 124 if (oldval == u) 87 125 break; 88 126 guess = oldval; 89 - oldval = atomic64_cmpxchg(v, guess, guess + a); 127 + oldval = cmpxchg(&v->counter, guess, guess + a); 90 128 } while (guess != oldval); 91 129 return oldval != u; 92 130 }
-4
arch/tile/include/asm/barrier.h
··· 77 77 78 78 #define __sync() __insn_mf() 79 79 80 - #if !CHIP_HAS_MF_WAITS_FOR_VICTIMS() 81 80 #include <hv/syscall_public.h> 82 81 /* 83 82 * Issue an uncacheable load to each memory controller, then ··· 95 96 "r20", "r21", "r22", "r23", "r24", 96 97 "r25", "r26", "r27", "r28", "r29"); 97 98 } 98 - #endif 99 99 100 100 /* Fence to guarantee visibility of stores to incoherent memory. */ 101 101 static inline void ··· 102 104 { 103 105 __insn_mf(); 104 106 105 - #if !CHIP_HAS_MF_WAITS_FOR_VICTIMS() 106 107 { 107 108 #if CHIP_HAS_TILE_WRITE_PENDING() 108 109 const unsigned long WRITE_TIMEOUT_CYCLES = 400; ··· 113 116 #endif /* CHIP_HAS_TILE_WRITE_PENDING() */ 114 117 (void) __mb_incoherent(); 115 118 } 116 - #endif /* CHIP_HAS_MF_WAITS_FOR_VICTIMS() */ 117 119 } 118 120 119 121 #define fast_wmb() __sync()
+3 -38
arch/tile/include/asm/bitops.h
··· 29 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 - */ 37 - static inline unsigned long __ffs(unsigned long word) 38 - { 39 - return __builtin_ctzl(word); 40 - } 41 - 42 - /** 43 32 * ffz - find first zero bit in word 44 33 * @word: The word to search 45 34 * ··· 37 48 static inline unsigned long ffz(unsigned long word) 38 49 { 39 50 return __builtin_ctzl(~word); 40 - } 41 - 42 - /** 43 - * __fls - find last set bit in word 44 - * @word: The word to search 45 - * 46 - * Undefined if no set bit exists, so code should check against 0 first. 47 - */ 48 - static inline unsigned long __fls(unsigned long word) 49 - { 50 - return (sizeof(word) * 8) - 1 - __builtin_clzl(word); 51 - } 52 - 53 - /** 54 - * ffs - find first set bit in word 55 - * @x: the word to search 56 - * 57 - * This is defined the same way as the libc and compiler builtin ffs 58 - * routines, therefore differs in spirit from the other bitops. 59 - * 60 - * ffs(value) returns 0 if value is 0 or the position of the first 61 - * set bit if value is nonzero. The first (least significant) bit 62 - * is at position 1. 63 - */ 64 - static inline int ffs(int x) 65 - { 66 - return __builtin_ffs(x); 67 51 } 68 52 69 53 static inline int fls64(__u64 w) ··· 80 118 return __builtin_popcountll(w); 81 119 } 82 120 121 + #include <asm-generic/bitops/builtin-__ffs.h> 122 + #include <asm-generic/bitops/builtin-__fls.h> 123 + #include <asm-generic/bitops/builtin-ffs.h> 83 124 #include <asm-generic/bitops/const_hweight.h> 84 125 #include <asm-generic/bitops/lock.h> 85 126 #include <asm-generic/bitops/find.h>
+1 -1
arch/tile/include/asm/bitops_32.h
··· 16 16 #define _ASM_TILE_BITOPS_32_H 17 17 18 18 #include <linux/compiler.h> 19 - #include <linux/atomic.h> 19 + #include <asm/barrier.h> 20 20 21 21 /* Tile-specific routines to support <asm/bitops.h>. */ 22 22 unsigned long _atomic_or(volatile unsigned long *p, unsigned long mask);
+3 -5
arch/tile/include/asm/bitops_64.h
··· 16 16 #define _ASM_TILE_BITOPS_64_H 17 17 18 18 #include <linux/compiler.h> 19 - #include <linux/atomic.h> 19 + #include <asm/cmpxchg.h> 20 20 21 21 /* See <asm/bitops.h> for API comments. */ 22 22 ··· 44 44 oldval = *addr; 45 45 do { 46 46 guess = oldval; 47 - oldval = atomic64_cmpxchg((atomic64_t *)addr, 48 - guess, guess ^ mask); 47 + oldval = cmpxchg(addr, guess, guess ^ mask); 49 48 } while (guess != oldval); 50 49 } 51 50 ··· 89 90 oldval = *addr; 90 91 do { 91 92 guess = oldval; 92 - oldval = atomic64_cmpxchg((atomic64_t *)addr, 93 - guess, guess ^ mask); 93 + oldval = cmpxchg(addr, guess, guess ^ mask); 94 94 } while (guess != oldval); 95 95 return (oldval & mask) != 0; 96 96 }
+10 -3
arch/tile/include/asm/cache.h
··· 49 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 53 - * initialization, then bumped to read/only incoherent for performance. 52 + * Originally we used small TLB pages for kernel data and grouped some 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 64 #endif /* _ASM_TILE_CACHE_H */
+20 -24
arch/tile/include/asm/cacheflush.h
··· 75 75 #define copy_from_user_page(vma, page, vaddr, dst, src, len) \ 76 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 - */ 85 - static 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 78 /* Flush a VA range; pads to L2 cacheline boundaries. */ 96 79 static inline void __flush_buffer(void *buffer, size_t size) 97 80 { ··· 98 115 } 99 116 100 117 101 - /* Invalidate a VA range and wait for it to be complete. */ 102 - static inline void inv_buffer(void *buffer, size_t size) 103 - { 104 - __inv_buffer(buffer, size); 105 - mb(); 106 - } 107 - 108 118 /* 109 119 * Flush a locally-homecached VA range and wait for the evicted 110 120 * cachelines to hit memory. ··· 117 141 __finv_buffer(buffer, size); 118 142 mb_incoherent(); 119 143 } 144 + 145 + #ifdef __tilepro__ 146 + /* Invalidate a VA range; pads to L2 cacheline boundaries. */ 147 + static inline void __inv_buffer(void *buffer, size_t size) 148 + { 149 + char *next = (char *)((long)buffer & -L2_CACHE_BYTES); 150 + char *finish = (char *)L2_CACHE_ALIGN((long)buffer + size); 151 + while (next < finish) { 152 + __insn_inv(next); 153 + next += CHIP_INV_STRIDE(); 154 + } 155 + } 156 + 157 + /* Invalidate a VA range and wait for it to be complete. */ 158 + static inline void inv_buffer(void *buffer, size_t size) 159 + { 160 + __inv_buffer(buffer, size); 161 + mb(); 162 + } 163 + #endif 120 164 121 165 /* 122 166 * Flush and invalidate a VA range that is homed remotely, waiting
+74 -19
arch/tile/include/asm/cmpxchg.h
··· 20 20 21 21 #ifndef __ASSEMBLY__ 22 22 23 - /* Nonexistent functions intended to cause link errors. */ 24 - extern unsigned long __xchg_called_with_bad_pointer(void); 25 - extern unsigned long __cmpxchg_called_with_bad_pointer(void); 23 + #include <asm/barrier.h> 26 24 27 - #define xchg(ptr, x) \ 25 + /* Nonexistent functions intended to cause compile errors. */ 26 + extern void __xchg_called_with_bad_pointer(void) 27 + __compiletime_error("Bad argument size for xchg"); 28 + extern 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(). */ 34 + int _atomic_xchg(int *ptr, int n); 35 + int _atomic_xchg_add(int *v, int i); 36 + int _atomic_xchg_add_unless(int *v, int a, int u); 37 + int _atomic_cmpxchg(int *ptr, int o, int n); 38 + u64 _atomic64_xchg(u64 *v, u64 n); 39 + u64 _atomic64_xchg_add(u64 *v, u64 i); 40 + u64 _atomic64_xchg_add_unless(u64 *v, u64 a, u64 u); 41 + u64 _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 79 typeof(*(ptr)) __x; \ 80 + smp_mb(); \ 30 81 switch (sizeof(*(ptr))) { \ 31 82 case 4: \ 32 - __x = (typeof(__x))(typeof(__x-__x))atomic_xchg( \ 33 - (atomic_t *)(ptr), \ 34 - (u32)(typeof((x)-(x)))(x)); \ 83 + __x = (typeof(__x))(unsigned long) \ 84 + __insn_exch4((ptr), (u32)(unsigned long)(n)); \ 35 85 break; \ 36 86 case 8: \ 37 - __x = (typeof(__x))(typeof(__x-__x))atomic64_xchg( \ 38 - (atomic64_t *)(ptr), \ 39 - (u64)(typeof((x)-(x)))(x)); \ 87 + __x = (typeof(__x)) \ 88 + __insn_exch((ptr), (unsigned long)(n)); \ 40 89 break; \ 41 90 default: \ 42 91 __xchg_called_with_bad_pointer(); \ 92 + break; \ 43 93 } \ 94 + smp_mb(); \ 44 95 __x; \ 45 96 }) 46 97 47 98 #define cmpxchg(ptr, o, n) \ 48 99 ({ \ 49 100 typeof(*(ptr)) __x; \ 101 + __insn_mtspr(SPR_CMPEXCH_VALUE, (unsigned long)(o)); \ 102 + smp_mb(); \ 50 103 switch (sizeof(*(ptr))) { \ 51 104 case 4: \ 52 - __x = (typeof(__x))(typeof(__x-__x))atomic_cmpxchg( \ 53 - (atomic_t *)(ptr), \ 54 - (u32)(typeof((o)-(o)))(o), \ 55 - (u32)(typeof((n)-(n)))(n)); \ 105 + __x = (typeof(__x))(unsigned long) \ 106 + __insn_cmpexch4((ptr), (u32)(unsigned long)(n)); \ 56 107 break; \ 57 108 case 8: \ 58 - __x = (typeof(__x))(typeof(__x-__x))atomic64_cmpxchg( \ 59 - (atomic64_t *)(ptr), \ 60 - (u64)(typeof((o)-(o)))(o), \ 61 - (u64)(typeof((n)-(n)))(n)); \ 109 + __x = (typeof(__x))__insn_cmpexch((ptr), (u64)(n)); \ 62 110 break; \ 63 111 default: \ 64 112 __cmpxchg_called_with_bad_pointer(); \ 113 + break; \ 65 114 } \ 115 + smp_mb(); \ 66 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 126 #endif /* __ASSEMBLY__ */ 72 127
+4 -1
arch/tile/include/asm/device.h
··· 23 23 /* Offset of the DMA address from the PA. */ 24 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 30 dma_addr_t max_direct_dma_addr; 28 31 }; 29 32
+20 -7
arch/tile/include/asm/dma-mapping.h
··· 20 20 #include <linux/cache.h> 21 21 #include <linux/io.h> 22 22 23 + #ifdef __tilegx__ 24 + #define ARCH_HAS_DMA_GET_REQUIRED_MASK 25 + #endif 26 + 23 27 extern struct dma_map_ops *tile_dma_map_ops; 24 28 extern struct dma_map_ops *gx_pci_dma_map_ops; 25 29 extern struct dma_map_ops *gx_legacy_pci_dma_map_ops; 30 + extern struct dma_map_ops *gx_hybrid_pci_dma_map_ops; 26 31 27 32 static inline struct dma_map_ops *get_dma_ops(struct device *dev) 28 33 { ··· 49 44 50 45 static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr) 51 46 { 52 - return paddr + get_dma_offset(dev); 47 + return paddr; 53 48 } 54 49 55 50 static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr) 56 51 { 57 - return daddr - get_dma_offset(dev); 52 + return daddr; 58 53 } 59 54 60 55 static inline void dma_mark_clean(void *addr, size_t size) {} ··· 92 87 { 93 88 struct dma_map_ops *dma_ops = get_dma_ops(dev); 94 89 95 - /* Handle legacy PCI devices with limited memory addressability. */ 96 - if ((dma_ops == gx_pci_dma_map_ops) && (mask <= DMA_BIT_MASK(32))) { 97 - set_dma_ops(dev, gx_legacy_pci_dma_map_ops); 98 - set_dma_offset(dev, 0); 99 - if (mask > dev->archdata.max_direct_dma_addr) 90 + /* 91 + * For PCI devices with 64-bit DMA addressing capability, promote 92 + * the dma_ops to hybrid, with the consistent memory DMA space limited 93 + * to 32-bit. For 32-bit capable devices, limit the streaming DMA 94 + * address range to max_direct_dma_addr. 95 + */ 96 + if (dma_ops == gx_pci_dma_map_ops || 97 + dma_ops == gx_hybrid_pci_dma_map_ops || 98 + dma_ops == gx_legacy_pci_dma_map_ops) { 99 + if (mask == DMA_BIT_MASK(64) && 100 + dma_ops == gx_legacy_pci_dma_map_ops) 101 + set_dma_ops(dev, gx_hybrid_pci_dma_map_ops); 102 + else if (mask > dev->archdata.max_direct_dma_addr) 100 103 mask = dev->archdata.max_direct_dma_addr; 101 104 } 102 105
+9 -1
arch/tile/include/asm/elf.h
··· 30 30 #define ELF_NGREG (sizeof(struct pt_regs) / sizeof(elf_greg_t)) 31 31 typedef elf_greg_t elf_gregset_t[ELF_NGREG]; 32 32 33 - #define EM_TILE64 187 34 33 #define EM_TILEPRO 188 35 34 #define EM_TILEGX 191 36 35 ··· 131 132 struct linux_binprm; 132 133 extern int arch_setup_additional_pages(struct linux_binprm *bprm, 133 134 int executable_stack); 135 + #define ARCH_DLINFO \ 136 + do { \ 137 + NEW_AUX_ENT(AT_SYSINFO_EHDR, VDSO_BASE); \ 138 + } while (0) 139 + 140 + struct mm_struct; 141 + extern unsigned long arch_randomize_brk(struct mm_struct *mm); 142 + #define arch_randomize_brk arch_randomize_brk 143 + 134 144 #ifdef CONFIG_COMPAT 135 145 136 146 #define COMPAT_ELF_PLATFORM "tilegx-m32"
-8
arch/tile/include/asm/fixmap.h
··· 78 78 #endif 79 79 }; 80 80 81 - extern 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 81 #define __FIXADDR_SIZE (__end_of_permanent_fixed_addresses << PAGE_SHIFT) 90 82 #define __FIXADDR_BOOT_SIZE (__end_of_fixed_addresses << PAGE_SHIFT) 91 83 #define FIXADDR_START (FIXADDR_TOP + PAGE_SIZE - __FIXADDR_SIZE)
+21 -1
arch/tile/include/asm/ftrace.h
··· 15 15 #ifndef _ASM_TILE_FTRACE_H 16 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__ 24 + extern void __mcount(void); 25 + 26 + #ifdef CONFIG_DYNAMIC_FTRACE 27 + static inline unsigned long ftrace_call_adjust(unsigned long addr) 28 + { 29 + return addr; 30 + } 31 + 32 + struct dyn_arch_ftrace { 33 + }; 34 + #endif /* CONFIG_DYNAMIC_FTRACE */ 35 + 36 + #endif /* __ASSEMBLY__ */ 37 + 38 + #endif /* CONFIG_FUNCTION_TRACER */ 19 39 20 40 #endif /* _ASM_TILE_FTRACE_H */
+1
arch/tile/include/asm/futex.h
··· 43 43 ".pushsection .fixup,\"ax\"\n" \ 44 44 "0: { movei %0, %5; j 9f }\n" \ 45 45 ".section __ex_table,\"a\"\n" \ 46 + ".align 8\n" \ 46 47 ".quad 1b, 0b\n" \ 47 48 ".popsection\n" \ 48 49 "9:" \
+1 -10
arch/tile/include/asm/homecache.h
··· 33 33 34 34 /* 35 35 * Is this page immutable (unwritable) and thus able to be cached more 36 - * widely than would otherwise be possible? On tile64 this means we 37 - * mark the PTE to cache locally; on tilepro it means we have "nc" set. 36 + * widely than would otherwise be possible? This means we have "nc" set. 38 37 */ 39 38 #define PAGE_HOME_IMMUTABLE -2 40 39 ··· 43 44 */ 44 45 #define PAGE_HOME_INCOHERENT -3 45 46 46 - #if CHIP_HAS_CBOX_HOME_MAP() 47 47 /* Home for the page is distributed via hash-for-home. */ 48 48 #define PAGE_HOME_HASH -4 49 - #endif 50 - 51 - /* Homing is unknown or unspecified. Not valid for page_home(). */ 52 - #define PAGE_HOME_UNKNOWN -5 53 - 54 - /* Home on the current cpu. Not valid for page_home(). */ 55 - #define PAGE_HOME_HERE -6 56 49 57 50 /* Support wrapper to use instead of explicit hv_flush_remote(). */ 58 51 extern void flush_remote(unsigned long cache_pfn, unsigned long cache_length,
+14 -4
arch/tile/include/asm/hw_irq.h arch/tile/kernel/vdso/vdso32.S
··· 1 1 /* 2 - * Copyright 2010 Tilera Corporation. All Rights Reserved. 2 + * Copyright 2013 Tilera Corporation. All Rights Reserved. 3 3 * 4 4 * This program is free software; you can redistribute it and/or 5 5 * modify it under the terms of the GNU General Public License ··· 12 12 * more details. 13 13 */ 14 14 15 - #ifndef _ASM_TILE_HW_IRQ_H 16 - #define _ASM_TILE_HW_IRQ_H 15 + #include <linux/init.h> 16 + #include <linux/linkage.h> 17 + #include <asm/page.h> 17 18 18 - #endif /* _ASM_TILE_HW_IRQ_H */ 19 + __PAGE_ALIGNED_DATA 20 + 21 + .global vdso32_start, vdso32_end 22 + .align PAGE_SIZE 23 + vdso32_start: 24 + .incbin "arch/tile/kernel/vdso/vdso32.so" 25 + .align PAGE_SIZE 26 + vdso32_end: 27 + 28 + .previous
+120 -12
arch/tile/include/asm/io.h
··· 19 19 #include <linux/bug.h> 20 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 26 * Convert a physical pointer to a virtual kernel pointer for /dev/mem ··· 255 254 256 255 static inline void memset_io(volatile void *dst, int val, size_t len) 257 256 { 258 - int x; 257 + size_t x; 259 258 BUG_ON((unsigned long)dst & 0x3); 260 259 val = (val & 0xff) * 0x01010101; 261 260 for (x = 0; x < len; x += 4) ··· 265 264 static inline void memcpy_fromio(void *dst, const volatile void __iomem *src, 266 265 size_t len) 267 266 { 268 - int x; 267 + size_t x; 269 268 BUG_ON((unsigned long)src & 0x3); 270 269 for (x = 0; x < len; x += 4) 271 270 *(u32 *)(dst + x) = readl(src + x); ··· 274 273 static inline void memcpy_toio(volatile void __iomem *dst, const void *src, 275 274 size_t len) 276 275 { 277 - int x; 276 + size_t x; 278 277 BUG_ON((unsigned long)dst & 0x3); 279 278 for (x = 0; x < len; x += 4) 280 279 writel(*(u32 *)(src + x), dst + x); ··· 282 281 283 282 #endif 284 283 284 + #if CHIP_HAS_MMIO() && defined(CONFIG_TILE_PCI_IO) 285 + 286 + static inline u8 inb(unsigned long addr) 287 + { 288 + return readb((volatile void __iomem *) addr); 289 + } 290 + 291 + static inline u16 inw(unsigned long addr) 292 + { 293 + return readw((volatile void __iomem *) addr); 294 + } 295 + 296 + static inline u32 inl(unsigned long addr) 297 + { 298 + return readl((volatile void __iomem *) addr); 299 + } 300 + 301 + static inline void outb(u8 b, unsigned long addr) 302 + { 303 + writeb(b, (volatile void __iomem *) addr); 304 + } 305 + 306 + static inline void outw(u16 b, unsigned long addr) 307 + { 308 + writew(b, (volatile void __iomem *) addr); 309 + } 310 + 311 + static inline void outl(u32 b, unsigned long addr) 312 + { 313 + writel(b, (volatile void __iomem *) addr); 314 + } 315 + 316 + static inline void insb(unsigned long addr, void *buffer, int count) 317 + { 318 + if (count) { 319 + u8 *buf = buffer; 320 + do { 321 + u8 x = inb(addr); 322 + *buf++ = x; 323 + } while (--count); 324 + } 325 + } 326 + 327 + static inline void insw(unsigned long addr, void *buffer, int count) 328 + { 329 + if (count) { 330 + u16 *buf = buffer; 331 + do { 332 + u16 x = inw(addr); 333 + *buf++ = x; 334 + } while (--count); 335 + } 336 + } 337 + 338 + static inline void insl(unsigned long addr, void *buffer, int count) 339 + { 340 + if (count) { 341 + u32 *buf = buffer; 342 + do { 343 + u32 x = inl(addr); 344 + *buf++ = x; 345 + } while (--count); 346 + } 347 + } 348 + 349 + static inline void outsb(unsigned long addr, const void *buffer, int count) 350 + { 351 + if (count) { 352 + const u8 *buf = buffer; 353 + do { 354 + outb(*buf++, addr); 355 + } while (--count); 356 + } 357 + } 358 + 359 + static inline void outsw(unsigned long addr, const void *buffer, int count) 360 + { 361 + if (count) { 362 + const u16 *buf = buffer; 363 + do { 364 + outw(*buf++, addr); 365 + } while (--count); 366 + } 367 + } 368 + 369 + static inline void outsl(unsigned long addr, const void *buffer, int count) 370 + { 371 + if (count) { 372 + const u32 *buf = buffer; 373 + do { 374 + outl(*buf++, addr); 375 + } while (--count); 376 + } 377 + } 378 + 379 + extern void __iomem *ioport_map(unsigned long port, unsigned int len); 380 + extern void ioport_unmap(void __iomem *addr); 381 + 382 + #else 383 + 285 384 /* 286 - * The Tile architecture does not support IOPORT, even with PCI. 385 + * The TilePro architecture does not support IOPORT, even with PCI. 287 386 * Unfortunately we can't yet simply not declare these methods, 288 387 * since some generic code that compiles into the kernel, but 289 388 * we never run, uses them unconditionally. ··· 391 290 392 291 static inline long ioport_panic(void) 393 292 { 293 + #ifdef __tilegx__ 294 + panic("PCI IO space support is disabled. Configure the kernel with" 295 + " CONFIG_TILE_PCI_IO to enable it"); 296 + #else 394 297 panic("inb/outb and friends do not exist on tile"); 298 + #endif 395 299 return 0; 396 300 } 397 301 ··· 441 335 ioport_panic(); 442 336 } 443 337 444 - #define inb_p(addr) inb(addr) 445 - #define inw_p(addr) inw(addr) 446 - #define inl_p(addr) inl(addr) 447 - #define outb_p(x, addr) outb((x), (addr)) 448 - #define outw_p(x, addr) outw((x), (addr)) 449 - #define outl_p(x, addr) outl((x), (addr)) 450 - 451 338 static inline void insb(unsigned long addr, void *buffer, int count) 452 339 { 453 340 ioport_panic(); ··· 470 371 { 471 372 ioport_panic(); 472 373 } 374 + 375 + #endif /* CHIP_HAS_MMIO() && defined(CONFIG_TILE_PCI_IO) */ 376 + 377 + #define inb_p(addr) inb(addr) 378 + #define inw_p(addr) inw(addr) 379 + #define inl_p(addr) inl(addr) 380 + #define outb_p(x, addr) outb((x), (addr)) 381 + #define outw_p(x, addr) outw((x), (addr)) 382 + #define outl_p(x, addr) outl((x), (addr)) 473 383 474 384 #define ioread16be(addr) be16_to_cpu(ioread16(addr)) 475 385 #define ioread32be(addr) be32_to_cpu(ioread32(addr))
+18 -3
arch/tile/include/asm/irqflags.h
··· 124 124 DECLARE_PER_CPU(unsigned long long, interrupts_enabled_mask); 125 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. */ 129 + extern unsigned int debug_smp_processor_id(void); 130 + # define smp_processor_id() debug_smp_processor_id() 131 + #endif 132 + 127 133 /* Disable interrupts. */ 128 134 #define arch_local_irq_disable() \ 129 135 interrupt_mask_set_mask(LINUX_MASKABLE_INTERRUPTS) ··· 138 132 #define arch_local_irq_disable_all() \ 139 133 interrupt_mask_set_mask(-1ULL) 140 134 135 + /* 136 + * Read the set of maskable interrupts. 137 + * We avoid the preemption warning here via __this_cpu_ptr since even 138 + * if irqs are already enabled, it's harmless to read the wrong cpu's 139 + * enabled mask. 140 + */ 141 + #define arch_local_irqs_enabled() \ 142 + (*__this_cpu_ptr(&interrupts_enabled_mask)) 143 + 141 144 /* Re-enable all maskable interrupts. */ 142 145 #define arch_local_irq_enable() \ 143 - interrupt_mask_reset_mask(__get_cpu_var(interrupts_enabled_mask)) 146 + interrupt_mask_reset_mask(arch_local_irqs_enabled()) 144 147 145 148 /* Disable or enable interrupts based on flag argument. */ 146 149 #define arch_local_irq_restore(disabled) do { \ ··· 176 161 177 162 /* Prevent the given interrupt from being enabled next time we enable irqs. */ 178 163 #define arch_local_irq_mask(interrupt) \ 179 - (__get_cpu_var(interrupts_enabled_mask) &= ~(1ULL << (interrupt))) 164 + this_cpu_and(interrupts_enabled_mask, ~(1ULL << (interrupt))) 180 165 181 166 /* Prevent the given interrupt from being enabled immediately. */ 182 167 #define arch_local_irq_mask_now(interrupt) do { \ ··· 186 171 187 172 /* Allow the given interrupt to be enabled next time we enable irqs. */ 188 173 #define arch_local_irq_unmask(interrupt) \ 189 - (__get_cpu_var(interrupts_enabled_mask) |= (1ULL << (interrupt))) 174 + this_cpu_or(interrupts_enabled_mask, (1ULL << (interrupt))) 190 175 191 176 /* Allow the given interrupt to be enabled immediately, if !irqs_disabled. */ 192 177 #define arch_local_irq_unmask_now(interrupt) do { \
+28
arch/tile/include/asm/kdebug.h
··· 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 _ASM_TILE_KDEBUG_H 16 + #define _ASM_TILE_KDEBUG_H 17 + 18 + #include <linux/notifier.h> 19 + 20 + enum 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 */
+71
arch/tile/include/asm/kgdb.h
··· 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 + */ 55 + static tile_bundle_bits compiled_bpt = TILEGX_BPT_BUNDLE | DIE_COMPILED_BPT; 56 + 57 + enum 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 + */ 65 + static inline void arch_kgdb_breakpoint(void) 66 + { 67 + asm volatile (".quad %0\n\t" 68 + ::""(compiled_bpt)); 69 + } 70 + 71 + #endif /* __TILE_KGDB_H__ */
+79
arch/tile/include/asm/kprobes.h
··· 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 + 31 + typedef 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 + 38 + struct kprobe; 39 + 40 + /* Architecture specific copy of original instruction. */ 41 + struct arch_specific_insn { 42 + kprobe_opcode_t *insn; 43 + }; 44 + 45 + struct 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. */ 62 + struct 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 + 71 + extern tile_bundle_bits breakpoint2_insn; 72 + extern tile_bundle_bits breakpoint_insn; 73 + 74 + void arch_remove_kprobe(struct kprobe *); 75 + 76 + extern int kprobe_exceptions_notify(struct notifier_block *self, 77 + unsigned long val, void *data); 78 + 79 + #endif /* _ASM_TILE_KPROBES_H */
+1
arch/tile/include/asm/mmu.h
··· 22 22 * semaphore but atomically, but it is conservatively set. 23 23 */ 24 24 unsigned long priority_cached; 25 + unsigned long vdso_base; 25 26 }; 26 27 27 28 typedef struct mm_context mm_context_t;
+1 -1
arch/tile/include/asm/mmu_context.h
··· 45 45 46 46 static 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 49 __install_page_table(pgdir, asid, *ptep); 50 50 } 51 51
+1 -1
arch/tile/include/asm/mmzone.h
··· 42 42 43 43 #define kern_addr_valid(kaddr) virt_addr_valid((void *)kaddr) 44 44 45 - static inline int pfn_valid(int pfn) 45 + static inline int pfn_valid(unsigned long pfn) 46 46 { 47 47 int nid = pfn_to_nid(pfn); 48 48
+29 -32
arch/tile/include/asm/page.h
··· 39 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 48 * If the Kconfig doesn't specify, set a maximum zone order that 43 49 * is enough so that we can create huge pages from small pages given 44 50 * the respective sizes of the two page types. See <linux/mmzone.h>. ··· 148 142 #define HAVE_ARCH_HUGETLB_UNMAPPED_AREA 149 143 #endif 150 144 145 + /* Allow overriding how much VA or PA the kernel will use. */ 146 + #define MAX_PA_WIDTH CHIP_PA_WIDTH() 147 + #define MAX_VA_WIDTH CHIP_VA_WIDTH() 148 + 151 149 /* Each memory controller has PAs distinct in their high bits. */ 152 - #define NR_PA_HIGHBIT_SHIFT (CHIP_PA_WIDTH() - CHIP_LOG_NUM_MSHIMS()) 150 + #define NR_PA_HIGHBIT_SHIFT (MAX_PA_WIDTH - CHIP_LOG_NUM_MSHIMS()) 153 151 #define NR_PA_HIGHBIT_VALUES (1 << CHIP_LOG_NUM_MSHIMS()) 154 152 #define __pa_to_highbits(pa) ((phys_addr_t)(pa) >> NR_PA_HIGHBIT_SHIFT) 155 153 #define __pfn_to_highbits(pfn) ((pfn) >> (NR_PA_HIGHBIT_SHIFT - PAGE_SHIFT)) ··· 164 154 * We reserve the lower half of memory for user-space programs, and the 165 155 * upper half for system code. We re-map all of physical memory in the 166 156 * upper half, which takes a quarter of our VA space. Then we have 167 - * the vmalloc regions. The supervisor code lives at 0xfffffff700000000, 157 + * the vmalloc regions. The supervisor code lives at the highest address, 168 158 * with the hypervisor above that. 169 159 * 170 160 * Loadable kernel modules are placed immediately after the static ··· 176 166 * Similarly, for now we don't play any struct page mapping games. 177 167 */ 178 168 179 - #if CHIP_PA_WIDTH() + 2 > CHIP_VA_WIDTH() 169 + #if MAX_PA_WIDTH + 2 > MAX_VA_WIDTH 180 170 # error Too much PA to map with the VA available! 181 171 #endif 182 - #define HALF_VA_SPACE (_AC(1, UL) << (CHIP_VA_WIDTH() - 1)) 183 172 184 - #define MEM_LOW_END (HALF_VA_SPACE - 1) /* low half */ 185 - #define MEM_HIGH_START (-HALF_VA_SPACE) /* high half */ 186 - #define PAGE_OFFSET MEM_HIGH_START 187 - #define FIXADDR_BASE _AC(0xfffffff400000000, UL) /* 4 GB */ 188 - #define FIXADDR_TOP _AC(0xfffffff500000000, UL) /* 4 GB */ 173 + #define PAGE_OFFSET (-(_AC(1, UL) << (MAX_VA_WIDTH - 1))) 174 + #define KERNEL_HIGH_VADDR _AC(0xfffffff800000000, UL) /* high 32GB */ 175 + #define FIXADDR_BASE (KERNEL_HIGH_VADDR - 0x400000000) /* 4 GB */ 176 + #define FIXADDR_TOP (KERNEL_HIGH_VADDR - 0x300000000) /* 4 GB */ 189 177 #define _VMALLOC_START FIXADDR_TOP 190 - #define HUGE_VMAP_BASE _AC(0xfffffff600000000, UL) /* 4 GB */ 191 - #define MEM_SV_START _AC(0xfffffff700000000, UL) /* 256 MB */ 192 - #define MEM_SV_INTRPT MEM_SV_START 193 - #define MEM_MODULE_START _AC(0xfffffff710000000, UL) /* 256 MB */ 178 + #define HUGE_VMAP_BASE (KERNEL_HIGH_VADDR - 0x200000000) /* 4 GB */ 179 + #define MEM_SV_START (KERNEL_HIGH_VADDR - 0x100000000) /* 256 MB */ 180 + #define MEM_MODULE_START (MEM_SV_START + (256*1024*1024)) /* 256 MB */ 194 181 #define MEM_MODULE_END (MEM_MODULE_START + (256*1024*1024)) 195 - #define MEM_HV_START _AC(0xfffffff800000000, UL) /* 32 GB */ 196 - 197 - /* Highest DTLB address we will use */ 198 - #define KERNEL_HIGH_VADDR MEM_SV_START 199 182 200 183 #else /* !__tilegx__ */ 201 184 ··· 210 207 * values, and after that, we show "typical" values, since the actual 211 208 * addresses depend on kernel #defines. 212 209 * 213 - * MEM_HV_INTRPT 0xfe000000 214 - * MEM_SV_INTRPT (kernel code) 0xfd000000 210 + * MEM_HV_START 0xfe000000 211 + * MEM_SV_START (kernel code) 0xfd000000 215 212 * MEM_USER_INTRPT (user vector) 0xfc000000 216 - * FIX_KMAP_xxx 0xf8000000 (via NR_CPUS * KM_TYPE_NR) 217 - * PKMAP_BASE 0xf7000000 (via LAST_PKMAP) 218 - * HUGE_VMAP 0xf3000000 (via CONFIG_NR_HUGE_VMAPS) 219 - * VMALLOC_START 0xf0000000 (via __VMALLOC_RESERVE) 213 + * FIX_KMAP_xxx 0xfa000000 (via NR_CPUS * KM_TYPE_NR) 214 + * PKMAP_BASE 0xf9000000 (via LAST_PKMAP) 215 + * VMALLOC_START 0xf7000000 (via VMALLOC_RESERVE) 220 216 * mapped LOWMEM 0xc0000000 221 217 */ 222 218 223 219 #define MEM_USER_INTRPT _AC(0xfc000000, UL) 224 - #if CONFIG_KERNEL_PL == 1 225 - #define MEM_SV_INTRPT _AC(0xfd000000, UL) 226 - #define MEM_HV_INTRPT _AC(0xfe000000, UL) 227 - #else 228 - #define MEM_GUEST_INTRPT _AC(0xfd000000, UL) 229 - #define MEM_SV_INTRPT _AC(0xfe000000, UL) 230 - #define MEM_HV_INTRPT _AC(0xff000000, UL) 231 - #endif 220 + #define MEM_SV_START _AC(0xfd000000, UL) 221 + #define MEM_HV_START _AC(0xfe000000, UL) 232 222 233 223 #define INTRPT_SIZE 0x4000 234 224 ··· 242 246 243 247 #endif /* __tilegx__ */ 244 248 245 - #ifndef __ASSEMBLY__ 249 + #if !defined(__ASSEMBLY__) && !defined(VDSO_BUILD) 246 250 247 251 #ifdef CONFIG_HIGHMEM 248 252 ··· 328 332 329 333 struct mm_struct; 330 334 extern pte_t *virt_to_pte(struct mm_struct *mm, unsigned long addr); 335 + extern pte_t *virt_to_kpte(unsigned long kaddr); 331 336 332 337 #endif /* !__ASSEMBLY__ */ 333 338
+16 -6
arch/tile/include/asm/pci.h
··· 17 17 18 18 #include <linux/dma-mapping.h> 19 19 #include <linux/pci.h> 20 - #include <linux/numa.h> 21 20 #include <asm-generic/pci_iomap.h> 22 21 23 22 #ifndef __tilegx__ ··· 28 29 int index; /* PCI domain number */ 29 30 struct pci_bus *root_bus; 30 31 31 - int first_busno; 32 32 int last_busno; 33 33 34 34 int hv_cfg_fd[2]; /* config{0,1} fds for this PCIe controller */ ··· 122 124 * the CPA plus TILE_PCI_MEM_MAP_BASE_OFFSET. To support 32-bit 123 125 * devices, we create a separate map region that handles the low 124 126 * 4GB. 127 + * 128 + * This design lets us avoid the "PCI hole" problem where the host bridge 129 + * won't pass DMA traffic with target addresses that happen to fall within the 130 + * BAR space. This enables us to use all the physical memory for DMA, instead 131 + * of wasting the same amount of physical memory as the BAR window size. 125 132 */ 126 133 #define TILE_PCI_MEM_MAP_BASE_OFFSET (1ULL << CHIP_PA_WIDTH()) 127 134 ··· 148 145 149 146 int pio_mem_index; /* PIO region index for memory access */ 150 147 148 + #ifdef CONFIG_TILE_PCI_IO 149 + int pio_io_index; /* PIO region index for I/O space access */ 150 + #endif 151 + 151 152 /* 152 153 * Mem-Map regions for all the memory controllers so that Linux can 153 154 * map all of its physical memory space to the PCI bus. ··· 160 153 161 154 int index; /* PCI domain number */ 162 155 struct pci_bus *root_bus; 156 + 157 + /* PCI I/O space resource for this controller. */ 158 + struct resource io_space; 159 + char io_space_name[32]; 163 160 164 161 /* PCI memory space resource for this controller. */ 165 162 struct resource mem_space; ··· 177 166 178 167 /* Table that maps the INTx numbers to Linux irq numbers. */ 179 168 int irq_intx_table[4]; 180 - 181 - /* Address ranges that are routed to this controller/bridge. */ 182 - struct resource mem_resources[3]; 183 169 }; 184 170 185 171 extern struct pci_controller pci_controllers[TILEGX_NUM_TRIO * TILEGX_TRIO_PCIES]; 186 172 extern gxio_trio_context_t trio_contexts[TILEGX_NUM_TRIO]; 173 + extern int num_trio_shims; 187 174 188 175 extern void pci_iounmap(struct pci_dev *dev, void __iomem *); 189 176 ··· 220 211 } 221 212 222 213 #define PCIBIOS_MIN_MEM 0 223 - #define PCIBIOS_MIN_IO 0 214 + /* Minimum PCI I/O address, starting at the page boundary. */ 215 + #define PCIBIOS_MIN_IO PAGE_SIZE 224 216 225 217 /* Use any cpu for PCI. */ 226 218 #define cpumask_of_pcibus(bus) cpu_online_mask
+3 -1
arch/tile/include/asm/pgtable_32.h
··· 84 84 /* We have no pmd or pud since we are strictly a two-level page table */ 85 85 #include <asm-generic/pgtable-nopmd.h> 86 86 87 + static inline int pud_huge_page(pud_t pud) { return 0; } 88 + 87 89 /* We don't define any pgds for these addresses. */ 88 90 static 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 /*
+18 -9
arch/tile/include/asm/pgtable_64.h
··· 63 63 /* We have no pud since we are a three-level page table. */ 64 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 + 66 75 static inline int pud_none(pud_t pud) 67 76 { 68 77 return pud_val(pud) == 0; ··· 80 71 static inline int pud_present(pud_t pud) 81 72 { 82 73 return pud_val(pud) & _PAGE_PRESENT; 74 + } 75 + 76 + static inline int pud_huge_page(pud_t pud) 77 + { 78 + return pud_val(pud) & _PAGE_HUGE_PAGE; 83 79 } 84 80 85 81 #define pmd_ERROR(e) \ ··· 102 88 103 89 /* Return the page-table frame number (ptfn) that a pud_t points at. */ 104 90 #define pud_ptfn(pud) hv_pte_get_ptfn((pud).pgd) 91 + 92 + /* Return the page frame number (pfn) that a pud_t points at. */ 93 + #define pud_pfn(pud) pte_pfn(pud_pte(pud)) 105 94 106 95 /* 107 96 * A given kernel pud_t maps to a kernel pmd_t table at a specific ··· 140 123 /* We don't define any pgds for these addresses. */ 141 124 static inline int pgd_addr_invalid(unsigned long addr) 142 125 { 143 - return addr >= MEM_HV_START || 144 - (addr > MEM_LOW_END && addr < MEM_HIGH_START); 126 + return addr >= KERNEL_HIGH_VADDR || addr != pgd_addr_normalize(addr); 145 127 } 146 128 147 129 /* ··· 167 151 { 168 152 return hv_pte(__insn_exch(&ptep->val, 0UL)); 169 153 } 170 - 171 - /* 172 - * pmds are the same as pgds and ptes, so converting is a no-op. 173 - */ 174 - #define pmd_pte(pmd) (pmd) 175 - #define pmdp_ptep(pmdp) (pmdp) 176 - #define pte_pmd(pte) (pte) 177 154 178 155 #endif /* __ASSEMBLY__ */ 179 156
+48 -36
arch/tile/include/asm/processor.h
··· 15 15 #ifndef _ASM_TILE_PROCESSOR_H 16 16 #define _ASM_TILE_PROCESSOR_H 17 17 18 + #include <arch/chip.h> 19 + 18 20 #ifndef __ASSEMBLY__ 19 21 20 22 /* ··· 27 25 #include <asm/ptrace.h> 28 26 #include <asm/percpu.h> 29 27 30 - #include <arch/chip.h> 31 28 #include <arch/spr_def.h> 32 29 33 30 struct task_struct; ··· 111 110 unsigned long long interrupt_mask; 112 111 /* User interrupt-control 0 state */ 113 112 unsigned long intctrl_0; 114 - #if CHIP_HAS_PROC_STATUS_SPR() 113 + /* Is this task currently doing a backtrace? */ 114 + bool in_backtrace; 115 115 /* Any other miscellaneous processor state bits */ 116 116 unsigned long proc_status; 117 - #endif 118 117 #if !CHIP_HAS_FIXED_INTVEC_BASE() 119 118 /* Interrupt base for PL0 interrupts */ 120 119 unsigned long interrupt_vector_base; 121 120 #endif 122 - #if CHIP_HAS_TILE_RTF_HWM() 123 121 /* Tile cache retry fifo high-water mark */ 124 122 unsigned long tile_rtf_hwm; 125 - #endif 126 123 #if CHIP_HAS_DSTREAM_PF() 127 124 /* Data stream prefetch control */ 128 125 unsigned long dstream_pf; ··· 133 134 /* Async DMA TLB fault information */ 134 135 struct async_tlb dma_async_tlb; 135 136 #endif 136 - #if CHIP_HAS_SN_PROC() 137 - /* Was static network processor when we were switched out? */ 138 - int sn_proc_running; 139 - /* Async SNI TLB fault information */ 140 - struct async_tlb sn_async_tlb; 141 - #endif 142 137 }; 143 138 144 139 #endif /* !__ASSEMBLY__ */ 145 140 146 141 /* 147 142 * Start with "sp" this many bytes below the top of the kernel stack. 148 - * This preserves the invariant that a called function may write to *sp. 143 + * This allows us to be cache-aware when handling the initial save 144 + * of the pt_regs value to the stack. 149 145 */ 150 - #define STACK_TOP_DELTA 8 146 + #define STACK_TOP_DELTA 64 151 147 152 148 /* 153 149 * When entering the kernel via a fault, start with the top of the ··· 158 164 #ifndef __ASSEMBLY__ 159 165 160 166 #ifdef __tilegx__ 161 - #define TASK_SIZE_MAX (MEM_LOW_END + 1) 167 + #define TASK_SIZE_MAX (_AC(1, UL) << (MAX_VA_WIDTH - 1)) 162 168 #else 163 169 #define TASK_SIZE_MAX PAGE_OFFSET 164 170 #endif ··· 172 178 #define TASK_SIZE TASK_SIZE_MAX 173 179 #endif 174 180 175 - /* We provide a minimal "vdso" a la x86; just the sigreturn code for now. */ 176 - #define VDSO_BASE (TASK_SIZE - PAGE_SIZE) 181 + #define VDSO_BASE ((unsigned long)current->active_mm->context.vdso_base) 182 + #define VDSO_SYM(x) (VDSO_BASE + (unsigned long)(x)) 177 183 178 - #define STACK_TOP VDSO_BASE 184 + #define STACK_TOP TASK_SIZE 179 185 180 186 /* STACK_TOP_MAX is used temporarily in execve and should not check COMPAT. */ 181 187 #define STACK_TOP_MAX TASK_SIZE_MAX ··· 226 232 unsigned long get_wchan(struct task_struct *p); 227 233 228 234 /* Return initial ksp value for given task. */ 229 - #define task_ksp0(task) ((unsigned long)(task)->stack + THREAD_SIZE) 235 + #define task_ksp0(task) \ 236 + ((unsigned long)(task)->stack + THREAD_SIZE - STACK_TOP_DELTA) 230 237 231 238 /* Return some info about the user process TASK. */ 232 - #define KSTK_TOP(task) (task_ksp0(task) - STACK_TOP_DELTA) 233 239 #define task_pt_regs(task) \ 234 - ((struct pt_regs *)(task_ksp0(task) - KSTK_PTREGS_GAP) - 1) 240 + ((struct pt_regs *)(task_ksp0(task) - KSTK_PTREGS_GAP) - 1) 235 241 #define current_pt_regs() \ 236 - ((struct pt_regs *)((stack_pointer | (THREAD_SIZE - 1)) - \ 237 - (KSTK_PTREGS_GAP - 1)) - 1) 242 + ((struct pt_regs *)((stack_pointer | (THREAD_SIZE - 1)) - \ 243 + STACK_TOP_DELTA - (KSTK_PTREGS_GAP - 1)) - 1) 238 244 #define task_sp(task) (task_pt_regs(task)->sp) 239 245 #define task_pc(task) (task_pt_regs(task)->pc) 240 246 /* Aliases for pc and sp (used in fs/proc/array.c) */ 241 247 #define KSTK_EIP(task) task_pc(task) 242 248 #define KSTK_ESP(task) task_sp(task) 249 + 250 + /* Fine-grained unaligned JIT support */ 251 + #define GET_UNALIGN_CTL(tsk, adr) get_unalign_ctl((tsk), (adr)) 252 + #define SET_UNALIGN_CTL(tsk, val) set_unalign_ctl((tsk), (val)) 253 + 254 + extern int get_unalign_ctl(struct task_struct *tsk, unsigned long adr); 255 + extern int set_unalign_ctl(struct task_struct *tsk, unsigned int val); 243 256 244 257 /* Standard format for printing registers and other word-size data. */ 245 258 #ifdef __tilegx__ ··· 276 275 /* Data on which physical memory controller corresponds to which NUMA node. */ 277 276 extern int node_controller[]; 278 277 279 - #if CHIP_HAS_CBOX_HOME_MAP() 280 278 /* Does the heap allocator return hash-for-home pages by default? */ 281 279 extern int hash_default; 282 280 ··· 285 285 /* Does MAP_ANONYMOUS return hash-for-home pages by default? */ 286 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 289 /* Are we using huge pages in the TLB for kernel data? */ 295 290 extern int kdata_huge; ··· 332 337 333 338 /* 334 339 * Provide symbolic constants for PLs. 335 - * Note that assembly code assumes that USER_PL is zero. 336 340 */ 337 341 #define USER_PL 0 338 342 #if CONFIG_KERNEL_PL == 2 ··· 340 346 #define KERNEL_PL CONFIG_KERNEL_PL 341 347 342 348 /* SYSTEM_SAVE_K_0 holds the current cpu number ORed with ksp0. */ 343 - #define CPU_LOG_MASK_VALUE 12 344 - #define CPU_MASK_VALUE ((1 << CPU_LOG_MASK_VALUE) - 1) 345 - #if CONFIG_NR_CPUS > CPU_MASK_VALUE 346 - # error Too many cpus! 349 + #ifdef __tilegx__ 350 + #define CPU_SHIFT 48 351 + #if CHIP_VA_WIDTH() > CPU_SHIFT 352 + # error Too many VA bits! 347 353 #endif 354 + #define MAX_CPU_ID ((1 << (64 - CPU_SHIFT)) - 1) 348 355 #define raw_smp_processor_id() \ 349 - ((int)__insn_mfspr(SPR_SYSTEM_SAVE_K_0) & CPU_MASK_VALUE) 356 + ((int)(__insn_mfspr(SPR_SYSTEM_SAVE_K_0) >> CPU_SHIFT)) 350 357 #define get_current_ksp0() \ 351 - (__insn_mfspr(SPR_SYSTEM_SAVE_K_0) & ~CPU_MASK_VALUE) 358 + ((unsigned long)(((long)__insn_mfspr(SPR_SYSTEM_SAVE_K_0) << \ 359 + (64 - CPU_SHIFT)) >> (64 - CPU_SHIFT))) 360 + #define next_current_ksp0(task) ({ \ 361 + unsigned long __ksp0 = task_ksp0(task) & ((1UL << CPU_SHIFT) - 1); \ 362 + unsigned long __cpu = (long)raw_smp_processor_id() << CPU_SHIFT; \ 363 + __ksp0 | __cpu; \ 364 + }) 365 + #else 366 + #define LOG2_NR_CPU_IDS 6 367 + #define MAX_CPU_ID ((1 << LOG2_NR_CPU_IDS) - 1) 368 + #define raw_smp_processor_id() \ 369 + ((int)__insn_mfspr(SPR_SYSTEM_SAVE_K_0) & MAX_CPU_ID) 370 + #define get_current_ksp0() \ 371 + (__insn_mfspr(SPR_SYSTEM_SAVE_K_0) & ~MAX_CPU_ID) 352 372 #define next_current_ksp0(task) ({ \ 353 373 unsigned long __ksp0 = task_ksp0(task); \ 354 374 int __cpu = raw_smp_processor_id(); \ 355 - BUG_ON(__ksp0 & CPU_MASK_VALUE); \ 375 + BUG_ON(__ksp0 & MAX_CPU_ID); \ 356 376 __ksp0 | __cpu; \ 357 377 }) 378 + #endif 379 + #if CONFIG_NR_CPUS > (MAX_CPU_ID + 1) 380 + # error Too many cpus! 381 + #endif 358 382 359 383 #endif /* _ASM_TILE_PROCESSOR_H */
+3 -3
arch/tile/include/asm/ptrace.h
··· 33 33 34 34 #ifndef __ASSEMBLY__ 35 35 36 + #define regs_return_value(regs) ((regs)->regs[0]) 36 37 #define instruction_pointer(regs) ((regs)->pc) 37 38 #define profile_pc(regs) instruction_pointer(regs) 38 39 #define user_stack_pointer(regs) ((regs)->sp) 39 40 40 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 44 /* Fill in a struct pt_regs with the current kernel registers. */ 44 45 struct pt_regs *get_pt_regs(struct pt_regs *); ··· 80 79 81 80 struct task_struct; 82 81 83 - extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, 84 - int error_code); 82 + extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs); 85 83 86 84 #ifdef __tilegx__ 87 85 /* We need this since sigval_t has a user pointer in it, for GETSIGINFO etc. */
+7 -1
arch/tile/include/asm/sections.h
··· 25 25 /* Write-once data is writable only till the end of initialization. */ 26 26 extern char __w1data_begin[], __w1data_end[]; 27 27 28 + extern char vdso_start[], vdso_end[]; 29 + #ifdef CONFIG_COMPAT 30 + extern char vdso32_start[], vdso32_end[]; 31 + #endif 28 32 29 33 /* Not exactly sections, but PC comparison points in the code. */ 30 34 extern char __rt_sigreturn[], __rt_sigreturn_end[]; 31 - #ifndef __tilegx__ 35 + #ifdef __tilegx__ 36 + extern char __start_unalign_asm_code[], __end_unalign_asm_code[]; 37 + #else 32 38 extern char sys_cmpxchg[], __sys_cmpxchg_end[]; 33 39 extern char __sys_cmpxchg_grab_lock[]; 34 40 extern char __start_atomic_asm_code[], __end_atomic_asm_code[];
+1 -2
arch/tile/include/asm/setup.h
··· 24 24 */ 25 25 #define MAXMEM_PFN PFN_DOWN(MAXMEM) 26 26 27 + int tile_console_write(const char *buf, int count); 27 28 void early_panic(const char *fmt, ...); 28 - void warn_early_printk(void); 29 - void __init disable_early_printk(void); 30 29 31 30 /* Init-time routine to do tile-specific per-cpu setup. */ 32 31 void setup_cpu(int boot);
-2
arch/tile/include/asm/smp.h
··· 101 101 extern struct cpumask cpu_lotar_map; 102 102 #define cpu_is_valid_lotar(cpu) cpumask_test_cpu((cpu), &cpu_lotar_map) 103 103 104 - #if CHIP_HAS_CBOX_HOME_MAP() 105 104 /* Which processors are used for hash-for-home mapping */ 106 105 extern struct cpumask hash_for_home_map; 107 - #endif 108 106 109 107 /* Which cpus can have their cache flushed by hv_flush_remote(). */ 110 108 extern struct cpumask cpu_cacheable_map;
+2 -2
arch/tile/include/asm/spinlock_64.h
··· 27 27 * Return the "current" portion of a ticket lock value, 28 28 * i.e. the number that currently owns the lock. 29 29 */ 30 - static inline int arch_spin_current(u32 val) 30 + static inline u32 arch_spin_current(u32 val) 31 31 { 32 32 return val >> __ARCH_SPIN_CURRENT_SHIFT; 33 33 } ··· 36 36 * Return the "next" portion of a ticket lock value, 37 37 * i.e. the number that the next task to try to acquire the lock will get. 38 38 */ 39 - static inline int arch_spin_next(u32 val) 39 + static inline u32 arch_spin_next(u32 val) 40 40 { 41 41 return val & __ARCH_SPIN_NEXT_MASK; 42 42 }
+2
arch/tile/include/asm/string.h
··· 21 21 #define __HAVE_ARCH_MEMMOVE 22 22 #define __HAVE_ARCH_STRCHR 23 23 #define __HAVE_ARCH_STRLEN 24 + #define __HAVE_ARCH_STRNLEN 24 25 25 26 extern __kernel_size_t strlen(const char *); 27 + extern __kernel_size_t strnlen(const char *, __kernel_size_t); 26 28 extern char *strchr(const char *s, int c); 27 29 extern void *memchr(const void *s, int c, size_t n); 28 30 extern void *memset(void *, int, __kernel_size_t);
+6
arch/tile/include/asm/thread_info.h
··· 39 39 struct restart_block restart_block; 40 40 struct single_step_state *step_state; /* single step state 41 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 /* ··· 61 56 .fn = do_no_restart_syscall, \ 62 57 }, \ 63 58 .step_state = NULL, \ 59 + .align_ctl = 0, \ 64 60 } 65 61 66 62 #define init_thread_info (init_thread_union.thread_info)
+12 -1
arch/tile/include/asm/traps.h
··· 15 15 #ifndef _ASM_TILE_TRAPS_H 16 16 #define _ASM_TILE_TRAPS_H 17 17 18 + #ifndef __ASSEMBLY__ 18 19 #include <arch/chip.h> 19 20 20 21 /* mm/fault.c */ 21 22 void do_page_fault(struct pt_regs *, int fault_num, 22 23 unsigned long address, unsigned long write); 23 - #if CHIP_HAS_TILE_DMA() || CHIP_HAS_SN_PROC() 24 + #if CHIP_HAS_TILE_DMA() 24 25 void do_async_page_fault(struct pt_regs *); 25 26 #endif 26 27 ··· 70 69 71 70 /* kernel/intvec_64.S */ 72 71 void fill_ra_stack(void); 72 + 73 + /* Handle unalign data fixup. */ 74 + extern void do_unaligned(struct pt_regs *regs, int vecnum); 75 + #endif 76 + 77 + #endif /* __ASSEMBLY__ */ 78 + 79 + #ifdef __tilegx__ 80 + /* 128 byte JIT per unalign fixup. */ 81 + #define UNALIGN_JIT_SHIFT 7 73 82 #endif 74 83 75 84 #endif /* _ASM_TILE_TRAPS_H */
+6 -31
arch/tile/include/asm/uaccess.h
··· 127 127 128 128 #ifdef __LP64__ 129 129 #define _ASM_PTR ".quad" 130 + #define _ASM_ALIGN ".align 8" 130 131 #else 131 132 #define _ASM_PTR ".long" 133 + #define _ASM_ALIGN ".align 4" 132 134 #endif 133 135 134 136 #define __get_user_asm(OP, x, ptr, ret) \ ··· 139 137 "0: { movei %1, 0; movei %0, %3 }\n" \ 140 138 "j 9f\n" \ 141 139 ".section __ex_table,\"a\"\n" \ 140 + _ASM_ALIGN "\n" \ 142 141 _ASM_PTR " 1b, 0b\n" \ 143 142 ".popsection\n" \ 144 143 "9:" \ ··· 171 168 "0: { movei %1, 0; movei %2, 0 }\n" \ 172 169 "{ movei %0, %4; j 9f }\n" \ 173 170 ".section __ex_table,\"a\"\n" \ 171 + ".align 4\n" \ 174 172 ".word 1b, 0b\n" \ 175 173 ".word 2b, 0b\n" \ 176 174 ".popsection\n" \ ··· 228 224 ".pushsection .fixup,\"ax\"\n" \ 229 225 "0: { movei %0, %3; j 9f }\n" \ 230 226 ".section __ex_table,\"a\"\n" \ 227 + _ASM_ALIGN "\n" \ 231 228 _ASM_PTR " 1b, 0b\n" \ 232 229 ".popsection\n" \ 233 230 "9:" \ ··· 253 248 ".pushsection .fixup,\"ax\"\n" \ 254 249 "0: { movei %0, %4; j 9f }\n" \ 255 250 ".section __ex_table,\"a\"\n" \ 251 + ".align 4\n" \ 256 252 ".word 1b, 0b\n" \ 257 253 ".word 2b, 0b\n" \ 258 254 ".popsection\n" \ ··· 569 563 { 570 564 if (access_ok(VERIFY_WRITE, mem, len)) 571 565 return __flush_user(mem, len); 572 - return len; 573 - } 574 - 575 - /** 576 - * inv_user: - Invalidate a block of memory in user space from cache. 577 - * @mem: Destination address, in user space. 578 - * @len: Number of bytes to invalidate. 579 - * 580 - * Returns number of bytes that could not be invalidated. 581 - * On success, this will be zero. 582 - * 583 - * Note that on Tile64, the "inv" operation is in fact a 584 - * "flush and invalidate", so cache write-backs will occur prior 585 - * to the cache being marked invalid. 586 - */ 587 - extern unsigned long inv_user_asm(void __user *mem, unsigned long len); 588 - static inline unsigned long __must_check __inv_user( 589 - void __user *mem, unsigned long len) 590 - { 591 - int retval; 592 - 593 - might_fault(); 594 - retval = inv_user_asm(mem, len); 595 - mb_incoherent(); 596 - return retval; 597 - } 598 - static inline unsigned long __must_check inv_user( 599 - void __user *mem, unsigned long len) 600 - { 601 - if (access_ok(VERIFY_WRITE, mem, len)) 602 - return __inv_user(mem, len); 603 566 return len; 604 567 } 605 568
+9 -5
arch/tile/include/asm/unaligned.h
··· 15 15 #ifndef _ASM_TILE_UNALIGNED_H 16 16 #define _ASM_TILE_UNALIGNED_H 17 17 18 - #include <linux/unaligned/le_struct.h> 19 - #include <linux/unaligned/be_byteshift.h> 20 - #include <linux/unaligned/generic.h> 21 - #define get_unaligned __get_unaligned_le 22 - #define put_unaligned __put_unaligned_le 18 + /* 19 + * We could implement faster get_unaligned_[be/le]64 using the ldna 20 + * instruction on tilegx; however, we need to either copy all of the 21 + * other generic functions to here (which is pretty ugly) or else 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 29 * Is the kernel doing fixups of unaligned accesses? If <0, no kernel
+49
arch/tile/include/asm/vdso.h
··· 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 + 28 + struct 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 + 42 + extern struct vdso_data *vdso_data; 43 + 44 + /* __vdso_rt_sigreturn is defined with the addresses in the vdso page. */ 45 + extern void __vdso_rt_sigreturn(void); 46 + 47 + extern int setup_vdso_pages(void); 48 + 49 + #endif /* __TILE_VDSO_H__ */
+5
arch/tile/include/gxio/iorpc_trio.h
··· 30 30 31 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 34 #define GXIO_TRIO_OP_ALLOC_PIO_REGIONS IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1412) 34 35 35 36 #define GXIO_TRIO_OP_INIT_PIO_REGION_AUX IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1414) ··· 54 53 unsigned int count, unsigned int first, 55 54 unsigned int flags); 56 55 56 + 57 + int gxio_trio_alloc_scatter_queues(gxio_trio_context_t * context, 58 + unsigned int count, unsigned int first, 59 + unsigned int flags); 57 60 58 61 int gxio_trio_alloc_pio_regions(gxio_trio_context_t * context, 59 62 unsigned int count, unsigned int first,
+40
arch/tile/include/gxio/iorpc_uart.h
··· 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 + 32 + int gxio_uart_cfg_interrupt(gxio_uart_context_t *context, int inter_x, 33 + int inter_y, int inter_ipi, int inter_event); 34 + 35 + int gxio_uart_get_mmio_base(gxio_uart_context_t *context, HV_PTE *base); 36 + 37 + int 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__ */
+105
arch/tile/include/gxio/uart.h
··· 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. */ 34 + typedef 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 + */ 58 + extern 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 + */ 74 + extern 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 + */ 88 + extern 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 + */ 95 + extern 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 + */ 103 + extern uint64_t gxio_uart_read(gxio_uart_context_t *context, uint64_t offset); 104 + 105 + #endif /* _GXIO_UART_H_ */
+6 -2
arch/tile/include/hv/drv_trio_intf.h
··· 64 64 * will not consider it an error if the link comes up as a x8 link. */ 65 65 uint8_t allow_x8: 1; 66 66 67 - /** Reserved. */ 68 - uint8_t reserved: 1; 67 + /** If true, this link is connected to a device which may or may not 68 + * be present. */ 69 + uint8_t removable: 1; 69 70 70 71 }; 71 72 ··· 168 167 struct pcie_trio_ports_property 169 168 { 170 169 struct pcie_port_property ports[TILEGX_TRIO_PCIES]; 170 + 171 + /** Set if this TRIO belongs to a Gx72 device. */ 172 + uint8_t is_gx72; 171 173 }; 172 174 173 175 /* Flags indicating traffic class. */
+33
arch/tile/include/hv/drv_uart_intf.h
··· 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 */
+41 -20
arch/tile/include/hv/hypervisor.h
··· 318 318 /** hv_set_pte_super_shift */ 319 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 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 328 #ifndef __ASSEMBLER__ ··· 544 541 HV_CONFSTR_CPUMOD_REV = 18, 545 542 546 543 /** Human-readable CPU module description. */ 547 - HV_CONFSTR_CPUMOD_DESC = 19 544 + HV_CONFSTR_CPUMOD_DESC = 19, 545 + 546 + /** Per-tile hypervisor statistics. When this identifier is specified, 547 + * the hv_confstr call takes two extra arguments. The first is the 548 + * HV_XY_TO_LOTAR of the target tile's coordinates. The second is 549 + * a flag word. The only current flag is the lowest bit, which means 550 + * "zero out the stats instead of retrieving them"; in this case the 551 + * buffer and buffer length are ignored. */ 552 + HV_CONFSTR_HV_STATS = 20 548 553 549 554 } HV_ConfstrQuery; 550 555 551 556 /** Query a configuration string from the hypervisor. 552 557 * 553 558 * @param query Identifier for the specific string to be retrieved 554 - * (HV_CONFSTR_xxx). 559 + * (HV_CONFSTR_xxx). Some strings may require or permit extra 560 + * arguments to be appended which select specific objects to be 561 + * described; see the string descriptions above. 555 562 * @param buf Buffer in which to place the string. 556 563 * @param len Length of the buffer. 557 564 * @return If query is valid, then the length of the corresponding string, ··· 569 556 * was truncated. If query is invalid, HV_EINVAL. If the specified 570 557 * buffer is not writable by the client, HV_EFAULT. 571 558 */ 572 - int hv_confstr(HV_ConfstrQuery query, HV_VirtAddr buf, int len); 559 + int hv_confstr(HV_ConfstrQuery query, HV_VirtAddr buf, int len, ...); 573 560 574 561 /** Tile coordinate */ 575 562 typedef struct 576 563 { 577 - #ifndef __BIG_ENDIAN__ 578 564 /** X coordinate, relative to supervisor's top-left coordinate */ 579 565 int x; 580 566 581 567 /** Y coordinate, relative to supervisor's top-left coordinate */ 582 568 int y; 583 - #else 584 - int y; 585 - int x; 586 - #endif 587 569 } HV_Coord; 588 570 589 571 ··· 592 584 * @result Zero if no error, non-zero for invalid parameters. 593 585 */ 594 586 int hv_get_ipi_pte(HV_Coord tile, int pl, HV_PTE* pte); 587 + 588 + /** Configure the console interrupt. 589 + * 590 + * When the console client interrupt is enabled, the hypervisor will 591 + * deliver the specified IPI to the client in the following situations: 592 + * 593 + * - The console has at least one character available for input. 594 + * 595 + * - The console can accept new characters for output, and the last call 596 + * to hv_console_write() did not write all of the characters requested 597 + * by the client. 598 + * 599 + * Note that in some system configurations, console interrupt will not 600 + * be available; clients should be prepared for this routine to fail and 601 + * to fall back to periodic console polling in that case. 602 + * 603 + * @param ipi Index of the IPI register which will receive the interrupt. 604 + * @param event IPI event number for console interrupt. If less than 0, 605 + * disable the console IPI interrupt. 606 + * @param coord Tile to be targeted for console interrupt. 607 + * @return 0 on success, otherwise, HV_EINVAL if illegal parameter, 608 + * HV_ENOTSUP if console interrupt are not available. 609 + */ 610 + int hv_console_set_ipi(int ipi, int event, HV_Coord coord); 595 611 596 612 #else /* !CHIP_HAS_IPI() */ 597 613 ··· 1124 1092 /** A range of ASID values. */ 1125 1093 typedef struct 1126 1094 { 1127 - #ifndef __BIG_ENDIAN__ 1128 1095 HV_ASID start; /**< First ASID in the range. */ 1129 1096 unsigned int size; /**< Number of ASIDs. Zero for an invalid range. */ 1130 - #else 1131 - unsigned int size; /**< Number of ASIDs. Zero for an invalid range. */ 1132 - HV_ASID start; /**< First ASID in the range. */ 1133 - #endif 1134 1097 } HV_ASIDRange; 1135 1098 1136 1099 /** Returns information about a range of ASIDs. ··· 1449 1422 /** Message recipient. */ 1450 1423 typedef struct 1451 1424 { 1452 - #ifndef __BIG_ENDIAN__ 1453 1425 /** X coordinate, relative to supervisor's top-left coordinate */ 1454 1426 unsigned int x:11; 1455 1427 ··· 1457 1431 1458 1432 /** Status of this recipient */ 1459 1433 HV_Recip_State state:10; 1460 - #else //__BIG_ENDIAN__ 1461 - HV_Recip_State state:10; 1462 - unsigned int y:11; 1463 - unsigned int x:11; 1464 - #endif 1465 1434 } HV_Recipient; 1466 1435 1467 1436 /** Send a message to a set of recipients.
-1
arch/tile/include/uapi/arch/Kbuild
··· 1 1 # UAPI Header export list 2 2 header-y += abi.h 3 3 header-y += chip.h 4 - header-y += chip_tile64.h 5 4 header-y += chip_tilegx.h 6 5 header-y += chip_tilepro.h 7 6 header-y += icache.h
+1 -3
arch/tile/include/uapi/arch/chip.h
··· 12 12 * more details. 13 13 */ 14 14 15 - #if __tile_chip__ == 0 16 - #include <arch/chip_tile64.h> 17 - #elif __tile_chip__ == 1 15 + #if __tile_chip__ == 1 18 16 #include <arch/chip_tilepro.h> 19 17 #elif defined(__tilegx__) 20 18 #include <arch/chip_tilegx.h>
-258
arch/tile/include/uapi/arch/chip_tile64.h
··· 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__ */
+1
arch/tile/include/uapi/arch/opcode_tilegx.h
··· 61 61 #define TILE_BUNDLE_ALIGNMENT_IN_BYTES TILEGX_BUNDLE_ALIGNMENT_IN_BYTES 62 62 #define TILE_LOG2_BUNDLE_ALIGNMENT_IN_BYTES \ 63 63 TILEGX_LOG2_BUNDLE_ALIGNMENT_IN_BYTES 64 + #define TILE_BPT_BUNDLE TILEGX_BPT_BUNDLE 64 65 65 66 /* 64-bit pattern for a { bpt ; nop } bundle. */ 66 67 #define TILEGX_BPT_BUNDLE 0x286a44ae51485000ULL
+1
arch/tile/include/uapi/arch/opcode_tilepro.h
··· 71 71 #define TILE_BUNDLE_ALIGNMENT_IN_BYTES TILEPRO_BUNDLE_ALIGNMENT_IN_BYTES 72 72 #define TILE_LOG2_BUNDLE_ALIGNMENT_IN_BYTES \ 73 73 TILEPRO_LOG2_BUNDLE_ALIGNMENT_IN_BYTES 74 + #define TILE_BPT_BUNDLE TILEPRO_BPT_BUNDLE 74 75 75 76 /* 64-bit pattern for a { bpt ; nop } bundle. */ 76 77 #define TILEPRO_BPT_BUNDLE 0x400b3cae70166000ULL
-2
arch/tile/include/uapi/arch/spr_def_32.h
··· 200 200 #define SPR_SIM_CONTROL 0x4e0c 201 201 #define SPR_SNCTL 0x0805 202 202 #define SPR_SNCTL__FRZFABRIC_MASK 0x1 203 - #define SPR_SNCTL__FRZPROC_MASK 0x2 204 - #define SPR_SNPC 0x080b 205 203 #define SPR_SNSTATIC 0x080c 206 204 #define SPR_SYSTEM_SAVE_0_0 0x4b00 207 205 #define SPR_SYSTEM_SAVE_0_1 0x4b01
+2 -1
arch/tile/include/uapi/asm/auxvec.h
··· 15 15 #ifndef _ASM_TILE_AUXVEC_H 16 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 21 #endif /* _ASM_TILE_AUXVEC_H */
+2 -2
arch/tile/include/uapi/asm/cachectl.h
··· 29 29 * to honor the arguments at some point.) 30 30 * 31 31 * Flush and invalidation of memory can normally be performed with the 32 - * __insn_flush(), __insn_inv(), and __insn_finv() instructions from 33 - * userspace. The DCACHE option to the system call allows userspace 32 + * __insn_flush() and __insn_finv() instructions from userspace. 33 + * The DCACHE option to the system call allows userspace 34 34 * to flush the entire L1+L2 data cache from the core. In this case, 35 35 * the address and length arguments are not used. The DCACHE flush is 36 36 * restricted to the current core, not all cores in the address space.
+14 -2
arch/tile/kernel/Makefile
··· 3 3 # 4 4 5 5 extra-y := vmlinux.lds head_$(BITS).o 6 - obj-y := backtrace.o entry.o irq.o messaging.o \ 6 + obj-y := backtrace.o entry.o hvglue.o irq.o messaging.o \ 7 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 10 intvec_$(BITS).o regs_$(BITS).o tile-desc_$(BITS).o 11 + 12 + ifdef CONFIG_FUNCTION_TRACER 13 + CFLAGS_REMOVE_ftrace.o = -pg 14 + CFLAGS_REMOVE_early_printk.o = -pg 15 + endif 10 16 11 17 obj-$(CONFIG_HARDWALL) += hardwall.o 12 18 obj-$(CONFIG_COMPAT) += compat.o compat_signal.o ··· 26 20 obj-$(CONFIG_PCI) += pci.o 27 21 endif 28 22 obj-$(CONFIG_TILE_USB) += usb.o 23 + obj-$(CONFIG_TILE_HVGLUE_TRACE) += hvglue_trace.o 24 + obj-$(CONFIG_FUNCTION_TRACER) += ftrace.o mcount_64.o 25 + obj-$(CONFIG_KPROBES) += kprobes.o 26 + obj-$(CONFIG_KGDB) += kgdb.o 27 + 28 + obj-y += vdso/
+30 -22
arch/tile/kernel/asm-offsets.c
··· 14 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 17 /* Check for compatible compiler early in the build. */ 25 18 #ifdef CONFIG_TILEGX 26 19 # ifndef __tilegx__ ··· 24 31 # endif 25 32 #else 26 33 # ifdef __tilegx__ 27 - # error Can not build TILEPro/TILE64 configurations with tilegx compiler 34 + # error Can not build TILEPro configurations with tilegx compiler 28 35 # endif 29 36 #endif 30 37 38 + #include <linux/kbuild.h> 39 + #include <linux/thread_info.h> 40 + #include <linux/sched.h> 41 + #include <linux/hardirq.h> 42 + #include <linux/ptrace.h> 43 + #include <hv/hypervisor.h> 44 + 31 45 void foo(void) 32 46 { 33 - DEFINE(SINGLESTEP_STATE_BUFFER_OFFSET, \ 47 + DEFINE(SINGLESTEP_STATE_BUFFER_OFFSET, 34 48 offsetof(struct single_step_state, buffer)); 35 - DEFINE(SINGLESTEP_STATE_FLAGS_OFFSET, \ 49 + DEFINE(SINGLESTEP_STATE_FLAGS_OFFSET, 36 50 offsetof(struct single_step_state, flags)); 37 - DEFINE(SINGLESTEP_STATE_ORIG_PC_OFFSET, \ 51 + DEFINE(SINGLESTEP_STATE_ORIG_PC_OFFSET, 38 52 offsetof(struct single_step_state, orig_pc)); 39 - DEFINE(SINGLESTEP_STATE_NEXT_PC_OFFSET, \ 53 + DEFINE(SINGLESTEP_STATE_NEXT_PC_OFFSET, 40 54 offsetof(struct single_step_state, next_pc)); 41 - DEFINE(SINGLESTEP_STATE_BRANCH_NEXT_PC_OFFSET, \ 55 + DEFINE(SINGLESTEP_STATE_BRANCH_NEXT_PC_OFFSET, 42 56 offsetof(struct single_step_state, branch_next_pc)); 43 - DEFINE(SINGLESTEP_STATE_UPDATE_VALUE_OFFSET, \ 57 + DEFINE(SINGLESTEP_STATE_UPDATE_VALUE_OFFSET, 44 58 offsetof(struct single_step_state, update_value)); 45 59 46 - DEFINE(THREAD_INFO_TASK_OFFSET, \ 60 + DEFINE(THREAD_INFO_TASK_OFFSET, 47 61 offsetof(struct thread_info, task)); 48 - DEFINE(THREAD_INFO_FLAGS_OFFSET, \ 62 + DEFINE(THREAD_INFO_FLAGS_OFFSET, 49 63 offsetof(struct thread_info, flags)); 50 - DEFINE(THREAD_INFO_STATUS_OFFSET, \ 64 + DEFINE(THREAD_INFO_STATUS_OFFSET, 51 65 offsetof(struct thread_info, status)); 52 - DEFINE(THREAD_INFO_HOMECACHE_CPU_OFFSET, \ 66 + DEFINE(THREAD_INFO_HOMECACHE_CPU_OFFSET, 53 67 offsetof(struct thread_info, homecache_cpu)); 54 - DEFINE(THREAD_INFO_STEP_STATE_OFFSET, \ 68 + DEFINE(THREAD_INFO_PREEMPT_COUNT_OFFSET, 69 + offsetof(struct thread_info, preempt_count)); 70 + DEFINE(THREAD_INFO_STEP_STATE_OFFSET, 55 71 offsetof(struct thread_info, step_state)); 72 + #ifdef __tilegx__ 73 + DEFINE(THREAD_INFO_UNALIGN_JIT_BASE_OFFSET, 74 + offsetof(struct thread_info, unalign_jit_base)); 75 + DEFINE(THREAD_INFO_UNALIGN_JIT_TMP_OFFSET, 76 + offsetof(struct thread_info, unalign_jit_tmp)); 77 + #endif 56 78 57 79 DEFINE(TASK_STRUCT_THREAD_KSP_OFFSET, 58 80 offsetof(struct task_struct, thread.ksp)); 59 81 DEFINE(TASK_STRUCT_THREAD_PC_OFFSET, 60 82 offsetof(struct task_struct, thread.pc)); 61 83 62 - DEFINE(HV_TOPOLOGY_WIDTH_OFFSET, \ 84 + DEFINE(HV_TOPOLOGY_WIDTH_OFFSET, 63 85 offsetof(HV_Topology, width)); 64 - DEFINE(HV_TOPOLOGY_HEIGHT_OFFSET, \ 86 + DEFINE(HV_TOPOLOGY_HEIGHT_OFFSET, 65 87 offsetof(HV_Topology, height)); 66 88 67 - DEFINE(IRQ_CPUSTAT_SYSCALL_COUNT_OFFSET, \ 89 + DEFINE(IRQ_CPUSTAT_SYSCALL_COUNT_OFFSET, 68 90 offsetof(irq_cpustat_t, irq_syscall_count)); 69 91 }
+2 -1
arch/tile/kernel/compat_signal.c
··· 32 32 #include <asm/ucontext.h> 33 33 #include <asm/sigframe.h> 34 34 #include <asm/syscalls.h> 35 + #include <asm/vdso.h> 35 36 #include <arch/interrupts.h> 36 37 37 38 struct compat_ucontext { ··· 228 227 if (err) 229 228 goto give_sigsegv; 230 229 231 - restorer = VDSO_BASE; 230 + restorer = VDSO_SYM(&__vdso_rt_sigreturn); 232 231 if (ka->sa.sa_flags & SA_RESTORER) 233 232 restorer = ptr_to_compat_reg(ka->sa.sa_restorer); 234 233
+11 -36
arch/tile/kernel/early_printk.c
··· 23 23 24 24 static 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 29 37 static struct console early_hv_console = { 30 38 .name = "earlyhv", 31 39 .write = early_hv_write, 32 - .flags = CON_PRINTBUFFER, 40 + .flags = CON_PRINTBUFFER | CON_BOOT, 33 41 .index = -1, 34 42 }; 35 - 36 - /* Direct interface for emergencies */ 37 - static int early_console_complete; 38 43 39 44 void early_panic(const char *fmt, ...) 40 45 { ··· 48 43 va_start(ap, fmt); 49 44 early_printk("Kernel panic - not syncing: "); 50 45 early_vprintk(fmt, ap); 51 - early_console->write(early_console, "\n", 1); 46 + early_printk("\n"); 52 47 va_end(ap); 53 48 dump_stack(); 54 49 hv_halt(); 55 50 } 56 - 57 - static int __initdata keep_early; 58 51 59 52 static int __init setup_early_printk(char *str) 60 53 { 61 54 if (early_console) 62 55 return 1; 63 56 64 - if (str != NULL && strncmp(str, "keep", 4) == 0) 65 - keep_early = 1; 66 - 67 57 early_console = &early_hv_console; 68 58 register_console(early_console); 69 59 70 60 return 0; 71 - } 72 - 73 - void __init disable_early_printk(void) 74 - { 75 - early_console_complete = 1; 76 - if (!early_console) 77 - return; 78 - if (!keep_early) { 79 - early_printk("disabling early console\n"); 80 - unregister_console(early_console); 81 - early_console = NULL; 82 - } else { 83 - early_printk("keeping early console\n"); 84 - } 85 - } 86 - 87 - void warn_early_printk(void) 88 - { 89 - if (early_console_complete || early_console) 90 - return; 91 - early_printk("\ 92 - Machine shutting down before console output is fully initialized.\n\ 93 - You may wish to reboot and add the option 'earlyprintk' to your\n\ 94 - boot command line to see any diagnostic early console output.\n\ 95 - "); 96 61 } 97 62 98 63 early_param("earlyprintk", setup_early_printk);
-16
arch/tile/kernel/entry.S
··· 27 27 { move r0, lr; jrp lr } 28 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 39 - ENTRY(__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 - 46 30 STD_ENTRY(dump_stack) 47 31 { move r2, lr; lnk r1 } 48 32 { move r4, r52; addli r1, r1, dump_stack - . }
+246
arch/tile/kernel/ftrace.c
··· 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 + 28 + static 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 + 38 + static int machine_stopped __read_mostly; 39 + 40 + int ftrace_arch_code_modify_prepare(void) 41 + { 42 + machine_stopped = 1; 43 + return 0; 44 + } 45 + 46 + int 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 + */ 57 + static 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 + 96 + static unsigned long ftrace_nop_replace(struct dyn_ftrace *rec) 97 + { 98 + return NOP(); 99 + } 100 + 101 + static unsigned long ftrace_call_replace(unsigned long pc, unsigned long addr) 102 + { 103 + return ftrace_gen_branch(pc, addr, true); 104 + } 105 + 106 + static 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 + 129 + int 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 + 144 + int 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 + 155 + int 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 + 170 + int __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 179 + void 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 210 + extern unsigned long ftrace_graph_call; 211 + 212 + static 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 + 225 + static 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 + 236 + int ftrace_enable_ftrace_graph_caller(void) 237 + { 238 + return ftrace_modify_graph_caller(true); 239 + } 240 + 241 + int 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 */
+18 -10
arch/tile/kernel/hardwall.c
··· 272 272 struct hardwall_info *r = info; 273 273 struct hardwall_type *hwt = r->type; 274 274 275 - int cpu = smp_processor_id(); 276 - int x = cpu % smp_width; 277 - int y = cpu / smp_width; 275 + int cpu = smp_processor_id(); /* on_each_cpu disables preemption */ 276 + int x = cpu_x(cpu); 277 + int y = cpu_y(cpu); 278 278 int bits = 0; 279 279 if (x == r->ulhc_x) 280 280 bits |= W_PROTECT; ··· 317 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. */ 320 321 void __kprobes do_hardwall_trap(struct pt_regs* regs, int fault_num) 321 322 { 322 323 struct hardwall_info *rect; ··· 326 325 struct siginfo info; 327 326 int cpu = smp_processor_id(); 328 327 int found_processes; 329 - unsigned long flags; 330 328 struct pt_regs *old_regs = set_irq_regs(regs); 331 329 332 330 irq_enter(); ··· 346 346 BUG_ON(hwt->disabled); 347 347 348 348 /* This tile trapped a network access; find the rectangle. */ 349 - spin_lock_irqsave(&hwt->lock, flags); 349 + spin_lock(&hwt->lock); 350 350 list_for_each_entry(rect, &hwt->list, list) { 351 351 if (cpumask_test_cpu(cpu, &rect->cpumask)) 352 352 break; ··· 401 401 pr_notice("hardwall: no associated processes!\n"); 402 402 403 403 done: 404 - spin_unlock_irqrestore(&hwt->lock, flags); 404 + spin_unlock(&hwt->lock); 405 405 406 406 /* 407 407 * We have to disable firewall interrupts now, or else when we ··· 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 551 /* Confirm it doesn't overlap and add it to the list. */ 544 552 spin_lock_irqsave(&hwt->lock, flags); 545 553 list_for_each_entry(iter, &hwt->list, list) { ··· 620 612 621 613 /* 622 614 * Deactivate a task's hardwall. Must hold lock for hardwall_type. 623 - * This method may be called from free_task(), so we don't want to 615 + * This method may be called from exit_thread(), so we don't want to 624 616 * rely on too many fields of struct task_struct still being valid. 625 617 * We assume the cpus_allowed, pid, and comm fields are still valid. 626 618 */ ··· 661 653 return -EINVAL; 662 654 663 655 printk(KERN_DEBUG "Pid %d (%s) deactivated for %s hardwall: cpu %d\n", 664 - task->pid, task->comm, hwt->name, smp_processor_id()); 656 + task->pid, task->comm, hwt->name, raw_smp_processor_id()); 665 657 return 0; 666 658 } 667 659 ··· 803 795 /* Reset UDN coordinates to their standard value */ 804 796 { 805 797 unsigned int cpu = smp_processor_id(); 806 - unsigned int x = cpu % smp_width; 807 - unsigned int y = cpu / smp_width; 798 + unsigned int x = cpu_x(cpu); 799 + unsigned int y = cpu_y(cpu); 808 800 __insn_mtspr(SPR_UDN_TILE_COORD, (x << 18) | (y << 7)); 809 801 } 810 802
+8 -9
arch/tile/kernel/head_32.S
··· 39 39 } 40 40 { 41 41 moveli r0, _HV_VERSION_OLD_HV_INIT 42 - jal hv_init 42 + jal _hv_init 43 43 } 44 44 /* Get a reasonable default ASID in r0 */ 45 45 { 46 46 move r0, zero 47 - jal hv_inquire_asid 47 + jal _hv_inquire_asid 48 48 } 49 49 /* Install the default page table */ 50 50 { ··· 64 64 auli r0, r0, ha16(swapper_pg_dir - PAGE_OFFSET) 65 65 } 66 66 { 67 - inv r6 67 + finv r6 68 68 move r1, zero /* high 32 bits of CPA is zero */ 69 69 } 70 70 { ··· 73 73 } 74 74 { 75 75 auli lr, lr, ha16(1f) 76 - j hv_install_context 76 + j _hv_install_context 77 77 } 78 78 1: 79 79 80 80 /* Get our processor number and save it away in SAVE_K_0. */ 81 - jal hv_inquire_topology 81 + jal _hv_inquire_topology 82 82 mulll_uu r4, r1, r2 /* r1 == y, r2 == width */ 83 83 add r4, r4, r0 /* r0 == x, so r4 == cpu == y*width + x */ 84 84 ··· 86 86 /* 87 87 * Load up our per-cpu offset. When the first (master) tile 88 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 90 * The master tile initializes the per-cpu offset array, so that 91 91 * when subsequent (secondary) tiles boot, they will instead load 92 92 * from their per-cpu versions of boot_sp and boot_pc. ··· 126 126 lw sp, r1 127 127 or r4, sp, r4 128 128 mtspr SPR_SYSTEM_SAVE_K_0, r4 /* save ksp0 + cpu */ 129 - addi sp, sp, -STACK_TOP_DELTA 130 129 { 131 130 move lr, zero /* stop backtraces in the called function */ 132 131 jr r0 ··· 162 163 .set addr, addr + PGDIR_SIZE 163 164 .endr 164 165 165 - /* The true text VAs are mapped as VA = PA + MEM_SV_INTRPT */ 166 - PTE MEM_SV_INTRPT, 0, (1 << (HV_PTE_INDEX_READABLE - 32)) | \ 166 + /* The true text VAs are mapped as VA = PA + MEM_SV_START */ 167 + PTE MEM_SV_START, 0, (1 << (HV_PTE_INDEX_READABLE - 32)) | \ 167 168 (1 << (HV_PTE_INDEX_EXECUTABLE - 32)) 168 169 .org swapper_pg_dir + PGDIR_SIZE 169 170 END(swapper_pg_dir)
+25 -21
arch/tile/kernel/head_64.S
··· 25 25 #include <arch/chip.h> 26 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 38 * This module contains the entry code for kernel images. It performs the 30 39 * minimal setup needed to call the generic C routines. ··· 55 46 movei r2, TILE_CHIP_REV 56 47 movei r3, KERNEL_PL 57 48 } 58 - jal hv_init 49 + jal _hv_init 59 50 /* Get a reasonable default ASID in r0 */ 60 51 { 61 52 move r0, zero 62 - jal hv_inquire_asid 53 + jal _hv_inquire_asid 63 54 } 64 55 65 56 /* ··· 70 61 * other CPUs should see a properly-constructed page table. 71 62 */ 72 63 { 73 - v4int_l r2, zero, r0 /* ASID for hv_install_context */ 64 + GET_FIRST_INT(r2, r0) /* ASID for hv_install_context */ 74 65 moveli r4, hw1_last(swapper_pgprot - PAGE_OFFSET) 75 66 } 76 67 { ··· 86 77 { 87 78 /* After initializing swapper_pgprot, HV_PTE_GLOBAL is set. */ 88 79 bfextu r7, r1, HV_PTE_INDEX_GLOBAL, HV_PTE_INDEX_GLOBAL 89 - inv r4 80 + finv r4 90 81 } 91 82 bnez r7, .Lno_write 92 83 { ··· 130 121 } 131 122 { 132 123 moveli r3, CTX_PAGE_FLAG 133 - j hv_install_context 124 + j _hv_install_context 134 125 } 135 126 1: 136 127 137 128 /* Install the interrupt base. */ 138 - moveli r0, hw2_last(MEM_SV_START) 139 - shl16insli r0, r0, hw1(MEM_SV_START) 140 - shl16insli r0, r0, hw0(MEM_SV_START) 129 + moveli r0, hw2_last(intrpt_start) 130 + shl16insli r0, r0, hw1(intrpt_start) 131 + shl16insli r0, r0, hw0(intrpt_start) 141 132 mtspr SPR_INTERRUPT_VECTOR_BASE_K, r0 142 133 143 - /* 144 - * Get our processor number and save it away in SAVE_K_0. 145 - * Extract stuff from the topology structure: r4 = y, r6 = x, 146 - * r5 = width. FIXME: consider whether we want to just make these 147 - * 64-bit values (and if so fix smp_topology write below, too). 148 - */ 149 - jal hv_inquire_topology 134 + /* Get our processor number and save it away in SAVE_K_0. */ 135 + jal _hv_inquire_topology 150 136 { 151 - v4int_l r5, zero, r1 /* r5 = width */ 152 - shrui r4, r0, 32 /* r4 = y */ 137 + GET_FIRST_INT(r5, r1) /* r5 = width */ 138 + GET_SECOND_INT(r4, r0) /* r4 = y */ 153 139 } 154 140 { 155 - v4int_l r6, zero, r0 /* r6 = x */ 141 + GET_FIRST_INT(r6, r0) /* r6 = x */ 156 142 mul_lu_lu r4, r4, r5 157 143 } 158 144 { ··· 158 154 /* 159 155 * Load up our per-cpu offset. When the first (master) tile 160 156 * boots, this value is still zero, so we will load boot_pc 161 - * with start_kernel, and boot_sp with init_stack + THREAD_SIZE. 157 + * with start_kernel, and boot_sp with at the top of init_stack. 162 158 * The master tile initializes the per-cpu offset array, so that 163 159 * when subsequent (secondary) tiles boot, they will instead load 164 160 * from their per-cpu versions of boot_sp and boot_pc. ··· 202 198 } 203 199 ld r0, r0 204 200 ld sp, r1 205 - or r4, sp, r4 201 + shli r4, r4, CPU_SHIFT 202 + bfins r4, sp, 0, CPU_SHIFT-1 206 203 mtspr SPR_SYSTEM_SAVE_K_0, r4 /* save ksp0 + cpu */ 207 - addi sp, sp, -STACK_TOP_DELTA 208 204 { 209 205 move lr, zero /* stop backtraces in the called function */ 210 206 jr r0
+74
arch/tile/kernel/hvglue.S
··· 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 16 + gensym hv_init, 0x20, 32 17 + gensym hv_install_context, 0x40, 32 18 + gensym hv_sysconf, 0x60, 32 19 + gensym hv_get_rtc, 0x80, 32 20 + gensym hv_set_rtc, 0xa0, 32 21 + gensym hv_flush_asid, 0xc0, 32 22 + gensym hv_flush_page, 0xe0, 32 23 + gensym hv_flush_pages, 0x100, 32 24 + gensym hv_restart, 0x120, 32 25 + gensym hv_halt, 0x140, 32 26 + gensym hv_power_off, 0x160, 32 27 + gensym hv_inquire_physical, 0x180, 32 28 + gensym hv_inquire_memory_controller, 0x1a0, 32 29 + gensym hv_inquire_virtual, 0x1c0, 32 30 + gensym hv_inquire_asid, 0x1e0, 32 31 + gensym hv_nanosleep, 0x200, 32 32 + gensym hv_console_read_if_ready, 0x220, 32 33 + gensym hv_console_write, 0x240, 32 34 + gensym hv_downcall_dispatch, 0x260, 32 35 + gensym hv_inquire_topology, 0x280, 32 36 + gensym hv_fs_findfile, 0x2a0, 32 37 + gensym hv_fs_fstat, 0x2c0, 32 38 + gensym hv_fs_pread, 0x2e0, 32 39 + gensym hv_physaddr_read64, 0x300, 32 40 + gensym hv_physaddr_write64, 0x320, 32 41 + gensym hv_get_command_line, 0x340, 32 42 + gensym hv_set_caching, 0x360, 32 43 + gensym hv_bzero_page, 0x380, 32 44 + gensym hv_register_message_state, 0x3a0, 32 45 + gensym hv_send_message, 0x3c0, 32 46 + gensym hv_receive_message, 0x3e0, 32 47 + gensym hv_inquire_context, 0x400, 32 48 + gensym hv_start_all_tiles, 0x420, 32 49 + gensym hv_dev_open, 0x440, 32 50 + gensym hv_dev_close, 0x460, 32 51 + gensym hv_dev_pread, 0x480, 32 52 + gensym hv_dev_pwrite, 0x4a0, 32 53 + gensym hv_dev_poll, 0x4c0, 32 54 + gensym hv_dev_poll_cancel, 0x4e0, 32 55 + gensym hv_dev_preada, 0x500, 32 56 + gensym hv_dev_pwritea, 0x520, 32 57 + gensym hv_flush_remote, 0x540, 32 58 + gensym hv_console_putc, 0x560, 32 59 + gensym hv_inquire_tiles, 0x580, 32 60 + gensym hv_confstr, 0x5a0, 32 61 + gensym hv_reexec, 0x5c0, 32 62 + gensym hv_set_command_line, 0x5e0, 32 63 + gensym hv_clear_intr, 0x600, 32 64 + gensym hv_enable_intr, 0x620, 32 65 + gensym hv_disable_intr, 0x640, 32 66 + gensym hv_raise_intr, 0x660, 32 67 + gensym hv_trigger_ipi, 0x680, 32 68 + gensym hv_store_mapping, 0x6a0, 32 69 + gensym hv_inquire_realpa, 0x6c0, 32 70 + gensym hv_flush_all, 0x6e0, 32 71 + gensym hv_get_ipi_pte, 0x700, 32 72 + gensym hv_set_pte_super_shift, 0x720, 32 73 + gensym hv_console_set_ipi, 0x7e0, 32 74 + gensym hv_glue_internals, 0x800, 30720
-59
arch/tile/kernel/hvglue.lds
··· 1 - /* Hypervisor call vector addresses; see <hv/hypervisor.h> */ 2 - hv_init = TEXT_OFFSET + 0x10020; 3 - hv_install_context = TEXT_OFFSET + 0x10040; 4 - hv_sysconf = TEXT_OFFSET + 0x10060; 5 - hv_get_rtc = TEXT_OFFSET + 0x10080; 6 - hv_set_rtc = TEXT_OFFSET + 0x100a0; 7 - hv_flush_asid = TEXT_OFFSET + 0x100c0; 8 - hv_flush_page = TEXT_OFFSET + 0x100e0; 9 - hv_flush_pages = TEXT_OFFSET + 0x10100; 10 - hv_restart = TEXT_OFFSET + 0x10120; 11 - hv_halt = TEXT_OFFSET + 0x10140; 12 - hv_power_off = TEXT_OFFSET + 0x10160; 13 - hv_inquire_physical = TEXT_OFFSET + 0x10180; 14 - hv_inquire_memory_controller = TEXT_OFFSET + 0x101a0; 15 - hv_inquire_virtual = TEXT_OFFSET + 0x101c0; 16 - hv_inquire_asid = TEXT_OFFSET + 0x101e0; 17 - hv_nanosleep = TEXT_OFFSET + 0x10200; 18 - hv_console_read_if_ready = TEXT_OFFSET + 0x10220; 19 - hv_console_write = TEXT_OFFSET + 0x10240; 20 - hv_downcall_dispatch = TEXT_OFFSET + 0x10260; 21 - hv_inquire_topology = TEXT_OFFSET + 0x10280; 22 - hv_fs_findfile = TEXT_OFFSET + 0x102a0; 23 - hv_fs_fstat = TEXT_OFFSET + 0x102c0; 24 - hv_fs_pread = TEXT_OFFSET + 0x102e0; 25 - hv_physaddr_read64 = TEXT_OFFSET + 0x10300; 26 - hv_physaddr_write64 = TEXT_OFFSET + 0x10320; 27 - hv_get_command_line = TEXT_OFFSET + 0x10340; 28 - hv_set_caching = TEXT_OFFSET + 0x10360; 29 - hv_bzero_page = TEXT_OFFSET + 0x10380; 30 - hv_register_message_state = TEXT_OFFSET + 0x103a0; 31 - hv_send_message = TEXT_OFFSET + 0x103c0; 32 - hv_receive_message = TEXT_OFFSET + 0x103e0; 33 - hv_inquire_context = TEXT_OFFSET + 0x10400; 34 - hv_start_all_tiles = TEXT_OFFSET + 0x10420; 35 - hv_dev_open = TEXT_OFFSET + 0x10440; 36 - hv_dev_close = TEXT_OFFSET + 0x10460; 37 - hv_dev_pread = TEXT_OFFSET + 0x10480; 38 - hv_dev_pwrite = TEXT_OFFSET + 0x104a0; 39 - hv_dev_poll = TEXT_OFFSET + 0x104c0; 40 - hv_dev_poll_cancel = TEXT_OFFSET + 0x104e0; 41 - hv_dev_preada = TEXT_OFFSET + 0x10500; 42 - hv_dev_pwritea = TEXT_OFFSET + 0x10520; 43 - hv_flush_remote = TEXT_OFFSET + 0x10540; 44 - hv_console_putc = TEXT_OFFSET + 0x10560; 45 - hv_inquire_tiles = TEXT_OFFSET + 0x10580; 46 - hv_confstr = TEXT_OFFSET + 0x105a0; 47 - hv_reexec = TEXT_OFFSET + 0x105c0; 48 - hv_set_command_line = TEXT_OFFSET + 0x105e0; 49 - hv_clear_intr = TEXT_OFFSET + 0x10600; 50 - hv_enable_intr = TEXT_OFFSET + 0x10620; 51 - hv_disable_intr = TEXT_OFFSET + 0x10640; 52 - hv_raise_intr = TEXT_OFFSET + 0x10660; 53 - hv_trigger_ipi = TEXT_OFFSET + 0x10680; 54 - hv_store_mapping = TEXT_OFFSET + 0x106a0; 55 - hv_inquire_realpa = TEXT_OFFSET + 0x106c0; 56 - hv_flush_all = TEXT_OFFSET + 0x106e0; 57 - hv_get_ipi_pte = TEXT_OFFSET + 0x10700; 58 - hv_set_pte_super_shift = TEXT_OFFSET + 0x10720; 59 - hv_glue_internals = TEXT_OFFSET + 0x10740;
+266
arch/tile/kernel/hvglue_trace.c
··· 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. */ 187 + HV_WRAP4(void, hv_init, HV_VersionNumber, interface_version_number, 188 + int, chip_num, int, chip_rev_num, int, client_pl) 189 + HV_WRAP1(long, hv_sysconf, HV_SysconfQuery, query) 190 + HV_WRAP3(int, hv_confstr, HV_ConfstrQuery, query, HV_VirtAddr, buf, int, len) 191 + #if CHIP_HAS_IPI() 192 + HV_WRAP3(int, hv_get_ipi_pte, HV_Coord, tile, int, pl, HV_PTE*, pte) 193 + HV_WRAP3(int, hv_console_set_ipi, int, ipi, int, event, HV_Coord, coord); 194 + #else 195 + HV_WRAP1(void, hv_enable_intr, HV_IntrMask, enab_mask) 196 + HV_WRAP1(void, hv_disable_intr, HV_IntrMask, disab_mask) 197 + HV_WRAP1(void, hv_clear_intr, HV_IntrMask, clear_mask) 198 + HV_WRAP1(void, hv_raise_intr, HV_IntrMask, raise_mask) 199 + HV_WRAP2(HV_Errno, hv_trigger_ipi, HV_Coord, tile, int, interrupt) 200 + #endif /* !CHIP_HAS_IPI() */ 201 + HV_WRAP3(int, hv_store_mapping, HV_VirtAddr, va, unsigned int, len, 202 + HV_PhysAddr, pa) 203 + HV_WRAP2(HV_PhysAddr, hv_inquire_realpa, HV_PhysAddr, cpa, unsigned int, len) 204 + HV_WRAP0(HV_RTCTime, hv_get_rtc) 205 + HV_WRAP1(void, hv_set_rtc, HV_RTCTime, time) 206 + HV_WRAP4(int, hv_install_context, HV_PhysAddr, page_table, HV_PTE, access, 207 + HV_ASID, asid, __hv32, flags) 208 + HV_WRAP2(int, hv_set_pte_super_shift, int, level, int, log2_count) 209 + HV_WRAP0(HV_Context, hv_inquire_context) 210 + HV_WRAP1(int, hv_flush_asid, HV_ASID, asid) 211 + HV_WRAP2(int, hv_flush_page, HV_VirtAddr, address, HV_PageSize, page_size) 212 + HV_WRAP3(int, hv_flush_pages, HV_VirtAddr, start, HV_PageSize, page_size, 213 + unsigned long, size) 214 + HV_WRAP1(int, hv_flush_all, int, preserve_global) 215 + HV_WRAP2(void, hv_restart, HV_VirtAddr, cmd, HV_VirtAddr, args) 216 + HV_WRAP0(void, hv_halt) 217 + HV_WRAP0(void, hv_power_off) 218 + HV_WRAP1(int, hv_reexec, HV_PhysAddr, entry) 219 + HV_WRAP0(HV_Topology, hv_inquire_topology) 220 + HV_WRAP3(HV_Errno, hv_inquire_tiles, HV_InqTileSet, set, HV_VirtAddr, cpumask, 221 + int, length) 222 + HV_WRAP1(HV_PhysAddrRange, hv_inquire_physical, int, idx) 223 + HV_WRAP2(HV_MemoryControllerInfo, hv_inquire_memory_controller, HV_Coord, coord, 224 + int, controller) 225 + HV_WRAP1(HV_VirtAddrRange, hv_inquire_virtual, int, idx) 226 + HV_WRAP1(HV_ASIDRange, hv_inquire_asid, int, idx) 227 + HV_WRAP1(void, hv_nanosleep, int, nanosecs) 228 + HV_WRAP0(int, hv_console_read_if_ready) 229 + HV_WRAP1(void, hv_console_putc, int, byte) 230 + HV_WRAP2(int, hv_console_write, HV_VirtAddr, bytes, int, len) 231 + HV_WRAP0(void, hv_downcall_dispatch) 232 + HV_WRAP1(int, hv_fs_findfile, HV_VirtAddr, filename) 233 + HV_WRAP1(HV_FS_StatInfo, hv_fs_fstat, int, inode) 234 + HV_WRAP4(int, hv_fs_pread, int, inode, HV_VirtAddr, buf, 235 + int, length, int, offset) 236 + HV_WRAP2(unsigned long long, hv_physaddr_read64, HV_PhysAddr, addr, 237 + HV_PTE, access) 238 + HV_WRAP3(void, hv_physaddr_write64, HV_PhysAddr, addr, HV_PTE, access, 239 + unsigned long long, val) 240 + HV_WRAP2(int, hv_get_command_line, HV_VirtAddr, buf, int, length) 241 + HV_WRAP2(HV_Errno, hv_set_command_line, HV_VirtAddr, buf, int, length) 242 + HV_WRAP1(void, hv_set_caching, unsigned long, bitmask) 243 + HV_WRAP2(void, hv_bzero_page, HV_VirtAddr, va, unsigned int, size) 244 + HV_WRAP1(HV_Errno, hv_register_message_state, HV_MsgState*, msgstate) 245 + HV_WRAP4(int, hv_send_message, HV_Recipient *, recips, int, nrecip, 246 + HV_VirtAddr, buf, int, buflen) 247 + HV_WRAP3(HV_RcvMsgInfo, hv_receive_message, HV_MsgState, msgstate, 248 + HV_VirtAddr, buf, int, buflen) 249 + HV_WRAP0(void, hv_start_all_tiles) 250 + HV_WRAP2(int, hv_dev_open, HV_VirtAddr, name, __hv32, flags) 251 + HV_WRAP1(int, hv_dev_close, int, devhdl) 252 + HV_WRAP5(int, hv_dev_pread, int, devhdl, __hv32, flags, HV_VirtAddr, va, 253 + __hv32, len, __hv64, offset) 254 + HV_WRAP5(int, hv_dev_pwrite, int, devhdl, __hv32, flags, HV_VirtAddr, va, 255 + __hv32, len, __hv64, offset) 256 + HV_WRAP3(int, hv_dev_poll, int, devhdl, __hv32, events, HV_IntArg, intarg) 257 + HV_WRAP1(int, hv_dev_poll_cancel, int, devhdl) 258 + HV_WRAP6(int, hv_dev_preada, int, devhdl, __hv32, flags, __hv32, sgl_len, 259 + HV_SGL *, sglp, __hv64, offset, HV_IntArg, intarg) 260 + HV_WRAP6(int, hv_dev_pwritea, int, devhdl, __hv32, flags, __hv32, sgl_len, 261 + HV_SGL *, sglp, __hv64, offset, HV_IntArg, intarg) 262 + HV_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)
+33 -81
arch/tile/kernel/intvec_32.S
··· 28 28 #include <arch/interrupts.h> 29 29 #include <arch/spr_def.h> 30 30 31 - #ifdef CONFIG_PREEMPT 32 - # error "No support for kernel preemption currently" 33 - #endif 34 - 35 31 #define PTREGS_PTR(reg, ptreg) addli reg, sp, C_ABI_SAVE_AREA_SIZE + (ptreg) 36 32 37 33 #define PTREGS_OFFSET_SYSCALL PTREGS_OFFSET_REG(TREG_SYSCALL_NR) 38 - 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 34 45 35 .macro push_reg reg, ptr=sp, delta=-4 46 36 { ··· 179 189 * point sp at the top aligned address on the actual stack page. 180 190 */ 181 191 mfspr r0, SPR_SYSTEM_SAVE_K_0 182 - mm r0, r0, zero, LOG2_THREAD_SIZE, 31 192 + mm r0, r0, zero, LOG2_NR_CPU_IDS, 31 183 193 184 194 0: 185 195 /* ··· 197 207 * cache line 1: r14...r29 198 208 * cache line 0: 2 x frame, r0..r13 199 209 */ 210 + #if STACK_TOP_DELTA != 64 211 + #error STACK_TOP_DELTA must be 64 for assumptions here and in task_pt_regs() 212 + #endif 200 213 andi r0, r0, -64 201 214 202 215 /* ··· 319 326 movei r3, -1 /* not used, but set for consistency */ 320 327 } 321 328 .else 322 - #if CHIP_HAS_AUX_PERF_COUNTERS() 323 329 .ifc \c_routine, op_handle_aux_perf_interrupt 324 330 { 325 331 mfspr r2, AUX_PERF_COUNT_STS 326 332 movei r3, -1 /* not used, but set for consistency */ 327 333 } 328 334 .else 329 - #endif 330 335 movei r3, 0 331 - #if CHIP_HAS_AUX_PERF_COUNTERS() 332 336 .endif 333 - #endif 334 337 .endif 335 338 .endif 336 339 .endif ··· 343 354 #ifdef __COLLECT_LINKER_FEEDBACK__ 344 355 .pushsection .text.intvec_feedback,"ax" 345 356 .org (\vecnum << 5) 346 - FEEDBACK_ENTER_EXPLICIT(intvec_\vecname, .intrpt1, 1 << 8) 357 + FEEDBACK_ENTER_EXPLICIT(intvec_\vecname, .intrpt, 1 << 8) 347 358 jrp lr 348 359 .popsection 349 360 #endif ··· 457 468 } 458 469 { 459 470 auli r21, r21, ha16(__per_cpu_offset) 460 - mm r20, r20, zero, 0, LOG2_THREAD_SIZE-1 471 + mm r20, r20, zero, 0, LOG2_NR_CPU_IDS-1 461 472 } 462 473 s2a r20, r20, r21 463 474 lw tp, r20 ··· 551 562 .endif 552 563 mtspr INTERRUPT_CRITICAL_SECTION, zero 553 564 554 - #if CHIP_HAS_WH64() 555 565 /* 556 566 * Prepare the first 256 stack bytes to be rapidly accessible 557 567 * without having to fetch the background data. We don't really ··· 571 583 addi r52, r52, -64 572 584 } 573 585 wh64 r52 574 - #endif 575 586 576 587 #ifdef CONFIG_TRACE_IRQFLAGS 577 588 .ifnc \function,handle_nmi ··· 749 762 .macro dc_dispatch vecnum, vecname 750 763 .org (\vecnum << 8) 751 764 intvec_\vecname: 752 - j hv_downcall_dispatch 765 + j _hv_downcall_dispatch 753 766 ENDPROC(intvec_\vecname) 754 767 .endm 755 768 ··· 799 812 } 800 813 lw r29, r29 801 814 andi r29, r29, SPR_EX_CONTEXT_1_1__PL_MASK /* mask off ICS */ 815 + bzt r29, .Lresume_userspace 816 + 817 + #ifdef CONFIG_PREEMPT 818 + /* Returning to kernel space. Check if we need preemption. */ 819 + GET_THREAD_INFO(r29) 820 + addli r28, r29, THREAD_INFO_FLAGS_OFFSET 802 821 { 803 - bzt r29, .Lresume_userspace 804 - PTREGS_PTR(r29, PTREGS_OFFSET_PC) 822 + lw r28, r28 823 + addli r29, r29, THREAD_INFO_PREEMPT_COUNT_OFFSET 805 824 } 825 + { 826 + andi r28, r28, _TIF_NEED_RESCHED 827 + lw r29, r29 828 + } 829 + bzt r28, 1f 830 + bnz r29, 1f 831 + jal preempt_schedule_irq 832 + FEEDBACK_REENTER(interrupt_return) 833 + 1: 834 + #endif 806 835 807 836 /* If we're resuming to _cpu_idle_nap, bump PC forward by 8. */ 808 837 { 809 - lw r28, r29 838 + PTREGS_PTR(r29, PTREGS_OFFSET_PC) 810 839 moveli r27, lo16(_cpu_idle_nap) 811 840 } 812 841 { 842 + lw r28, r29 813 843 auli r27, r27, ha16(_cpu_idle_nap) 814 844 } 815 845 { ··· 1424 1420 { 1425 1421 lw r0, r0 /* indirect thru thread_info to get task_info*/ 1426 1422 addi r1, sp, C_ABI_SAVE_AREA_SIZE /* put ptregs pointer into r1 */ 1427 - move r2, zero /* load error code into r2 */ 1428 1423 } 1429 1424 1430 1425 jal send_sigtrap /* issue a SIGTRAP */ ··· 1521 1518 __HEAD 1522 1519 .align 64 1523 1520 /* Align much later jump on the start of a cache line. */ 1524 - #if !ATOMIC_LOCKS_FOUND_VIA_TABLE() 1525 1521 nop 1526 1522 #if PAGE_SIZE >= 0x10000 1527 1523 nop 1528 - #endif 1529 1524 #endif 1530 1525 ENTRY(sys_cmpxchg) 1531 1526 ··· 1558 1557 # error Code here assumes PAGE_OFFSET can be loaded with just hi16() 1559 1558 #endif 1560 1559 1561 - #if ATOMIC_LOCKS_FOUND_VIA_TABLE() 1562 - { 1563 - /* Check for unaligned input. */ 1564 - bnz sp, .Lcmpxchg_badaddr 1565 - mm r25, r0, zero, 3, PAGE_SHIFT-1 1566 - } 1567 - { 1568 - crc32_32 r25, zero, r25 1569 - moveli r21, lo16(atomic_lock_ptr) 1570 - } 1571 - { 1572 - auli r21, r21, ha16(atomic_lock_ptr) 1573 - auli r23, zero, hi16(PAGE_OFFSET) /* hugepage-aligned */ 1574 - } 1575 - { 1576 - shri r20, r25, 32 - ATOMIC_HASH_L1_SHIFT 1577 - slt_u r23, r0, r23 1578 - lw r26, r0 /* see comment in the "#else" for the "lw r26". */ 1579 - } 1580 - { 1581 - s2a r21, r20, r21 1582 - bbns r23, .Lcmpxchg_badaddr 1583 - } 1584 - { 1585 - lw r21, r21 1586 - seqi r23, TREG_SYSCALL_NR_NAME, __NR_FAST_cmpxchg64 1587 - andi r25, r25, ATOMIC_HASH_L2_SIZE - 1 1588 - } 1589 - { 1590 - /* Branch away at this point if we're doing a 64-bit cmpxchg. */ 1591 - bbs r23, .Lcmpxchg64 1592 - andi r23, r0, 7 /* Precompute alignment for cmpxchg64. */ 1593 - } 1594 - { 1595 - s2a ATOMIC_LOCK_REG_NAME, r25, r21 1596 - j .Lcmpxchg32_tns /* see comment in the #else for the jump. */ 1597 - } 1598 - 1599 - #else /* ATOMIC_LOCKS_FOUND_VIA_TABLE() */ 1600 1560 { 1601 1561 /* Check for unaligned input. */ 1602 1562 bnz sp, .Lcmpxchg_badaddr ··· 1571 1609 * Because of C pointer arithmetic, we want to compute this: 1572 1610 * 1573 1611 * ((char*)atomic_locks + 1574 - * (((r0 >> 3) & (1 << (ATOMIC_HASH_SIZE - 1))) << 2)) 1612 + * (((r0 >> 3) & ((1 << ATOMIC_HASH_SHIFT) - 1)) << 2)) 1575 1613 * 1576 1614 * Instead of two shifts we just ">> 1", and use 'mm' 1577 1615 * to ignore the low and high bits we don't want. ··· 1582 1620 1583 1621 /* 1584 1622 * Ensure that the TLB is loaded before we take out the lock. 1585 - * On tilepro, this will start fetching the value all the way 1586 - * into our L1 as well (and if it gets modified before we 1587 - * grab the lock, it will be invalidated from our cache 1588 - * before we reload it). On tile64, we'll start fetching it 1589 - * into our L1 if we're the home, and if we're not, we'll 1590 - * still at least start fetching it into the home's L2. 1623 + * This will start fetching the value all the way into our L1 1624 + * as well (and if it gets modified before we grab the lock, 1625 + * it will be invalidated from our cache before we reload it). 1591 1626 */ 1592 1627 lw r26, r0 1593 1628 } ··· 1626 1667 */ 1627 1668 j .Lcmpxchg32_tns 1628 1669 } 1629 - 1630 - #endif /* ATOMIC_LOCKS_FOUND_VIA_TABLE() */ 1631 1670 1632 1671 /* Symbol for do_page_fault_ics() to use to compare against the PC. */ 1633 1672 .global __sys_cmpxchg_grab_lock ··· 1764 1807 .align 64 1765 1808 .Lcmpxchg64: 1766 1809 { 1767 - #if ATOMIC_LOCKS_FOUND_VIA_TABLE() 1768 - s2a ATOMIC_LOCK_REG_NAME, r25, r21 1769 - #endif 1770 1810 bzt r23, .Lcmpxchg64_tns 1771 1811 } 1772 1812 j .Lcmpxchg_badaddr ··· 1829 1875 push_extra_callee_saves r0 1830 1876 j do_trap 1831 1877 1832 - /* Include .intrpt1 array of interrupt vectors */ 1833 - .section ".intrpt1", "ax" 1878 + /* Include .intrpt array of interrupt vectors */ 1879 + .section ".intrpt", "ax" 1834 1880 1835 1881 #define op_handle_perf_interrupt bad_intr 1836 1882 #define op_handle_aux_perf_interrupt bad_intr ··· 1898 1944 do_page_fault 1899 1945 int_hand INT_SN_CPL, SN_CPL, bad_intr 1900 1946 int_hand INT_DOUBLE_FAULT, DOUBLE_FAULT, do_trap 1901 - #if CHIP_HAS_AUX_PERF_COUNTERS() 1902 1947 int_hand INT_AUX_PERF_COUNT, AUX_PERF_COUNT, \ 1903 1948 op_handle_aux_perf_interrupt, handle_nmi 1904 - #endif 1905 1949 1906 1950 /* Synthetic interrupt delivered only by the simulator */ 1907 1951 int_hand INT_BREAKPOINT, BREAKPOINT, do_breakpoint
+275 -30
arch/tile/kernel/intvec_64.S
··· 17 17 #include <linux/linkage.h> 18 18 #include <linux/errno.h> 19 19 #include <linux/unistd.h> 20 + #include <linux/init.h> 20 21 #include <asm/ptrace.h> 21 22 #include <asm/thread_info.h> 22 23 #include <asm/irqflags.h> 23 24 #include <asm/asm-offsets.h> 24 25 #include <asm/types.h> 26 + #include <asm/traps.h> 25 27 #include <asm/signal.h> 26 28 #include <hv/hypervisor.h> 27 29 #include <arch/abi.h> 28 30 #include <arch/interrupts.h> 29 31 #include <arch/spr_def.h> 30 32 31 - #ifdef CONFIG_PREEMPT 32 - # error "No support for kernel preemption currently" 33 - #endif 34 - 35 33 #define PTREGS_PTR(reg, ptreg) addli reg, sp, C_ABI_SAVE_AREA_SIZE + (ptreg) 36 34 37 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 48 .macro push_reg reg, ptr=sp, delta=-8 41 49 { ··· 106 98 } 107 99 .endm 108 100 101 + /* 102 + * Unalign data exception fast handling: In order to handle 103 + * unaligned data access, a fast JIT version is generated and stored 104 + * in a specific area in user space. We first need to do a quick poke 105 + * to see if the JIT is available. We use certain bits in the fault 106 + * PC (3 to 9 is used for 16KB page size) as index to address the JIT 107 + * code area. The first 64bit word is the fault PC, and the 2nd one is 108 + * the fault bundle itself. If these 2 words both match, then we 109 + * directly "iret" to JIT code. If not, a slow path is invoked to 110 + * generate new JIT code. Note: the current JIT code WILL be 111 + * overwritten if it existed. So, ideally we can handle 128 unalign 112 + * fixups via JIT. For lookup efficiency and to effectively support 113 + * tight loops with multiple unaligned reference, a simple 114 + * direct-mapped cache is used. 115 + * 116 + * SPR_EX_CONTEXT_K_0 is modified to return to JIT code. 117 + * SPR_EX_CONTEXT_K_1 has ICS set. 118 + * SPR_EX_CONTEXT_0_0 is setup to user program's next PC. 119 + * SPR_EX_CONTEXT_0_1 = 0. 120 + */ 121 + .macro int_hand_unalign_fast vecnum, vecname 122 + .org (\vecnum << 8) 123 + intvec_\vecname: 124 + /* Put r3 in SPR_SYSTEM_SAVE_K_1. */ 125 + mtspr SPR_SYSTEM_SAVE_K_1, r3 126 + 127 + mfspr r3, SPR_EX_CONTEXT_K_1 128 + /* 129 + * Examine if exception comes from user without ICS set. 130 + * If not, just go directly to the slow path. 131 + */ 132 + bnez r3, hand_unalign_slow_nonuser 133 + 134 + mfspr r3, SPR_SYSTEM_SAVE_K_0 135 + 136 + /* Get &thread_info->unalign_jit_tmp[0] in r3. */ 137 + bfexts r3, r3, 0, CPU_SHIFT-1 138 + mm r3, zero, LOG2_THREAD_SIZE, 63 139 + addli r3, r3, THREAD_INFO_UNALIGN_JIT_TMP_OFFSET 140 + 141 + /* 142 + * Save r0, r1, r2 into thread_info array r3 points to 143 + * from low to high memory in order. 144 + */ 145 + st_add r3, r0, 8 146 + st_add r3, r1, 8 147 + { 148 + st_add r3, r2, 8 149 + andi r2, sp, 7 150 + } 151 + 152 + /* Save stored r3 value so we can revert it on a page fault. */ 153 + mfspr r1, SPR_SYSTEM_SAVE_K_1 154 + st r3, r1 155 + 156 + { 157 + /* Generate a SIGBUS if sp is not 8-byte aligned. */ 158 + bnez r2, hand_unalign_slow_badsp 159 + } 160 + 161 + /* 162 + * Get the thread_info in r0; load r1 with pc. Set the low bit of sp 163 + * as an indicator to the page fault code in case we fault. 164 + */ 165 + { 166 + ori sp, sp, 1 167 + mfspr r1, SPR_EX_CONTEXT_K_0 168 + } 169 + 170 + /* Add the jit_info offset in thread_info; extract r1 [3:9] into r2. */ 171 + { 172 + addli r0, r3, THREAD_INFO_UNALIGN_JIT_BASE_OFFSET - \ 173 + (THREAD_INFO_UNALIGN_JIT_TMP_OFFSET + (3 * 8)) 174 + bfextu r2, r1, 3, (2 + PAGE_SHIFT - UNALIGN_JIT_SHIFT) 175 + } 176 + 177 + /* Load the jit_info; multiply r2 by 128. */ 178 + { 179 + ld r0, r0 180 + shli r2, r2, UNALIGN_JIT_SHIFT 181 + } 182 + 183 + /* 184 + * If r0 is NULL, the JIT page is not mapped, so go to slow path; 185 + * add offset r2 to r0 at the same time. 186 + */ 187 + { 188 + beqz r0, hand_unalign_slow 189 + add r2, r0, r2 190 + } 191 + 192 + /* 193 + * We are loading from userspace (both the JIT info PC and 194 + * instruction word, and the instruction word we executed) 195 + * and since either could fault while holding the interrupt 196 + * critical section, we must tag this region and check it in 197 + * do_page_fault() to handle it properly. 198 + */ 199 + ENTRY(__start_unalign_asm_code) 200 + 201 + /* Load first word of JIT in r0 and increment r2 by 8. */ 202 + ld_add r0, r2, 8 203 + 204 + /* 205 + * Compare the PC with the 1st word in JIT; load the fault bundle 206 + * into r1. 207 + */ 208 + { 209 + cmpeq r0, r0, r1 210 + ld r1, r1 211 + } 212 + 213 + /* Go to slow path if PC doesn't match. */ 214 + beqz r0, hand_unalign_slow 215 + 216 + /* 217 + * Load the 2nd word of JIT, which is supposed to be the fault 218 + * bundle for a cache hit. Increment r2; after this bundle r2 will 219 + * point to the potential start of the JIT code we want to run. 220 + */ 221 + ld_add r0, r2, 8 222 + 223 + /* No further accesses to userspace are done after this point. */ 224 + ENTRY(__end_unalign_asm_code) 225 + 226 + /* Compare the real bundle with what is saved in the JIT area. */ 227 + { 228 + cmpeq r0, r1, r0 229 + mtspr SPR_EX_CONTEXT_0_1, zero 230 + } 231 + 232 + /* Go to slow path if the fault bundle does not match. */ 233 + beqz r0, hand_unalign_slow 234 + 235 + /* 236 + * A cache hit is found. 237 + * r2 points to start of JIT code (3rd word). 238 + * r0 is the fault pc. 239 + * r1 is the fault bundle. 240 + * Reset the low bit of sp. 241 + */ 242 + { 243 + mfspr r0, SPR_EX_CONTEXT_K_0 244 + andi sp, sp, ~1 245 + } 246 + 247 + /* Write r2 into EX_CONTEXT_K_0 and increment PC. */ 248 + { 249 + mtspr SPR_EX_CONTEXT_K_0, r2 250 + addi r0, r0, 8 251 + } 252 + 253 + /* 254 + * Set ICS on kernel EX_CONTEXT_K_1 in order to "iret" to 255 + * user with ICS set. This way, if the JIT fixup causes another 256 + * unalign exception (which shouldn't be possible) the user 257 + * process will be terminated with SIGBUS. Also, our fixup will 258 + * run without interleaving with external interrupts. 259 + * Each fixup is at most 14 bundles, so it won't hold ICS for long. 260 + */ 261 + { 262 + movei r1, PL_ICS_EX1(USER_PL, 1) 263 + mtspr SPR_EX_CONTEXT_0_0, r0 264 + } 265 + 266 + { 267 + mtspr SPR_EX_CONTEXT_K_1, r1 268 + addi r3, r3, -(3 * 8) 269 + } 270 + 271 + /* Restore r0..r3. */ 272 + ld_add r0, r3, 8 273 + ld_add r1, r3, 8 274 + ld_add r2, r3, 8 275 + ld r3, r3 276 + 277 + iret 278 + ENDPROC(intvec_\vecname) 279 + .endm 109 280 110 281 #ifdef __COLLECT_LINKER_FEEDBACK__ 111 282 .pushsection .text.intvec_feedback,"ax" ··· 305 118 * The "processing" argument specifies the code for processing 306 119 * the interrupt. Defaults to "handle_interrupt". 307 120 */ 308 - .macro int_hand vecnum, vecname, c_routine, processing=handle_interrupt 309 - .org (\vecnum << 8) 121 + .macro __int_hand vecnum, vecname, c_routine,processing=handle_interrupt 310 122 intvec_\vecname: 311 123 /* Temporarily save a register so we have somewhere to work. */ 312 124 313 125 mtspr SPR_SYSTEM_SAVE_K_1, r0 314 126 mfspr r0, SPR_EX_CONTEXT_K_1 315 127 316 - andi r0, r0, SPR_EX_CONTEXT_1_1__PL_MASK /* mask off ICS */ 128 + /* 129 + * The unalign data fastpath code sets the low bit in sp to 130 + * force us to reset it here on fault. 131 + */ 132 + { 133 + blbs sp, 2f 134 + IS_KERNEL_EX1(r0, r0) 135 + } 317 136 318 137 .ifc \vecnum, INT_DOUBLE_FAULT 319 138 /* ··· 369 176 } 370 177 .endif 371 178 372 - 179 + 2: 373 180 /* 374 - * SYSTEM_SAVE_K_0 holds the cpu number in the low bits, and 375 - * the current stack top in the higher bits. So we recover 376 - * our stack top by just masking off the low bits, then 181 + * SYSTEM_SAVE_K_0 holds the cpu number in the high bits, and 182 + * the current stack top in the lower bits. So we recover 183 + * our starting stack value by sign-extending the low bits, then 377 184 * point sp at the top aligned address on the actual stack page. 378 185 */ 379 186 mfspr r0, SPR_SYSTEM_SAVE_K_0 380 - mm r0, zero, LOG2_THREAD_SIZE, 63 187 + bfexts r0, r0, 0, CPU_SHIFT-1 381 188 382 189 0: 383 190 /* ··· 399 206 * cache line 1: r6...r13 400 207 * cache line 0: 2 x frame, r0..r5 401 208 */ 209 + #if STACK_TOP_DELTA != 64 210 + #error STACK_TOP_DELTA must be 64 for assumptions here and in task_pt_regs() 211 + #endif 402 212 andi r0, r0, -64 403 213 404 214 /* ··· 501 305 mfspr r3, SPR_SYSTEM_SAVE_K_2 /* info about page fault */ 502 306 .else 503 307 .ifc \vecnum, INT_ILL_TRANS 504 - mfspr r2, ILL_TRANS_REASON 308 + mfspr r2, ILL_VA_PC 505 309 .else 506 310 .ifc \vecnum, INT_DOUBLE_FAULT 507 311 mfspr r2, SPR_SYSTEM_SAVE_K_2 /* double fault info from HV */ ··· 511 315 .else 512 316 .ifc \c_routine, op_handle_perf_interrupt 513 317 mfspr r2, PERF_COUNT_STS 514 - #if CHIP_HAS_AUX_PERF_COUNTERS() 515 318 .else 516 319 .ifc \c_routine, op_handle_aux_perf_interrupt 517 320 mfspr r2, AUX_PERF_COUNT_STS 518 321 .endif 519 - #endif 520 322 .endif 521 323 .endif 522 324 .endif ··· 533 339 #ifdef __COLLECT_LINKER_FEEDBACK__ 534 340 .pushsection .text.intvec_feedback,"ax" 535 341 .org (\vecnum << 5) 536 - FEEDBACK_ENTER_EXPLICIT(intvec_\vecname, .intrpt1, 1 << 8) 342 + FEEDBACK_ENTER_EXPLICIT(intvec_\vecname, .intrpt, 1 << 8) 537 343 jrp lr 538 344 .popsection 539 345 #endif ··· 649 455 /* 650 456 * If we will be returning to the kernel, we will need to 651 457 * reset the interrupt masks to the state they had before. 652 - * Set DISABLE_IRQ in flags iff we came from PL1 with irqs disabled. 458 + * Set DISABLE_IRQ in flags iff we came from kernel pl with 459 + * irqs disabled. 653 460 */ 654 461 mfspr r32, SPR_EX_CONTEXT_K_1 655 462 { 656 - andi r32, r32, SPR_EX_CONTEXT_1_1__PL_MASK /* mask off ICS */ 463 + IS_KERNEL_EX1(r22, r22) 657 464 PTREGS_PTR(r21, PTREGS_OFFSET_FLAGS) 658 465 } 659 466 beqzt r32, 1f /* zero if from user space */ ··· 698 503 } 699 504 { 700 505 shl16insli r21, r21, hw1(__per_cpu_offset) 701 - bfextu r20, r20, 0, LOG2_THREAD_SIZE-1 506 + bfextu r20, r20, CPU_SHIFT, 63 702 507 } 703 508 shl16insli r21, r21, hw0(__per_cpu_offset) 704 509 shl3add r20, r20, r21 ··· 780 585 .macro dc_dispatch vecnum, vecname 781 586 .org (\vecnum << 8) 782 587 intvec_\vecname: 783 - j hv_downcall_dispatch 588 + j _hv_downcall_dispatch 784 589 ENDPROC(intvec_\vecname) 785 590 .endm 786 591 ··· 821 626 PTREGS_PTR(r29, PTREGS_OFFSET_EX1) 822 627 } 823 628 ld r29, r29 824 - andi r29, r29, SPR_EX_CONTEXT_1_1__PL_MASK /* mask off ICS */ 629 + IS_KERNEL_EX1(r29, r29) 825 630 { 826 631 beqzt r29, .Lresume_userspace 827 - PTREGS_PTR(r29, PTREGS_OFFSET_PC) 632 + move r29, sp 828 633 } 829 634 635 + #ifdef CONFIG_PREEMPT 636 + /* Returning to kernel space. Check if we need preemption. */ 637 + EXTRACT_THREAD_INFO(r29) 638 + addli r28, r29, THREAD_INFO_FLAGS_OFFSET 639 + { 640 + ld r28, r28 641 + addli r29, r29, THREAD_INFO_PREEMPT_COUNT_OFFSET 642 + } 643 + { 644 + andi r28, r28, _TIF_NEED_RESCHED 645 + ld4s r29, r29 646 + } 647 + beqzt r28, 1f 648 + bnez r29, 1f 649 + jal preempt_schedule_irq 650 + FEEDBACK_REENTER(interrupt_return) 651 + 1: 652 + #endif 653 + 830 654 /* If we're resuming to _cpu_idle_nap, bump PC forward by 8. */ 831 - moveli r27, hw2_last(_cpu_idle_nap) 655 + { 656 + moveli r27, hw2_last(_cpu_idle_nap) 657 + PTREGS_PTR(r29, PTREGS_OFFSET_PC) 658 + } 832 659 { 833 660 ld r28, r29 834 661 shl16insli r27, r27, hw1(_cpu_idle_nap) ··· 945 728 PTREGS_PTR(r32, PTREGS_OFFSET_FLAGS) 946 729 } 947 730 { 948 - andi r0, r0, SPR_EX_CONTEXT_1_1__PL_MASK 731 + IS_KERNEL_EX1(r0, r0) 949 732 ld r32, r32 950 733 } 951 734 bnez r0, 1f ··· 1016 799 pop_reg r21, sp, PTREGS_OFFSET_REG(31) - PTREGS_OFFSET_PC 1017 800 { 1018 801 mtspr SPR_EX_CONTEXT_K_1, lr 1019 - andi lr, lr, SPR_EX_CONTEXT_1_1__PL_MASK /* mask off ICS */ 802 + IS_KERNEL_EX1(lr, lr) 1020 803 } 1021 804 { 1022 805 mtspr SPR_EX_CONTEXT_K_0, r21 ··· 1440 1223 j sys_clone 1441 1224 STD_ENDPROC(_sys_clone) 1442 1225 1443 - /* The single-step support may need to read all the registers. */ 1226 + /* 1227 + * Recover r3, r2, r1 and r0 here saved by unalign fast vector. 1228 + * The vector area limit is 32 bundles, so we handle the reload here. 1229 + * r0, r1, r2 are in thread_info from low to high memory in order. 1230 + * r3 points to location the original r3 was saved. 1231 + * We put this code in the __HEAD section so it can be reached 1232 + * via a conditional branch from the fast path. 1233 + */ 1234 + __HEAD 1235 + hand_unalign_slow: 1236 + andi sp, sp, ~1 1237 + hand_unalign_slow_badsp: 1238 + addi r3, r3, -(3 * 8) 1239 + ld_add r0, r3, 8 1240 + ld_add r1, r3, 8 1241 + ld r2, r3 1242 + hand_unalign_slow_nonuser: 1243 + mfspr r3, SPR_SYSTEM_SAVE_K_1 1244 + __int_hand INT_UNALIGN_DATA, UNALIGN_DATA_SLOW, int_unalign 1245 + 1246 + /* The unaligned data support needs to read all the registers. */ 1444 1247 int_unalign: 1445 1248 push_extra_callee_saves r0 1446 - j do_trap 1249 + j do_unaligned 1250 + ENDPROC(hand_unalign_slow) 1447 1251 1448 1252 /* Fill the return address stack with nonzero entries. */ 1449 1253 STD_ENTRY(fill_ra_stack) ··· 1478 1240 4: jrp r0 1479 1241 STD_ENDPROC(fill_ra_stack) 1480 1242 1481 - /* Include .intrpt1 array of interrupt vectors */ 1482 - .section ".intrpt1", "ax" 1243 + .macro int_hand vecnum, vecname, c_routine, processing=handle_interrupt 1244 + .org (\vecnum << 8) 1245 + __int_hand \vecnum, \vecname, \c_routine, \processing 1246 + .endm 1247 + 1248 + /* Include .intrpt array of interrupt vectors */ 1249 + .section ".intrpt", "ax" 1250 + .global intrpt_start 1251 + intrpt_start: 1483 1252 1484 1253 #define op_handle_perf_interrupt bad_intr 1485 1254 #define op_handle_aux_perf_interrupt bad_intr ··· 1517 1272 int_hand INT_SWINT_1, SWINT_1, SYSCALL, handle_syscall 1518 1273 int_hand INT_SWINT_0, SWINT_0, do_trap 1519 1274 int_hand INT_ILL_TRANS, ILL_TRANS, do_trap 1520 - int_hand INT_UNALIGN_DATA, UNALIGN_DATA, int_unalign 1275 + int_hand_unalign_fast INT_UNALIGN_DATA, UNALIGN_DATA 1521 1276 int_hand INT_DTLB_MISS, DTLB_MISS, do_page_fault 1522 1277 int_hand INT_DTLB_ACCESS, DTLB_ACCESS, do_page_fault 1523 1278 int_hand INT_IDN_FIREWALL, IDN_FIREWALL, do_hardwall_trap
+5 -3
arch/tile/kernel/irq.c
··· 55 55 56 56 /* State for allocating IRQs on Gx. */ 57 57 #if CHIP_HAS_IPI() 58 - static unsigned long available_irqs = ~(1UL << IRQ_RESCHEDULE); 58 + static unsigned long available_irqs = ((1UL << NR_IRQS) - 1) & 59 + (~(1UL << IRQ_RESCHEDULE)); 59 60 static DEFINE_SPINLOCK(available_irqs_lock); 60 61 #endif 61 62 ··· 74 73 75 74 /* 76 75 * The interrupt handling path, implemented in terms of HV interrupt 77 - * emulation on TILE64 and TILEPro, and IPI hardware on TILE-Gx. 76 + * emulation on TILEPro, and IPI hardware on TILE-Gx. 77 + * Entered with interrupts disabled. 78 78 */ 79 79 void tile_dev_intr(struct pt_regs *regs, int intnum) 80 80 { ··· 235 233 { 236 234 /* 237 235 * We use handle_level_irq() by default because the pending 238 - * interrupt vector (whether modeled by the HV on TILE64 and 236 + * interrupt vector (whether modeled by the HV on 239 237 * TILEPro or implemented in hardware on TILE-Gx) has 240 238 * level-style semantics for each bit. An interrupt fires 241 239 * whenever a bit is high, not just at edges.
+499
arch/tile/kernel/kgdb.c
··· 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 + 24 + static tile_bundle_bits singlestep_insn = TILEGX_BPT_BUNDLE | DIE_SSTEPBP; 25 + static unsigned long stepped_addr; 26 + static tile_bundle_bits stepped_instr; 27 + 28 + struct 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 + 97 + char *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 + 110 + int 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 + */ 125 + void 126 + sleeping_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 + 146 + void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long pc) 147 + { 148 + regs->pc = pc; 149 + } 150 + 151 + static void kgdb_call_nmi_hook(void *ignored) 152 + { 153 + kgdb_nmicallback(raw_smp_processor_id(), NULL); 154 + } 155 + 156 + void 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 + */ 166 + static 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 + */ 183 + static 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 + */ 300 + static 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 + 316 + static 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 + */ 335 + static int 336 + kgdb_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 + 376 + static 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 + */ 396 + int 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 + 437 + struct 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 + */ 445 + int 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 + */ 459 + void kgdb_arch_exit(void) 460 + { 461 + unregister_die_notifier(&kgdb_notifier); 462 + } 463 + 464 + int 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 + 485 + int 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 + }
+528
arch/tile/kernel/kprobes.c
··· 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 + 33 + DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL; 34 + DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); 35 + 36 + tile_bundle_bits breakpoint_insn = TILEGX_BPT_BUNDLE; 37 + tile_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 + */ 43 + static 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 + 85 + int __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 + 115 + void __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 + 130 + void __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 + 145 + void __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 + 153 + static 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 + 160 + static 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 + 167 + static 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 + 174 + static 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 + 184 + static 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 + 262 + ss_probe: 263 + prepare_singlestep(p, regs); 264 + kcb->kprobe_status = KPROBE_HIT_SS; 265 + return 1; 266 + 267 + no_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 + */ 282 + static 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 + 290 + static 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(); 311 + out: 312 + preempt_enable_no_resched(); 313 + 314 + return 1; 315 + } 316 + 317 + static 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 + */ 343 + int __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 + 373 + int __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. */ 390 + void jprobe_return_end(void); 391 + 392 + void __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 + 400 + int __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 + */ 422 + static 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 + 432 + void kretprobe_trampoline(void); 433 + 434 + void __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 + */ 446 + static 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 + 511 + int __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 + 519 + static struct kprobe trampoline_p = { 520 + .addr = (kprobe_opcode_t *)kretprobe_trampoline, 521 + .pre_handler = trampoline_probe_handler 522 + }; 523 + 524 + int __init arch_init_kprobes(void) 525 + { 526 + register_kprobe(&trampoline_p); 527 + return 0; 528 + }
+224
arch/tile/kernel/mcount_64.S
··· 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 73 + STD_ENTRY(__mcount) 74 + __mcount: 75 + j ftrace_stub 76 + STD_ENDPROC(__mcount) 77 + 78 + .align 64 79 + STD_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 + 87 + 1: 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 96 + ftrace_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 105 + ftrace_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 114 + ftrace_stub: 115 + RETURN_BACK 116 + STD_ENDPROC(ftrace_caller) 117 + 118 + #else /* ! CONFIG_DYNAMIC_FTRACE */ 119 + 120 + .align 64 121 + STD_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 + 129 + 1: 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 + 175 + static_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 188 + ftrace_stub: 189 + RETURN_BACK 190 + STD_ENDPROC(__mcount) 191 + 192 + #endif /* ! CONFIG_DYNAMIC_FTRACE */ 193 + 194 + #ifdef CONFIG_FUNCTION_GRAPH_TRACER 195 + 196 + STD_ENTRY(ftrace_graph_caller) 197 + ftrace_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 211 + STD_ENDPROC(ftrace_graph_caller) 212 + 213 + .global return_to_handler 214 + return_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 */
+59 -15
arch/tile/kernel/pci-dma.c
··· 36 36 dma_addr_t *dma_handle, gfp_t gfp, 37 37 struct dma_attrs *attrs) 38 38 { 39 - u64 dma_mask = dev->coherent_dma_mask ?: DMA_BIT_MASK(32); 40 - int node = dev_to_node(dev); 39 + u64 dma_mask = (dev && dev->coherent_dma_mask) ? 40 + dev->coherent_dma_mask : DMA_BIT_MASK(32); 41 + int node = dev ? dev_to_node(dev) : 0; 41 42 int order = get_order(size); 42 43 struct page *pg; 43 44 dma_addr_t addr; ··· 257 256 BUG_ON(!valid_dma_direction(direction)); 258 257 259 258 __dma_complete_page(pfn_to_page(PFN_DOWN(dma_address)), 260 - dma_address & PAGE_OFFSET, size, direction); 259 + dma_address & (PAGE_SIZE - 1), size, direction); 261 260 } 262 261 263 262 static void tile_dma_sync_single_for_cpu(struct device *dev, ··· 358 357 359 358 addr = page_to_phys(pg); 360 359 361 - *dma_handle = phys_to_dma(dev, addr); 360 + *dma_handle = addr + get_dma_offset(dev); 362 361 363 362 return page_address(pg); 364 363 } ··· 388 387 sg->dma_address = sg_phys(sg); 389 388 __dma_prep_pa_range(sg->dma_address, sg->length, direction); 390 389 391 - sg->dma_address = phys_to_dma(dev, sg->dma_address); 390 + sg->dma_address = sg->dma_address + get_dma_offset(dev); 392 391 #ifdef CONFIG_NEED_SG_DMA_LENGTH 393 392 sg->dma_length = sg->length; 394 393 #endif ··· 423 422 BUG_ON(offset + size > PAGE_SIZE); 424 423 __dma_prep_page(page, offset, size, direction); 425 424 426 - return phys_to_dma(dev, page_to_pa(page) + offset); 425 + return page_to_pa(page) + offset + get_dma_offset(dev); 427 426 } 428 427 429 428 static void tile_pci_dma_unmap_page(struct device *dev, dma_addr_t dma_address, ··· 433 432 { 434 433 BUG_ON(!valid_dma_direction(direction)); 435 434 436 - dma_address = dma_to_phys(dev, dma_address); 435 + dma_address -= get_dma_offset(dev); 437 436 438 437 __dma_complete_page(pfn_to_page(PFN_DOWN(dma_address)), 439 - dma_address & PAGE_OFFSET, size, direction); 438 + dma_address & (PAGE_SIZE - 1), size, direction); 440 439 } 441 440 442 441 static void tile_pci_dma_sync_single_for_cpu(struct device *dev, ··· 446 445 { 447 446 BUG_ON(!valid_dma_direction(direction)); 448 447 449 - dma_handle = dma_to_phys(dev, dma_handle); 448 + dma_handle -= get_dma_offset(dev); 450 449 451 450 __dma_complete_pa_range(dma_handle, size, direction); 452 451 } ··· 457 456 enum dma_data_direction 458 457 direction) 459 458 { 460 - dma_handle = dma_to_phys(dev, dma_handle); 459 + dma_handle -= get_dma_offset(dev); 461 460 462 461 __dma_prep_pa_range(dma_handle, size, direction); 463 462 } ··· 559 558 .mapping_error = swiotlb_dma_mapping_error, 560 559 }; 561 560 561 + static struct dma_map_ops pci_hybrid_dma_ops = { 562 + .alloc = tile_swiotlb_alloc_coherent, 563 + .free = tile_swiotlb_free_coherent, 564 + .map_page = tile_pci_dma_map_page, 565 + .unmap_page = tile_pci_dma_unmap_page, 566 + .map_sg = tile_pci_dma_map_sg, 567 + .unmap_sg = tile_pci_dma_unmap_sg, 568 + .sync_single_for_cpu = tile_pci_dma_sync_single_for_cpu, 569 + .sync_single_for_device = tile_pci_dma_sync_single_for_device, 570 + .sync_sg_for_cpu = tile_pci_dma_sync_sg_for_cpu, 571 + .sync_sg_for_device = tile_pci_dma_sync_sg_for_device, 572 + .mapping_error = tile_pci_dma_mapping_error, 573 + .dma_supported = tile_pci_dma_supported 574 + }; 575 + 562 576 struct dma_map_ops *gx_legacy_pci_dma_map_ops = &pci_swiotlb_dma_ops; 577 + struct dma_map_ops *gx_hybrid_pci_dma_map_ops = &pci_hybrid_dma_ops; 563 578 #else 564 579 struct dma_map_ops *gx_legacy_pci_dma_map_ops; 580 + struct dma_map_ops *gx_hybrid_pci_dma_map_ops; 565 581 #endif 566 582 EXPORT_SYMBOL(gx_legacy_pci_dma_map_ops); 583 + EXPORT_SYMBOL(gx_hybrid_pci_dma_map_ops); 567 584 568 585 #ifdef CONFIG_ARCH_HAS_DMA_SET_COHERENT_MASK 569 586 int dma_set_coherent_mask(struct device *dev, u64 mask) 570 587 { 571 588 struct dma_map_ops *dma_ops = get_dma_ops(dev); 572 589 573 - /* Handle legacy PCI devices with limited memory addressability. */ 574 - if (((dma_ops == gx_pci_dma_map_ops) || 575 - (dma_ops == gx_legacy_pci_dma_map_ops)) && 576 - (mask <= DMA_BIT_MASK(32))) { 577 - if (mask > dev->archdata.max_direct_dma_addr) 590 + /* 591 + * For PCI devices with 64-bit DMA addressing capability, promote 592 + * the dma_ops to full capability for both streams and consistent 593 + * memory access. For 32-bit capable devices, limit the consistent 594 + * memory DMA range to max_direct_dma_addr. 595 + */ 596 + if (dma_ops == gx_pci_dma_map_ops || 597 + dma_ops == gx_hybrid_pci_dma_map_ops || 598 + dma_ops == gx_legacy_pci_dma_map_ops) { 599 + if (mask == DMA_BIT_MASK(64)) 600 + set_dma_ops(dev, gx_pci_dma_map_ops); 601 + else if (mask > dev->archdata.max_direct_dma_addr) 578 602 mask = dev->archdata.max_direct_dma_addr; 579 603 } 580 604 ··· 609 583 return 0; 610 584 } 611 585 EXPORT_SYMBOL(dma_set_coherent_mask); 586 + #endif 587 + 588 + #ifdef ARCH_HAS_DMA_GET_REQUIRED_MASK 589 + /* 590 + * The generic dma_get_required_mask() uses the highest physical address 591 + * (max_pfn) to provide the hint to the PCI drivers regarding 32-bit or 592 + * 64-bit DMA configuration. Since TILEGx has I/O TLB/MMU, allowing the 593 + * DMAs to use the full 64-bit PCI address space and not limited by 594 + * the physical memory space, we always let the PCI devices use 595 + * 64-bit DMA if they have that capability, by returning the 64-bit 596 + * DMA mask here. The device driver has the option to use 32-bit DMA if 597 + * the device is not capable of 64-bit DMA. 598 + */ 599 + u64 dma_get_required_mask(struct device *dev) 600 + { 601 + return DMA_BIT_MASK(64); 602 + } 603 + EXPORT_SYMBOL_GPL(dma_get_required_mask); 612 604 #endif
+20 -13
arch/tile/kernel/pci.c
··· 20 20 #include <linux/capability.h> 21 21 #include <linux/sched.h> 22 22 #include <linux/errno.h> 23 - #include <linux/bootmem.h> 24 23 #include <linux/irq.h> 25 24 #include <linux/io.h> 26 25 #include <linux/uaccess.h> ··· 50 51 * generic Linux PCI layer. 51 52 * 52 53 */ 54 + 55 + static int pci_probe = 1; 53 56 54 57 /* 55 58 * This flag tells if the platform is TILEmpower that needs ··· 145 144 { 146 145 int i; 147 146 147 + if (!pci_probe) { 148 + pr_info("PCI: disabled by boot argument\n"); 149 + return 0; 150 + } 151 + 148 152 pr_info("PCI: Searching for controllers...\n"); 149 153 150 154 /* Re-init number of PCIe controllers to support hot-plug feature. */ ··· 198 192 controller->hv_cfg_fd[0] = hv_cfg_fd0; 199 193 controller->hv_cfg_fd[1] = hv_cfg_fd1; 200 194 controller->hv_mem_fd = hv_mem_fd; 201 - controller->first_busno = 0; 202 195 controller->last_busno = 0xff; 203 196 controller->ops = &tile_cfg_ops; 204 197 ··· 288 283 * known to require at least 20ms here, but we use a more 289 284 * conservative value. 290 285 */ 291 - mdelay(250); 286 + msleep(250); 292 287 293 288 /* Scan all of the recorded PCI controllers. */ 294 289 for (i = 0; i < TILE_NUM_PCIE; i++) { ··· 309 304 310 305 pr_info("PCI: initializing controller #%d\n", i); 311 306 312 - /* 313 - * This comes from the generic Linux PCI driver. 314 - * 315 - * It reads the PCI tree for this bus into the Linux 316 - * data structures. 317 - * 318 - * This is inlined in linux/pci.h and calls into 319 - * pci_scan_bus_parented() in probe.c. 320 - */ 321 307 pci_add_resource(&resources, &ioport_resource); 322 308 pci_add_resource(&resources, &iomem_resource); 323 - bus = pci_scan_root_bus(NULL, 0, controller->ops, controller, &resources); 309 + bus = pci_scan_root_bus(NULL, 0, controller->ops, 310 + controller, &resources); 324 311 controller->root_bus = bus; 325 312 controller->last_busno = bus->busn_res.end; 326 313 } ··· 383 386 void pcibios_set_master(struct pci_dev *dev) 384 387 { 385 388 /* No special bus mastering setup handling. */ 389 + } 390 + 391 + /* Process any "pci=" kernel boot arguments. */ 392 + char *__init pcibios_setup(char *str) 393 + { 394 + if (!strcmp(str, "off")) { 395 + pci_probe = 0; 396 + return NULL; 397 + } 398 + return str; 386 399 } 387 400 388 401 /*
+421 -320
arch/tile/kernel/pci_gx.c
··· 69 69 * a HW PCIe link-training bug. The exact delay is specified with 70 70 * a kernel boot argument in the form of "pcie_rc_delay=T,P,S", 71 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 73 - * will be DEFAULT_RC_DELAY. 72 + * the delay in seconds. If the argument is specified, but the delay is 73 + * not provided, the value will be DEFAULT_RC_DELAY. 74 74 */ 75 75 static int rc_delay[TILEGX_NUM_TRIO][TILEGX_TRIO_PCIES]; 76 76 77 77 /* Default number of seconds that the PCIe RC port probe can be delayed. */ 78 78 #define DEFAULT_RC_DELAY 10 79 79 80 - /* Max number of seconds that the PCIe RC port probe can be delayed. */ 81 - #define MAX_RC_DELAY 20 80 + /* The PCI I/O space size in each PCI domain. */ 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 93 /* Array of the PCIe ports configuration info obtained from the BIB. */ 84 - struct pcie_port_property pcie_ports[TILEGX_NUM_TRIO][TILEGX_TRIO_PCIES]; 94 + struct pcie_trio_ports_property pcie_ports[TILEGX_NUM_TRIO]; 95 + 96 + /* Number of configured TRIO instances. */ 97 + int num_trio_shims; 85 98 86 99 /* All drivers share the TRIO contexts defined here. */ 87 100 gxio_trio_context_t trio_contexts[TILEGX_NUM_TRIO]; ··· 102 89 /* Pointer to an array of PCIe RC controllers. */ 103 90 struct pci_controller pci_controllers[TILEGX_NUM_TRIO * TILEGX_TRIO_PCIES]; 104 91 int num_rc_controllers; 105 - static int num_ep_controllers; 106 92 107 93 static struct pci_ops tile_cfg_ops; 108 94 109 95 /* Mask of CPUs that should receive PCIe interrupts. */ 110 96 static struct cpumask intr_cpus_map; 111 97 112 - /* 113 - * We don't need to worry about the alignment of resources. 114 - */ 98 + /* We don't need to worry about the alignment of resources. */ 115 99 resource_size_t pcibios_align_resource(void *data, const struct resource *res, 116 - resource_size_t size, resource_size_t align) 100 + resource_size_t size, 101 + resource_size_t align) 117 102 { 118 103 return res->start; 119 104 } 120 105 EXPORT_SYMBOL(pcibios_align_resource); 121 - 122 106 123 107 /* 124 108 * Pick a CPU to receive and handle the PCIe interrupts, based on the IRQ #. ··· 144 134 return cpu; 145 135 } 146 136 147 - /* 148 - * Open a file descriptor to the TRIO shim. 149 - */ 137 + /* Open a file descriptor to the TRIO shim. */ 150 138 static int tile_pcie_open(int trio_index) 151 139 { 152 140 gxio_trio_context_t *context = &trio_contexts[trio_index]; 153 141 int ret; 142 + int mac; 154 143 155 - /* 156 - * This opens a file descriptor to the TRIO shim. 157 - */ 144 + /* This opens a file descriptor to the TRIO shim. */ 158 145 ret = gxio_trio_init(context, trio_index); 159 146 if (ret < 0) 160 - return ret; 147 + goto gxio_trio_init_failure; 161 148 162 - /* 163 - * Allocate an ASID for the kernel. 164 - */ 149 + /* Allocate an ASID for the kernel. */ 165 150 ret = gxio_trio_alloc_asids(context, 1, 0, 0); 166 151 if (ret < 0) { 167 152 pr_err("PCI: ASID alloc failure on TRIO %d, give up\n", ··· 194 189 } 195 190 #endif 196 191 192 + /* Get the properties of the PCIe ports on this TRIO instance. */ 193 + ret = gxio_trio_get_port_property(context, &pcie_ports[trio_index]); 194 + if (ret < 0) { 195 + pr_err("PCI: PCIE_GET_PORT_PROPERTY failure, error %d," 196 + " on TRIO %d\n", ret, trio_index); 197 + goto get_port_property_failure; 198 + } 199 + 200 + context->mmio_base_mac = 201 + iorpc_ioremap(context->fd, 0, HV_TRIO_CONFIG_IOREMAP_SIZE); 202 + if (context->mmio_base_mac == NULL) { 203 + pr_err("PCI: TRIO config space mapping failure, error %d," 204 + " on TRIO %d\n", ret, trio_index); 205 + ret = -ENOMEM; 206 + 207 + goto trio_mmio_mapping_failure; 208 + } 209 + 210 + /* Check the port strap state which will override the BIB setting. */ 211 + for (mac = 0; mac < TILEGX_TRIO_PCIES; mac++) { 212 + TRIO_PCIE_INTFC_PORT_CONFIG_t port_config; 213 + unsigned int reg_offset; 214 + 215 + /* Ignore ports that are not specified in the BIB. */ 216 + if (!pcie_ports[trio_index].ports[mac].allow_rc && 217 + !pcie_ports[trio_index].ports[mac].allow_ep) 218 + continue; 219 + 220 + reg_offset = 221 + (TRIO_PCIE_INTFC_PORT_CONFIG << 222 + TRIO_CFG_REGION_ADDR__REG_SHIFT) | 223 + (TRIO_CFG_REGION_ADDR__INTFC_VAL_MAC_INTERFACE << 224 + TRIO_CFG_REGION_ADDR__INTFC_SHIFT) | 225 + (mac << TRIO_CFG_REGION_ADDR__MAC_SEL_SHIFT); 226 + 227 + port_config.word = 228 + __gxio_mmio_read(context->mmio_base_mac + reg_offset); 229 + 230 + if (port_config.strap_state != AUTO_CONFIG_RC && 231 + port_config.strap_state != AUTO_CONFIG_RC_G1) { 232 + /* 233 + * If this is really intended to be an EP port, record 234 + * it so that the endpoint driver will know about it. 235 + */ 236 + if (port_config.strap_state == AUTO_CONFIG_EP || 237 + port_config.strap_state == AUTO_CONFIG_EP_G1) 238 + pcie_ports[trio_index].ports[mac].allow_ep = 1; 239 + } 240 + } 241 + 197 242 return ret; 198 243 244 + trio_mmio_mapping_failure: 245 + get_port_property_failure: 199 246 asid_alloc_failure: 200 247 #ifdef USE_SHARED_PCIE_CONFIG_REGION 201 248 pio_alloc_failure: 202 249 #endif 203 250 hv_dev_close(context->fd); 251 + gxio_trio_init_failure: 252 + context->fd = -1; 204 253 205 254 return ret; 206 255 } 207 256 208 - static void 209 - tilegx_legacy_irq_ack(struct irq_data *d) 257 + static int __init tile_trio_init(void) 258 + { 259 + int i; 260 + 261 + /* We loop over all the TRIO shims. */ 262 + for (i = 0; i < TILEGX_NUM_TRIO; i++) { 263 + if (tile_pcie_open(i) < 0) 264 + continue; 265 + num_trio_shims++; 266 + } 267 + 268 + return 0; 269 + } 270 + postcore_initcall(tile_trio_init); 271 + 272 + static void tilegx_legacy_irq_ack(struct irq_data *d) 210 273 { 211 274 __insn_mtspr(SPR_IPI_EVENT_RESET_K, 1UL << d->irq); 212 275 } 213 276 214 - static void 215 - tilegx_legacy_irq_mask(struct irq_data *d) 277 + static void tilegx_legacy_irq_mask(struct irq_data *d) 216 278 { 217 279 __insn_mtspr(SPR_IPI_MASK_SET_K, 1UL << d->irq); 218 280 } 219 281 220 - static void 221 - tilegx_legacy_irq_unmask(struct irq_data *d) 282 + static void tilegx_legacy_irq_unmask(struct irq_data *d) 222 283 { 223 284 __insn_mtspr(SPR_IPI_MASK_RESET_K, 1UL << d->irq); 224 285 } ··· 305 234 * to Linux which just calls handle_level_irq() after clearing the 306 235 * MAC INTx Assert status bit associated with this interrupt. 307 236 */ 308 - static void 309 - trio_handle_level_irq(unsigned int irq, struct irq_desc *desc) 237 + static void trio_handle_level_irq(unsigned int irq, struct irq_desc *desc) 310 238 { 311 239 struct pci_controller *controller = irq_desc_get_handler_data(desc); 312 240 gxio_trio_context_t *trio_context = controller->trio; ··· 371 301 goto free_irqs; 372 302 } 373 303 374 - /* 375 - * Register the IRQ handler with the kernel. 376 - */ 304 + /* Register the IRQ handler with the kernel. */ 377 305 irq_set_chip_and_handler(irq, &tilegx_legacy_irq_chip, 378 306 trio_handle_level_irq); 379 307 irq_set_chip_data(irq, (void *)(uint64_t)i); ··· 388 320 } 389 321 390 322 /* 323 + * Return 1 if the port is strapped to operate in RC mode. 324 + */ 325 + static int 326 + strapped_for_rc(gxio_trio_context_t *trio_context, int mac) 327 + { 328 + TRIO_PCIE_INTFC_PORT_CONFIG_t port_config; 329 + unsigned int reg_offset; 330 + 331 + /* Check the port configuration. */ 332 + reg_offset = 333 + (TRIO_PCIE_INTFC_PORT_CONFIG << 334 + TRIO_CFG_REGION_ADDR__REG_SHIFT) | 335 + (TRIO_CFG_REGION_ADDR__INTFC_VAL_MAC_INTERFACE << 336 + TRIO_CFG_REGION_ADDR__INTFC_SHIFT) | 337 + (mac << TRIO_CFG_REGION_ADDR__MAC_SEL_SHIFT); 338 + port_config.word = 339 + __gxio_mmio_read(trio_context->mmio_base_mac + reg_offset); 340 + 341 + if (port_config.strap_state == AUTO_CONFIG_RC || 342 + port_config.strap_state == AUTO_CONFIG_RC_G1) 343 + return 1; 344 + else 345 + return 0; 346 + } 347 + 348 + /* 391 349 * Find valid controllers and fill in pci_controller structs for each 392 350 * of them. 393 351 * 394 - * Returns the number of controllers discovered. 352 + * Return the number of controllers discovered. 395 353 */ 396 354 int __init tile_pci_init(void) 397 355 { 398 - int num_trio_shims = 0; 399 356 int ctl_index = 0; 400 357 int i, j; 401 358 ··· 431 338 432 339 pr_info("PCI: Searching for controllers...\n"); 433 340 434 - /* 435 - * We loop over all the TRIO shims. 436 - */ 437 - for (i = 0; i < TILEGX_NUM_TRIO; i++) { 438 - int ret; 439 - 440 - ret = tile_pcie_open(i); 441 - if (ret < 0) 442 - continue; 443 - 444 - num_trio_shims++; 445 - } 446 - 447 341 if (num_trio_shims == 0 || sim_is_simulator()) 448 342 return 0; 449 343 450 344 /* 451 - * Now determine which PCIe ports are configured to operate in RC mode. 452 - * We look at the Board Information Block first and then see if there 453 - * are any overriding configuration by the HW strapping pin. 345 + * Now determine which PCIe ports are configured to operate in RC 346 + * mode. There is a differece in the port configuration capability 347 + * between the Gx36 and Gx72 devices. 348 + * 349 + * The Gx36 has configuration capability for each of the 3 PCIe 350 + * interfaces (disable, auto endpoint, auto RC, etc.). 351 + * On the Gx72, you can only select one of the 3 PCIe interfaces per 352 + * TRIO to train automatically. Further, the allowable training modes 353 + * are reduced to four options (auto endpoint, auto RC, stream x1, 354 + * stream x4). 355 + * 356 + * For Gx36 ports, it must be allowed to be in RC mode by the 357 + * Board Information Block, and the hardware strapping pins must be 358 + * set to RC mode. 359 + * 360 + * For Gx72 ports, the port will operate in RC mode if either of the 361 + * following is true: 362 + * 1. It is allowed to be in RC mode by the Board Information Block, 363 + * and the BIB doesn't allow the EP mode. 364 + * 2. It is allowed to be in either the RC or the EP mode by the BIB, 365 + * and the hardware strapping pin is set to RC mode. 454 366 */ 455 367 for (i = 0; i < TILEGX_NUM_TRIO; i++) { 456 368 gxio_trio_context_t *context = &trio_contexts[i]; 457 - int ret; 458 369 459 370 if (context->fd < 0) 460 371 continue; 461 372 462 - ret = hv_dev_pread(context->fd, 0, 463 - (HV_VirtAddr)&pcie_ports[i][0], 464 - sizeof(struct pcie_port_property) * TILEGX_TRIO_PCIES, 465 - GXIO_TRIO_OP_GET_PORT_PROPERTY); 466 - if (ret < 0) { 467 - pr_err("PCI: PCIE_GET_PORT_PROPERTY failure, error %d," 468 - " on TRIO %d\n", ret, i); 469 - continue; 470 - } 471 - 472 373 for (j = 0; j < TILEGX_TRIO_PCIES; j++) { 473 - if (pcie_ports[i][j].allow_rc) { 374 + int is_rc = 0; 375 + 376 + if (pcie_ports[i].is_gx72 && 377 + pcie_ports[i].ports[j].allow_rc) { 378 + if (!pcie_ports[i].ports[j].allow_ep || 379 + strapped_for_rc(context, j)) 380 + is_rc = 1; 381 + } else if (pcie_ports[i].ports[j].allow_rc && 382 + strapped_for_rc(context, j)) { 383 + is_rc = 1; 384 + } 385 + if (is_rc) { 474 386 pcie_rc[i][j] = 1; 475 387 num_rc_controllers++; 476 - } 477 - else if (pcie_ports[i][j].allow_ep) { 478 - num_ep_controllers++; 479 388 } 480 389 } 481 390 } 482 391 483 - /* 484 - * Return if no PCIe ports are configured to operate in RC mode. 485 - */ 392 + /* Return if no PCIe ports are configured to operate in RC mode. */ 486 393 if (num_rc_controllers == 0) 487 394 return 0; 488 395 489 - /* 490 - * Set the TRIO pointer and MAC index for each PCIe RC port. 491 - */ 396 + /* Set the TRIO pointer and MAC index for each PCIe RC port. */ 492 397 for (i = 0; i < TILEGX_NUM_TRIO; i++) { 493 398 for (j = 0; j < TILEGX_TRIO_PCIES; j++) { 494 399 if (pcie_rc[i][j]) { ··· 502 411 } 503 412 504 413 out: 505 - /* 506 - * Configure each PCIe RC port. 507 - */ 414 + /* Configure each PCIe RC port. */ 508 415 for (i = 0; i < num_rc_controllers; i++) { 509 - /* 510 - * Configure the PCIe MAC to run in RC mode. 511 - */ 512 416 417 + /* Configure the PCIe MAC to run in RC mode. */ 513 418 struct pci_controller *controller = &pci_controllers[i]; 514 419 515 420 controller->index = i; 516 421 controller->ops = &tile_cfg_ops; 422 + 423 + controller->io_space.start = PCIBIOS_MIN_IO + 424 + (i * IO_SPACE_SIZE); 425 + controller->io_space.end = controller->io_space.start + 426 + IO_SPACE_SIZE - 1; 427 + BUG_ON(controller->io_space.end > IO_SPACE_LIMIT); 428 + controller->io_space.flags = IORESOURCE_IO; 429 + snprintf(controller->io_space_name, 430 + sizeof(controller->io_space_name), 431 + "PCI I/O domain %d", i); 432 + controller->io_space.name = controller->io_space_name; 517 433 518 434 /* 519 435 * The PCI memory resource is located above the PA space. ··· 528 430 * is in range [3GB, 4GB - 1] of a 4GB space beyond the 529 431 * PA space. 530 432 */ 531 - 532 433 controller->mem_offset = TILE_PCI_MEM_START + 533 434 (i * TILE_PCI_BAR_WINDOW_TOP); 534 435 controller->mem_space.start = controller->mem_offset + ··· 555 458 return controller->irq_intx_table[pin - 1]; 556 459 } 557 460 558 - 559 461 static void fixup_read_and_payload_sizes(struct pci_controller *controller) 560 462 { 561 463 gxio_trio_context_t *trio_context = controller->trio; ··· 568 472 569 473 mac = controller->mac; 570 474 571 - /* 572 - * Set our max read request size to be 4KB. 573 - */ 475 + /* Set our max read request size to be 4KB. */ 574 476 reg_offset = 575 477 (TRIO_PCIE_RC_DEVICE_CONTROL << 576 478 TRIO_CFG_REGION_ADDR__REG_SHIFT) | ··· 577 483 (mac << TRIO_CFG_REGION_ADDR__MAC_SEL_SHIFT); 578 484 579 485 dev_control.word = __gxio_mmio_read32(trio_context->mmio_base_mac + 580 - reg_offset); 486 + reg_offset); 581 487 dev_control.max_read_req_sz = 5; 582 488 __gxio_mmio_write32(trio_context->mmio_base_mac + reg_offset, 583 - dev_control.word); 489 + dev_control.word); 584 490 585 491 /* 586 492 * Set the max payload size supported by this Gx PCIe MAC. ··· 596 502 (mac << TRIO_CFG_REGION_ADDR__MAC_SEL_SHIFT); 597 503 598 504 rc_dev_cap.word = __gxio_mmio_read32(trio_context->mmio_base_mac + 599 - reg_offset); 505 + reg_offset); 600 506 rc_dev_cap.mps_sup = 1; 601 507 __gxio_mmio_write32(trio_context->mmio_base_mac + reg_offset, 602 - rc_dev_cap.word); 508 + rc_dev_cap.word); 603 509 604 510 /* Configure PCI Express MPS setting. */ 605 511 list_for_each_entry(child, &root_bus->children, node) ··· 622 528 dev_control.max_payload_size, 623 529 dev_control.max_read_req_sz, 624 530 mac); 625 - if (err < 0) { 531 + if (err < 0) { 626 532 pr_err("PCI: PCIE_CONFIGURE_MAC_MPS_MRS failure, " 627 533 "MAC %d on TRIO %d\n", 628 534 mac, controller->trio_index); ··· 659 565 if (!isdigit(*str)) 660 566 return -EINVAL; 661 567 delay = simple_strtoul(str, (char **)&str, 10); 662 - if (delay > MAX_RC_DELAY) 663 - return -EINVAL; 664 568 } 665 569 666 570 rc_delay[trio_index][mac] = delay ? : DEFAULT_RC_DELAY; 667 - pr_info("Delaying PCIe RC link training for %u sec" 668 - " on MAC %lu on TRIO %lu\n", rc_delay[trio_index][mac], 669 - mac, trio_index); 670 571 return 0; 671 572 } 672 573 early_param("pcie_rc_delay", setup_pcie_rc_delay); 673 574 674 - /* 675 - * PCI initialization entry point, called by subsys_initcall. 676 - */ 575 + /* PCI initialization entry point, called by subsys_initcall. */ 677 576 int __init pcibios_init(void) 678 577 { 679 578 resource_size_t offset; ··· 676 589 677 590 tile_pci_init(); 678 591 679 - if (num_rc_controllers == 0 && num_ep_controllers == 0) 592 + if (num_rc_controllers == 0) 680 593 return 0; 681 - 682 - /* 683 - * We loop over all the TRIO shims and set up the MMIO mappings. 684 - */ 685 - for (i = 0; i < TILEGX_NUM_TRIO; i++) { 686 - gxio_trio_context_t *context = &trio_contexts[i]; 687 - 688 - if (context->fd < 0) 689 - continue; 690 - 691 - /* 692 - * Map in the MMIO space for the MAC. 693 - */ 694 - offset = 0; 695 - context->mmio_base_mac = 696 - iorpc_ioremap(context->fd, offset, 697 - HV_TRIO_CONFIG_IOREMAP_SIZE); 698 - if (context->mmio_base_mac == NULL) { 699 - pr_err("PCI: MAC map failure on TRIO %d\n", i); 700 - 701 - hv_dev_close(context->fd); 702 - context->fd = -1; 703 - continue; 704 - } 705 - } 706 594 707 595 /* 708 596 * Delay a bit in case devices aren't ready. Some devices are ··· 690 628 for (next_busno = 0, i = 0; i < num_rc_controllers; i++) { 691 629 struct pci_controller *controller = &pci_controllers[i]; 692 630 gxio_trio_context_t *trio_context = controller->trio; 693 - TRIO_PCIE_INTFC_PORT_CONFIG_t port_config; 694 631 TRIO_PCIE_INTFC_PORT_STATUS_t port_status; 695 632 TRIO_PCIE_INTFC_TX_FIFO_CTL_t tx_fifo_ctl; 696 633 struct pci_bus *bus; ··· 706 645 mac = controller->mac; 707 646 708 647 /* 709 - * Check the port strap state which will override the BIB 710 - * setting. 648 + * Check for PCIe link-up status to decide if we need 649 + * to force the link to come up. 711 650 */ 712 - 713 - reg_offset = 714 - (TRIO_PCIE_INTFC_PORT_CONFIG << 715 - TRIO_CFG_REGION_ADDR__REG_SHIFT) | 716 - (TRIO_CFG_REGION_ADDR__INTFC_VAL_MAC_INTERFACE << 717 - TRIO_CFG_REGION_ADDR__INTFC_SHIFT ) | 718 - (mac << TRIO_CFG_REGION_ADDR__MAC_SEL_SHIFT); 719 - 720 - port_config.word = 721 - __gxio_mmio_read(trio_context->mmio_base_mac + 722 - reg_offset); 723 - 724 - if ((port_config.strap_state != 725 - TRIO_PCIE_INTFC_PORT_CONFIG__STRAP_STATE_VAL_AUTO_CONFIG_RC) && 726 - (port_config.strap_state != 727 - TRIO_PCIE_INTFC_PORT_CONFIG__STRAP_STATE_VAL_AUTO_CONFIG_RC_G1)) { 728 - /* 729 - * If this is really intended to be an EP port, 730 - * record it so that the endpoint driver will know about it. 731 - */ 732 - if (port_config.strap_state == 733 - TRIO_PCIE_INTFC_PORT_CONFIG__STRAP_STATE_VAL_AUTO_CONFIG_ENDPOINT || 734 - port_config.strap_state == 735 - TRIO_PCIE_INTFC_PORT_CONFIG__STRAP_STATE_VAL_AUTO_CONFIG_ENDPOINT_G1) 736 - pcie_ports[trio_index][mac].allow_ep = 1; 737 - 738 - continue; 739 - } 740 - 741 - /* 742 - * Delay the RC link training if needed. 743 - */ 744 - if (rc_delay[trio_index][mac]) 745 - msleep(rc_delay[trio_index][mac] * 1000); 746 - 747 - ret = gxio_trio_force_rc_link_up(trio_context, mac); 748 - if (ret < 0) 749 - pr_err("PCI: PCIE_FORCE_LINK_UP failure, " 750 - "MAC %d on TRIO %d\n", mac, trio_index); 751 - 752 - pr_info("PCI: Found PCI controller #%d on TRIO %d MAC %d\n", i, 753 - trio_index, controller->mac); 754 - 755 - /* 756 - * Wait a bit here because some EP devices take longer 757 - * to come up. 758 - */ 759 - msleep(1000); 760 - 761 - /* 762 - * Check for PCIe link-up status. 763 - */ 764 - 765 651 reg_offset = 766 652 (TRIO_PCIE_INTFC_PORT_STATUS << 767 653 TRIO_CFG_REGION_ADDR__REG_SHIFT) | 768 654 (TRIO_CFG_REGION_ADDR__INTFC_VAL_MAC_INTERFACE << 769 - TRIO_CFG_REGION_ADDR__INTFC_SHIFT ) | 655 + TRIO_CFG_REGION_ADDR__INTFC_SHIFT) | 770 656 (mac << TRIO_CFG_REGION_ADDR__MAC_SEL_SHIFT); 771 657 772 658 port_status.word = 773 659 __gxio_mmio_read(trio_context->mmio_base_mac + 774 660 reg_offset); 775 661 if (!port_status.dl_up) { 776 - pr_err("PCI: link is down, MAC %d on TRIO %d\n", 777 - mac, trio_index); 662 + if (rc_delay[trio_index][mac]) { 663 + pr_info("Delaying PCIe RC TRIO init %d sec" 664 + " on MAC %d on TRIO %d\n", 665 + rc_delay[trio_index][mac], mac, 666 + trio_index); 667 + msleep(rc_delay[trio_index][mac] * 1000); 668 + } 669 + ret = gxio_trio_force_rc_link_up(trio_context, mac); 670 + if (ret < 0) 671 + pr_err("PCI: PCIE_FORCE_LINK_UP failure, " 672 + "MAC %d on TRIO %d\n", mac, trio_index); 673 + } 674 + 675 + pr_info("PCI: Found PCI controller #%d on TRIO %d MAC %d\n", i, 676 + trio_index, controller->mac); 677 + 678 + /* Delay the bus probe if needed. */ 679 + if (rc_delay[trio_index][mac]) { 680 + pr_info("Delaying PCIe RC bus enumerating %d sec" 681 + " on MAC %d on TRIO %d\n", 682 + rc_delay[trio_index][mac], mac, 683 + trio_index); 684 + msleep(rc_delay[trio_index][mac] * 1000); 685 + } else { 686 + /* 687 + * Wait a bit here because some EP devices 688 + * take longer to come up. 689 + */ 690 + msleep(1000); 691 + } 692 + 693 + /* Check for PCIe link-up status again. */ 694 + port_status.word = 695 + __gxio_mmio_read(trio_context->mmio_base_mac + 696 + reg_offset); 697 + if (!port_status.dl_up) { 698 + if (pcie_ports[trio_index].ports[mac].removable) { 699 + pr_info("PCI: link is down, MAC %d on TRIO %d\n", 700 + mac, trio_index); 701 + pr_info("This is expected if no PCIe card" 702 + " is connected to this link\n"); 703 + } else 704 + pr_err("PCI: link is down, MAC %d on TRIO %d\n", 705 + mac, trio_index); 778 706 continue; 779 707 } 780 708 ··· 789 739 * Change the device ID so that Linux bus crawl doesn't confuse 790 740 * the internal bridge with any Tilera endpoints. 791 741 */ 792 - 793 742 reg_offset = 794 743 (TRIO_PCIE_RC_DEVICE_ID_VEN_ID << 795 744 TRIO_CFG_REGION_ADDR__REG_SHIFT) | ··· 801 752 TRIO_PCIE_RC_DEVICE_ID_VEN_ID__DEV_ID_SHIFT) | 802 753 TILERA_VENDOR_ID); 803 754 804 - /* 805 - * Set the internal P2P bridge class code. 806 - */ 807 - 755 + /* Set the internal P2P bridge class code. */ 808 756 reg_offset = 809 757 (TRIO_PCIE_RC_REVISION_ID << 810 758 TRIO_CFG_REGION_ADDR__REG_SHIFT) | ··· 812 766 class_code_revision = 813 767 __gxio_mmio_read32(trio_context->mmio_base_mac + 814 768 reg_offset); 815 - class_code_revision = (class_code_revision & 0xff ) | 816 - (PCI_CLASS_BRIDGE_PCI << 16); 769 + class_code_revision = (class_code_revision & 0xff) | 770 + (PCI_CLASS_BRIDGE_PCI << 16); 817 771 818 772 __gxio_mmio_write32(trio_context->mmio_base_mac + 819 773 reg_offset, class_code_revision); 820 774 821 775 #ifdef USE_SHARED_PCIE_CONFIG_REGION 822 776 823 - /* 824 - * Map in the MMIO space for the PIO region. 825 - */ 777 + /* Map in the MMIO space for the PIO region. */ 826 778 offset = HV_TRIO_PIO_OFFSET(trio_context->pio_cfg_index) | 827 779 (((unsigned long long)mac) << 828 780 TRIO_TILE_PIO_REGION_SETUP_CFG_ADDR__MAC_SHIFT); 829 781 830 782 #else 831 783 832 - /* 833 - * Alloc a PIO region for PCI config access per MAC. 834 - */ 784 + /* Alloc a PIO region for PCI config access per MAC. */ 835 785 ret = gxio_trio_alloc_pio_regions(trio_context, 1, 0, 0); 836 786 if (ret < 0) { 837 787 pr_err("PCI: PCI CFG PIO alloc failure for mac %d " ··· 838 796 839 797 trio_context->pio_cfg_index[mac] = ret; 840 798 841 - /* 842 - * For PIO CFG, the bus_address_hi parameter is 0. 843 - */ 799 + /* For PIO CFG, the bus_address_hi parameter is 0. */ 844 800 ret = gxio_trio_init_pio_region_aux(trio_context, 845 801 trio_context->pio_cfg_index[mac], 846 802 mac, 0, HV_TRIO_PIO_FLAG_CONFIG_SPACE); ··· 855 815 856 816 #endif 857 817 818 + /* 819 + * To save VMALLOC space, we take advantage of the fact that 820 + * bit 29 in the PIO CFG address format is reserved 0. With 821 + * TRIO_TILE_PIO_REGION_SETUP_CFG_ADDR__MAC_SHIFT being 30, 822 + * this cuts VMALLOC space usage from 1GB to 512MB per mac. 823 + */ 858 824 trio_context->mmio_base_pio_cfg[mac] = 859 - iorpc_ioremap(trio_context->fd, offset, 860 - (1 << TRIO_TILE_PIO_REGION_SETUP_CFG_ADDR__MAC_SHIFT)); 825 + iorpc_ioremap(trio_context->fd, offset, (1UL << 826 + (TRIO_TILE_PIO_REGION_SETUP_CFG_ADDR__MAC_SHIFT - 1))); 861 827 if (trio_context->mmio_base_pio_cfg[mac] == NULL) { 862 828 pr_err("PCI: PIO map failure for mac %d on TRIO %d\n", 863 829 mac, trio_index); ··· 871 825 continue; 872 826 } 873 827 874 - /* 875 - * Initialize the PCIe interrupts. 876 - */ 828 + /* Initialize the PCIe interrupts. */ 877 829 if (tile_init_irqs(controller)) { 878 830 pr_err("PCI: IRQs init failure for mac %d on TRIO %d\n", 879 831 mac, trio_index); ··· 882 838 /* 883 839 * The PCI memory resource is located above the PA space. 884 840 * The memory range for the PCI root bus should not overlap 885 - * with the physical RAM 841 + * with the physical RAM. 886 842 */ 887 843 pci_add_resource_offset(&resources, &controller->mem_space, 888 844 controller->mem_offset); 889 - 845 + pci_add_resource(&resources, &controller->io_space); 890 846 controller->first_busno = next_busno; 891 847 bus = pci_scan_root_bus(NULL, next_busno, controller->ops, 892 848 controller, &resources); 893 849 controller->root_bus = bus; 894 850 next_busno = bus->busn_res.end + 1; 895 - 896 851 } 897 852 898 853 /* Do machine dependent PCI interrupt routing */ ··· 903 860 * It allocates all of the resources (I/O memory, etc) 904 861 * associated with the devices read in above. 905 862 */ 906 - 907 863 pci_assign_unassigned_resources(); 908 864 909 865 /* Record the I/O resources in the PCI controller structure. */ ··· 910 868 struct pci_controller *controller = &pci_controllers[i]; 911 869 gxio_trio_context_t *trio_context = controller->trio; 912 870 struct pci_bus *root_bus = pci_controllers[i].root_bus; 913 - struct pci_bus *next_bus; 914 - uint32_t bus_address_hi; 915 - struct pci_dev *dev; 916 871 int ret; 917 872 int j; 918 873 ··· 923 884 /* Configure the max_payload_size values for this domain. */ 924 885 fixup_read_and_payload_sizes(controller); 925 886 926 - list_for_each_entry(dev, &root_bus->devices, bus_list) { 927 - /* Find the PCI host controller, ie. the 1st bridge. */ 928 - if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI && 929 - (PCI_SLOT(dev->devfn) == 0)) { 930 - next_bus = dev->subordinate; 931 - pci_controllers[i].mem_resources[0] = 932 - *next_bus->resource[0]; 933 - pci_controllers[i].mem_resources[1] = 934 - *next_bus->resource[1]; 935 - pci_controllers[i].mem_resources[2] = 936 - *next_bus->resource[2]; 937 - 938 - break; 939 - } 940 - } 941 - 942 - if (pci_controllers[i].mem_resources[1].flags & IORESOURCE_MEM) 943 - bus_address_hi = 944 - pci_controllers[i].mem_resources[1].start >> 32; 945 - else if (pci_controllers[i].mem_resources[2].flags & IORESOURCE_PREFETCH) 946 - bus_address_hi = 947 - pci_controllers[i].mem_resources[2].start >> 32; 948 - else { 949 - /* This is unlikely. */ 950 - pr_err("PCI: no memory resources on TRIO %d mac %d\n", 951 - controller->trio_index, controller->mac); 952 - continue; 953 - } 954 - 955 - /* 956 - * Alloc a PIO region for PCI memory access for each RC port. 957 - */ 887 + /* Alloc a PIO region for PCI memory access for each RC port. */ 958 888 ret = gxio_trio_alloc_pio_regions(trio_context, 1, 0, 0); 959 889 if (ret < 0) { 960 890 pr_err("PCI: MEM PIO alloc failure on TRIO %d mac %d, " 961 - "give up\n", controller->trio_index, 962 - controller->mac); 891 + "give up\n", controller->trio_index, 892 + controller->mac); 963 893 964 894 continue; 965 895 } ··· 946 938 0); 947 939 if (ret < 0) { 948 940 pr_err("PCI: MEM PIO init failure on TRIO %d mac %d, " 949 - "give up\n", controller->trio_index, 950 - controller->mac); 941 + "give up\n", controller->trio_index, 942 + controller->mac); 951 943 952 944 continue; 953 945 } 946 + 947 + #ifdef CONFIG_TILE_PCI_IO 948 + /* 949 + * Alloc a PIO region for PCI I/O space access for each RC port. 950 + */ 951 + ret = gxio_trio_alloc_pio_regions(trio_context, 1, 0, 0); 952 + if (ret < 0) { 953 + pr_err("PCI: I/O PIO alloc failure on TRIO %d mac %d, " 954 + "give up\n", controller->trio_index, 955 + controller->mac); 956 + 957 + continue; 958 + } 959 + 960 + controller->pio_io_index = ret; 961 + 962 + /* 963 + * For PIO IO, the bus_address_hi parameter is hard-coded 0 964 + * because PCI I/O address space is 32-bit. 965 + */ 966 + ret = gxio_trio_init_pio_region_aux(trio_context, 967 + controller->pio_io_index, 968 + controller->mac, 969 + 0, 970 + HV_TRIO_PIO_FLAG_IO_SPACE); 971 + if (ret < 0) { 972 + pr_err("PCI: I/O PIO init failure on TRIO %d mac %d, " 973 + "give up\n", controller->trio_index, 974 + controller->mac); 975 + 976 + continue; 977 + } 978 + #endif 954 979 955 980 /* 956 981 * Configure a Mem-Map region for each memory controller so ··· 999 958 0); 1000 959 if (ret < 0) { 1001 960 pr_err("PCI: Mem-Map alloc failure on TRIO %d " 1002 - "mac %d for MC %d, give up\n", 1003 - controller->trio_index, 1004 - controller->mac, j); 961 + "mac %d for MC %d, give up\n", 962 + controller->trio_index, 963 + controller->mac, j); 1005 964 1006 965 goto alloc_mem_map_failed; 1007 966 } ··· 1032 991 GXIO_TRIO_ORDER_MODE_UNORDERED); 1033 992 if (ret < 0) { 1034 993 pr_err("PCI: Mem-Map init failure on TRIO %d " 1035 - "mac %d for MC %d, give up\n", 1036 - controller->trio_index, 1037 - controller->mac, j); 994 + "mac %d for MC %d, give up\n", 995 + controller->trio_index, 996 + controller->mac, j); 1038 997 1039 998 goto alloc_mem_map_failed; 1040 999 } ··· 1043 1002 alloc_mem_map_failed: 1044 1003 break; 1045 1004 } 1046 - 1047 1005 } 1048 1006 1049 1007 return 0; 1050 1008 } 1051 1009 subsys_initcall(pcibios_init); 1052 1010 1053 - /* Note: to be deleted after Linux 3.6 merge. */ 1011 + /* No bus fixups needed. */ 1054 1012 void pcibios_fixup_bus(struct pci_bus *bus) 1055 1013 { 1056 1014 } 1057 1015 1058 - /* 1059 - * This can be called from the generic PCI layer, but doesn't need to 1060 - * do anything. 1061 - */ 1062 - char *pcibios_setup(char *str) 1016 + /* Process any "pci=" kernel boot arguments. */ 1017 + char *__init pcibios_setup(char *str) 1063 1018 { 1064 1019 if (!strcmp(str, "off")) { 1065 1020 pci_probe = 0; ··· 1066 1029 1067 1030 /* 1068 1031 * Enable memory address decoding, as appropriate, for the 1069 - * device described by the 'dev' struct. The I/O decoding 1070 - * is disabled, though the TILE-Gx supports I/O addressing. 1032 + * device described by the 'dev' struct. 1071 1033 * 1072 1034 * This is called from the generic PCI layer, and can be called 1073 1035 * for bridges or endpoints. ··· 1076 1040 return pci_enable_resources(dev, mask); 1077 1041 } 1078 1042 1079 - /* Called for each device after PCI setup is done. */ 1043 + /* 1044 + * Called for each device after PCI setup is done. 1045 + * We initialize the PCI device capabilities conservatively, assuming that 1046 + * all devices can only address the 32-bit DMA space. The exception here is 1047 + * that the device dma_offset is set to the value that matches the 64-bit 1048 + * capable devices. This is OK because dma_offset is not used by legacy 1049 + * dma_ops, nor by the hybrid dma_ops's streaming DMAs, which are 64-bit ops. 1050 + * This implementation matches the kernel design of setting PCI devices' 1051 + * coherent_dma_mask to 0xffffffffull by default, allowing the device drivers 1052 + * to skip calling pci_set_consistent_dma_mask(DMA_BIT_MASK(32)). 1053 + */ 1080 1054 static void pcibios_fixup_final(struct pci_dev *pdev) 1081 1055 { 1082 - set_dma_ops(&pdev->dev, gx_pci_dma_map_ops); 1056 + set_dma_ops(&pdev->dev, gx_legacy_pci_dma_map_ops); 1083 1057 set_dma_offset(&pdev->dev, TILE_PCI_MEM_MAP_BASE_OFFSET); 1084 1058 pdev->dev.archdata.max_direct_dma_addr = 1085 1059 TILE_PCI_MAX_DIRECT_DMA_ADDRESS; 1060 + pdev->dev.coherent_dma_mask = TILE_PCI_MAX_DIRECT_DMA_ADDRESS; 1086 1061 } 1087 1062 DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, pcibios_fixup_final); 1088 1063 ··· 1107 1060 resource_size_t start; 1108 1061 resource_size_t end; 1109 1062 int trio_fd; 1110 - int i, j; 1063 + int i; 1111 1064 1112 1065 start = phys_addr; 1113 1066 end = phys_addr + size - 1; 1114 1067 1115 1068 /* 1116 - * In the following, each PCI controller's mem_resources[1] 1117 - * represents its (non-prefetchable) PCI memory resource and 1118 - * mem_resources[2] refers to its prefetchable PCI memory resource. 1119 - * By searching phys_addr in each controller's mem_resources[], we can 1069 + * By searching phys_addr in each controller's mem_space, we can 1120 1070 * determine the controller that should accept the PCI memory access. 1121 1071 */ 1122 - 1123 1072 for (i = 0; i < num_rc_controllers; i++) { 1124 1073 /* 1125 1074 * Skip controllers that are not properly initialized or ··· 1124 1081 if (pci_controllers[i].root_bus == NULL) 1125 1082 continue; 1126 1083 1127 - for (j = 1; j < 3; j++) { 1128 - bar_start = 1129 - pci_controllers[i].mem_resources[j].start; 1130 - bar_end = 1131 - pci_controllers[i].mem_resources[j].end; 1084 + bar_start = pci_controllers[i].mem_space.start; 1085 + bar_end = pci_controllers[i].mem_space.end; 1132 1086 1133 - if ((start >= bar_start) && (end <= bar_end)) { 1134 - 1135 - controller = &pci_controllers[i]; 1136 - 1137 - goto got_it; 1138 - } 1087 + if ((start >= bar_start) && (end <= bar_end)) { 1088 + controller = &pci_controllers[i]; 1089 + break; 1139 1090 } 1140 1091 } 1141 1092 1142 1093 if (controller == NULL) 1143 1094 return NULL; 1144 1095 1145 - got_it: 1146 1096 trio_fd = controller->trio->fd; 1147 1097 1148 1098 /* Convert the resource start to the bus address offset. */ ··· 1143 1107 1144 1108 offset = HV_TRIO_PIO_OFFSET(controller->pio_mem_index) + start; 1145 1109 1146 - /* 1147 - * We need to keep the PCI bus address's in-page offset in the VA. 1148 - */ 1110 + /* We need to keep the PCI bus address's in-page offset in the VA. */ 1149 1111 return iorpc_ioremap(trio_fd, offset, size) + 1150 - (phys_addr & (PAGE_SIZE - 1)); 1112 + (start & (PAGE_SIZE - 1)); 1151 1113 } 1152 1114 EXPORT_SYMBOL(ioremap); 1115 + 1116 + #ifdef CONFIG_TILE_PCI_IO 1117 + /* Map a PCI I/O address into VA space. */ 1118 + void __iomem *ioport_map(unsigned long port, unsigned int size) 1119 + { 1120 + struct pci_controller *controller = NULL; 1121 + resource_size_t bar_start; 1122 + resource_size_t bar_end; 1123 + resource_size_t offset; 1124 + resource_size_t start; 1125 + resource_size_t end; 1126 + int trio_fd; 1127 + int i; 1128 + 1129 + start = port; 1130 + end = port + size - 1; 1131 + 1132 + /* 1133 + * By searching the port in each controller's io_space, we can 1134 + * determine the controller that should accept the PCI I/O access. 1135 + */ 1136 + for (i = 0; i < num_rc_controllers; i++) { 1137 + /* 1138 + * Skip controllers that are not properly initialized or 1139 + * have down links. 1140 + */ 1141 + if (pci_controllers[i].root_bus == NULL) 1142 + continue; 1143 + 1144 + bar_start = pci_controllers[i].io_space.start; 1145 + bar_end = pci_controllers[i].io_space.end; 1146 + 1147 + if ((start >= bar_start) && (end <= bar_end)) { 1148 + controller = &pci_controllers[i]; 1149 + break; 1150 + } 1151 + } 1152 + 1153 + if (controller == NULL) 1154 + return NULL; 1155 + 1156 + trio_fd = controller->trio->fd; 1157 + 1158 + /* Convert the resource start to the bus address offset. */ 1159 + port -= controller->io_space.start; 1160 + 1161 + offset = HV_TRIO_PIO_OFFSET(controller->pio_io_index) + port; 1162 + 1163 + /* We need to keep the PCI bus address's in-page offset in the VA. */ 1164 + return iorpc_ioremap(trio_fd, offset, size) + (port & (PAGE_SIZE - 1)); 1165 + } 1166 + EXPORT_SYMBOL(ioport_map); 1167 + 1168 + void ioport_unmap(void __iomem *addr) 1169 + { 1170 + iounmap(addr); 1171 + } 1172 + EXPORT_SYMBOL(ioport_unmap); 1173 + #endif 1153 1174 1154 1175 void pci_iounmap(struct pci_dev *dev, void __iomem *addr) 1155 1176 { ··· 1229 1136 * offset is in bytes, from the start of config space for the 1230 1137 * specified bus & device. 1231 1138 */ 1232 - 1233 1139 static int tile_cfg_read(struct pci_bus *bus, unsigned int devfn, int offset, 1234 1140 int size, u32 *val) 1235 1141 { ··· 1278 1186 * Accesses to the directly attached device have to be 1279 1187 * sent as type-0 configs. 1280 1188 */ 1281 - 1282 1189 if (busnum == (controller->first_busno + 1)) { 1283 1190 /* 1284 1191 * There is only one device off of our built-in P2P bridge. ··· 1299 1208 * Note that we don't set the mac field in cfg_addr because the 1300 1209 * mapping is per port. 1301 1210 */ 1302 - 1303 1211 mmio_addr = trio_context->mmio_base_pio_cfg[controller->mac] + 1304 - cfg_addr.word; 1212 + cfg_addr.word; 1305 1213 1306 1214 valid_device: 1307 1215 ··· 1404 1314 * Accesses to the directly attached device have to be 1405 1315 * sent as type-0 configs. 1406 1316 */ 1407 - 1408 1317 if (busnum == (controller->first_busno + 1)) { 1409 1318 /* 1410 1319 * There is only one device off of our built-in P2P bridge. ··· 1425 1336 * Note that we don't set the mac field in cfg_addr because the 1426 1337 * mapping is per port. 1427 1338 */ 1428 - 1429 1339 mmio_addr = trio_context->mmio_base_pio_cfg[controller->mac] + 1430 1340 cfg_addr.word; 1431 1341 ··· 1462 1374 }; 1463 1375 1464 1376 1465 - /* 1466 - * MSI support starts here. 1467 - */ 1468 - static unsigned int 1469 - tilegx_msi_startup(struct irq_data *d) 1377 + /* MSI support starts here. */ 1378 + static unsigned int tilegx_msi_startup(struct irq_data *d) 1470 1379 { 1471 1380 if (d->msi_desc) 1472 1381 unmask_msi_irq(d); ··· 1471 1386 return 0; 1472 1387 } 1473 1388 1474 - static void 1475 - tilegx_msi_ack(struct irq_data *d) 1389 + static void tilegx_msi_ack(struct irq_data *d) 1476 1390 { 1477 1391 __insn_mtspr(SPR_IPI_EVENT_RESET_K, 1UL << d->irq); 1478 1392 } 1479 1393 1480 - static void 1481 - tilegx_msi_mask(struct irq_data *d) 1394 + static void tilegx_msi_mask(struct irq_data *d) 1482 1395 { 1483 1396 mask_msi_irq(d); 1484 1397 __insn_mtspr(SPR_IPI_MASK_SET_K, 1UL << d->irq); 1485 1398 } 1486 1399 1487 - static void 1488 - tilegx_msi_unmask(struct irq_data *d) 1400 + static void tilegx_msi_unmask(struct irq_data *d) 1489 1401 { 1490 1402 __insn_mtspr(SPR_IPI_MASK_RESET_K, 1UL << d->irq); 1491 1403 unmask_msi_irq(d); ··· 1539 1457 trio_context = controller->trio; 1540 1458 1541 1459 /* 1542 - * Allocate the Mem-Map that will accept the MSI write and 1543 - * trigger the TILE-side interrupts. 1460 + * Allocate a scatter-queue that will accept the MSI write and 1461 + * trigger the TILE-side interrupts. We use the scatter-queue regions 1462 + * before the mem map regions, because the latter are needed by more 1463 + * applications. 1544 1464 */ 1545 - mem_map = gxio_trio_alloc_memory_maps(trio_context, 1, 0, 0); 1546 - if (mem_map < 0) { 1547 - dev_printk(KERN_INFO, &pdev->dev, 1548 - "%s Mem-Map alloc failure. " 1549 - "Failed to initialize MSI interrupts. " 1550 - "Falling back to legacy interrupts.\n", 1551 - desc->msi_attrib.is_msix ? "MSI-X" : "MSI"); 1465 + mem_map = gxio_trio_alloc_scatter_queues(trio_context, 1, 0, 0); 1466 + if (mem_map >= 0) { 1467 + TRIO_MAP_SQ_DOORBELL_FMT_t doorbell_template = {{ 1468 + .pop = 0, 1469 + .doorbell = 1, 1470 + }}; 1552 1471 1553 - ret = -ENOMEM; 1554 - goto msi_mem_map_alloc_failure; 1472 + mem_map += TRIO_NUM_MAP_MEM_REGIONS; 1473 + mem_map_base = MEM_MAP_INTR_REGIONS_BASE + 1474 + mem_map * MEM_MAP_INTR_REGION_SIZE; 1475 + mem_map_limit = mem_map_base + MEM_MAP_INTR_REGION_SIZE - 1; 1476 + 1477 + msi_addr = mem_map_base + MEM_MAP_INTR_REGION_SIZE - 8; 1478 + msg.data = (unsigned int)doorbell_template.word; 1479 + } else { 1480 + /* SQ regions are out, allocate from map mem regions. */ 1481 + mem_map = gxio_trio_alloc_memory_maps(trio_context, 1, 0, 0); 1482 + if (mem_map < 0) { 1483 + dev_printk(KERN_INFO, &pdev->dev, 1484 + "%s Mem-Map alloc failure. " 1485 + "Failed to initialize MSI interrupts. " 1486 + "Falling back to legacy interrupts.\n", 1487 + desc->msi_attrib.is_msix ? "MSI-X" : "MSI"); 1488 + ret = -ENOMEM; 1489 + goto msi_mem_map_alloc_failure; 1490 + } 1491 + 1492 + mem_map_base = MEM_MAP_INTR_REGIONS_BASE + 1493 + mem_map * MEM_MAP_INTR_REGION_SIZE; 1494 + mem_map_limit = mem_map_base + MEM_MAP_INTR_REGION_SIZE - 1; 1495 + 1496 + msi_addr = mem_map_base + TRIO_MAP_MEM_REG_INT3 - 1497 + TRIO_MAP_MEM_REG_INT0; 1498 + 1499 + msg.data = mem_map; 1555 1500 } 1556 1501 1557 1502 /* We try to distribute different IRQs to different tiles. */ 1558 1503 cpu = tile_irq_cpu(irq); 1559 1504 1560 1505 /* 1561 - * Now call up to the HV to configure the Mem-Map interrupt and 1506 + * Now call up to the HV to configure the MSI interrupt and 1562 1507 * set up the IPI binding. 1563 1508 */ 1564 - mem_map_base = MEM_MAP_INTR_REGIONS_BASE + 1565 - mem_map * MEM_MAP_INTR_REGION_SIZE; 1566 - mem_map_limit = mem_map_base + MEM_MAP_INTR_REGION_SIZE - 1; 1567 - 1568 1509 ret = gxio_trio_config_msi_intr(trio_context, cpu_x(cpu), cpu_y(cpu), 1569 1510 KERNEL_PL, irq, controller->mac, 1570 1511 mem_map, mem_map_base, mem_map_limit, ··· 1600 1495 1601 1496 irq_set_msi_desc(irq, desc); 1602 1497 1603 - msi_addr = mem_map_base + TRIO_MAP_MEM_REG_INT3 - TRIO_MAP_MEM_REG_INT0; 1604 - 1605 1498 msg.address_hi = msi_addr >> 32; 1606 1499 msg.address_lo = msi_addr & 0xffffffff; 1607 - 1608 - msg.data = mem_map; 1609 1500 1610 1501 write_msi_msg(irq, &msg); 1611 1502 irq_set_chip_and_handler(irq, &tilegx_msi_chip, handle_level_irq);
-2
arch/tile/kernel/proc.c
··· 113 113 * Support /proc/sys/tile directory 114 114 */ 115 115 116 - #ifndef __tilegx__ /* FIXME: GX: no support for unaligned access yet */ 117 116 static ctl_table unaligned_subtable[] = { 118 117 { 119 118 .procname = "enabled", ··· 159 160 } 160 161 161 162 arch_initcall(proc_sys_tile_init); 162 - #endif
+46 -70
arch/tile/kernel/process.c
··· 33 33 #include <asm/syscalls.h> 34 34 #include <asm/traps.h> 35 35 #include <asm/setup.h> 36 + #include <asm/uaccess.h> 36 37 #ifdef CONFIG_HARDWALL 37 38 #include <asm/hardwall.h> 38 39 #endif ··· 74 73 void arch_release_thread_info(struct thread_info *info) 75 74 { 76 75 struct single_step_state *step_state = info->step_state; 77 - 78 - #ifdef CONFIG_HARDWALL 79 - /* 80 - * We free a thread_info from the context of the task that has 81 - * been scheduled next, so the original task is already dead. 82 - * Calling deactivate here just frees up the data structures. 83 - * If the task we're freeing held the last reference to a 84 - * hardwall fd, it would have been released prior to this point 85 - * anyway via exit_files(), and the hardwall_task.info pointers 86 - * would be NULL by now. 87 - */ 88 - hardwall_deactivate_all(info->task); 89 - #endif 90 76 91 77 if (step_state) { 92 78 ··· 148 160 */ 149 161 task_thread_info(p)->step_state = NULL; 150 162 163 + #ifdef __tilegx__ 164 + /* 165 + * Do not clone unalign jit fixup from the parent; each thread 166 + * must allocate its own on demand. 167 + */ 168 + task_thread_info(p)->unalign_jit_base = NULL; 169 + #endif 170 + 151 171 /* 152 172 * Copy the registers onto the kernel stack so the 153 173 * return-from-interrupt code will reload it into registers. ··· 187 191 memset(&p->thread.dma_async_tlb, 0, sizeof(struct async_tlb)); 188 192 #endif 189 193 190 - #if CHIP_HAS_SN_PROC() 191 - /* Likewise, the new thread is not running static processor code. */ 192 - p->thread.sn_proc_running = 0; 193 - memset(&p->thread.sn_async_tlb, 0, sizeof(struct async_tlb)); 194 - #endif 195 - 196 - #if CHIP_HAS_PROC_STATUS_SPR() 197 194 /* New thread has its miscellaneous processor state bits clear. */ 198 195 p->thread.proc_status = 0; 199 - #endif 200 196 201 197 #ifdef CONFIG_HARDWALL 202 198 /* New thread does not own any networks. */ ··· 206 218 return 0; 207 219 } 208 220 221 + int set_unalign_ctl(struct task_struct *tsk, unsigned int val) 222 + { 223 + task_thread_info(tsk)->align_ctl = val; 224 + return 0; 225 + } 226 + 227 + int get_unalign_ctl(struct task_struct *tsk, unsigned long adr) 228 + { 229 + return put_user(task_thread_info(tsk)->align_ctl, 230 + (unsigned int __user *)adr); 231 + } 232 + 233 + static struct task_struct corrupt_current = { .comm = "<corrupt>" }; 234 + 209 235 /* 210 236 * Return "current" if it looks plausible, or else a pointer to a dummy. 211 237 * This can be helpful if we are just trying to emit a clean panic. 212 238 */ 213 239 struct task_struct *validate_current(void) 214 240 { 215 - static struct task_struct corrupt = { .comm = "<corrupt>" }; 216 241 struct task_struct *tsk = current; 217 242 if (unlikely((unsigned long)tsk < PAGE_OFFSET || 218 243 (high_memory && (void *)tsk > high_memory) || 219 244 ((unsigned long)tsk & (__alignof__(*tsk) - 1)) != 0)) { 220 245 pr_err("Corrupt 'current' %p (sp %#lx)\n", tsk, stack_pointer); 221 - tsk = &corrupt; 246 + tsk = &corrupt_current; 222 247 } 223 248 return tsk; 224 249 } ··· 370 369 t->system_save[2] = __insn_mfspr(SPR_SYSTEM_SAVE_0_2); 371 370 t->system_save[3] = __insn_mfspr(SPR_SYSTEM_SAVE_0_3); 372 371 t->intctrl_0 = __insn_mfspr(SPR_INTCTRL_0_STATUS); 373 - #if CHIP_HAS_PROC_STATUS_SPR() 374 372 t->proc_status = __insn_mfspr(SPR_PROC_STATUS); 375 - #endif 376 373 #if !CHIP_HAS_FIXED_INTVEC_BASE() 377 374 t->interrupt_vector_base = __insn_mfspr(SPR_INTERRUPT_VECTOR_BASE_0); 378 375 #endif 379 - #if CHIP_HAS_TILE_RTF_HWM() 380 376 t->tile_rtf_hwm = __insn_mfspr(SPR_TILE_RTF_HWM); 381 - #endif 382 377 #if CHIP_HAS_DSTREAM_PF() 383 378 t->dstream_pf = __insn_mfspr(SPR_DSTREAM_PF); 384 379 #endif ··· 395 398 __insn_mtspr(SPR_SYSTEM_SAVE_0_2, t->system_save[2]); 396 399 __insn_mtspr(SPR_SYSTEM_SAVE_0_3, t->system_save[3]); 397 400 __insn_mtspr(SPR_INTCTRL_0_STATUS, t->intctrl_0); 398 - #if CHIP_HAS_PROC_STATUS_SPR() 399 401 __insn_mtspr(SPR_PROC_STATUS, t->proc_status); 400 - #endif 401 402 #if !CHIP_HAS_FIXED_INTVEC_BASE() 402 403 __insn_mtspr(SPR_INTERRUPT_VECTOR_BASE_0, t->interrupt_vector_base); 403 404 #endif 404 - #if CHIP_HAS_TILE_RTF_HWM() 405 405 __insn_mtspr(SPR_TILE_RTF_HWM, t->tile_rtf_hwm); 406 - #endif 407 406 #if CHIP_HAS_DSTREAM_PF() 408 407 __insn_mtspr(SPR_DSTREAM_PF, t->dstream_pf); 409 408 #endif ··· 408 415 409 416 void _prepare_arch_switch(struct task_struct *next) 410 417 { 411 - #if CHIP_HAS_SN_PROC() 412 - int snctl; 413 - #endif 414 418 #if CHIP_HAS_TILE_DMA() 415 419 struct tile_dma_state *dma = &current->thread.tile_dma_state; 416 420 if (dma->enabled) 417 421 save_tile_dma_state(dma); 418 - #endif 419 - #if CHIP_HAS_SN_PROC() 420 - /* 421 - * Suspend the static network processor if it was running. 422 - * We do not suspend the fabric itself, just like we don't 423 - * try to suspend the UDN. 424 - */ 425 - snctl = __insn_mfspr(SPR_SNCTL); 426 - current->thread.sn_proc_running = 427 - (snctl & SPR_SNCTL__FRZPROC_MASK) == 0; 428 - if (current->thread.sn_proc_running) 429 - __insn_mtspr(SPR_SNCTL, snctl | SPR_SNCTL__FRZPROC_MASK); 430 422 #endif 431 423 } 432 424 ··· 439 461 440 462 /* Restore other arch state. */ 441 463 restore_arch_state(&next->thread); 442 - 443 - #if CHIP_HAS_SN_PROC() 444 - /* 445 - * Restart static network processor in the new process 446 - * if it was running before. 447 - */ 448 - if (next->thread.sn_proc_running) { 449 - int snctl = __insn_mfspr(SPR_SNCTL); 450 - __insn_mtspr(SPR_SNCTL, snctl & ~SPR_SNCTL__FRZPROC_MASK); 451 - } 452 - #endif 453 464 454 465 #ifdef CONFIG_HARDWALL 455 466 /* Enable or disable access to the network registers appropriately. */ ··· 481 514 schedule(); 482 515 return 1; 483 516 } 484 - #if CHIP_HAS_TILE_DMA() || CHIP_HAS_SN_PROC() 517 + #if CHIP_HAS_TILE_DMA() 485 518 if (thread_info_flags & _TIF_ASYNC_TLB) { 486 519 do_async_page_fault(regs); 487 520 return 1; ··· 531 564 */ 532 565 void exit_thread(void) 533 566 { 534 - /* Nothing */ 567 + #ifdef CONFIG_HARDWALL 568 + /* 569 + * Remove the task from the list of tasks that are associated 570 + * with any live hardwalls. (If the task that is exiting held 571 + * the last reference to a hardwall fd, it would already have 572 + * been released and deactivated at this point.) 573 + */ 574 + hardwall_deactivate_all(current); 575 + #endif 535 576 } 536 577 537 578 void show_regs(struct pt_regs *regs) ··· 548 573 int i; 549 574 550 575 pr_err("\n"); 551 - show_regs_print_info(KERN_ERR); 576 + if (tsk != &corrupt_current) 577 + show_regs_print_info(KERN_ERR); 552 578 #ifdef __tilegx__ 553 - for (i = 0; i < 51; i += 3) 579 + for (i = 0; i < 17; i++) 554 580 pr_err(" r%-2d: "REGFMT" r%-2d: "REGFMT" r%-2d: "REGFMT"\n", 555 - i, regs->regs[i], i+1, regs->regs[i+1], 556 - i+2, regs->regs[i+2]); 557 - pr_err(" r51: "REGFMT" r52: "REGFMT" tp : "REGFMT"\n", 558 - regs->regs[51], regs->regs[52], regs->tp); 581 + i, regs->regs[i], i+18, regs->regs[i+18], 582 + i+36, regs->regs[i+36]); 583 + pr_err(" r17: "REGFMT" r35: "REGFMT" tp : "REGFMT"\n", 584 + regs->regs[17], regs->regs[35], regs->tp); 559 585 pr_err(" sp : "REGFMT" lr : "REGFMT"\n", regs->sp, regs->lr); 560 586 #else 561 - for (i = 0; i < 52; i += 4) 587 + for (i = 0; i < 13; i++) 562 588 pr_err(" r%-2d: "REGFMT" r%-2d: "REGFMT 563 589 " r%-2d: "REGFMT" r%-2d: "REGFMT"\n", 564 - i, regs->regs[i], i+1, regs->regs[i+1], 565 - i+2, regs->regs[i+2], i+3, regs->regs[i+3]); 566 - pr_err(" r52: "REGFMT" tp : "REGFMT" sp : "REGFMT" lr : "REGFMT"\n", 567 - regs->regs[52], regs->tp, regs->sp, regs->lr); 590 + i, regs->regs[i], i+14, regs->regs[i+14], 591 + i+27, regs->regs[i+27], i+40, regs->regs[i+40]); 592 + pr_err(" r13: "REGFMT" tp : "REGFMT" sp : "REGFMT" lr : "REGFMT"\n", 593 + regs->regs[13], regs->tp, regs->sp, regs->lr); 568 594 #endif 569 595 pr_err(" pc : "REGFMT" ex1: %ld faultnum: %ld\n", 570 596 regs->pc, regs->ex1, regs->faultnum);
+17 -2
arch/tile/kernel/ptrace.c
··· 265 265 266 266 void 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 283 if (test_thread_flag(TIF_SYSCALL_TRACE)) 269 284 tracehook_report_syscall_exit(regs, 0); 270 285 ··· 287 272 trace_sys_exit(regs, regs->regs[0]); 288 273 } 289 274 290 - void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code) 275 + void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs) 291 276 { 292 277 struct siginfo info; 293 278 ··· 303 288 /* Handle synthetic interrupt delivered only by the simulator. */ 304 289 void __kprobes do_breakpoint(struct pt_regs* regs, int fault_num) 305 290 { 306 - send_sigtrap(current, regs, fault_num); 291 + send_sigtrap(current, regs); 307 292 }
-2
arch/tile/kernel/reboot.c
··· 27 27 28 28 void machine_halt(void) 29 29 { 30 - warn_early_printk(); 31 30 arch_local_irq_disable_all(); 32 31 smp_send_stop(); 33 32 hv_halt(); ··· 34 35 35 36 void machine_power_off(void) 36 37 { 37 - warn_early_printk(); 38 38 arch_local_irq_disable_all(); 39 39 smp_send_stop(); 40 40 hv_power_off();
+2 -2
arch/tile/kernel/regs_32.S
··· 20 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 24 * "prev" is returned in r0 for _switch_to and also for ret_from_fork. 25 25 * 26 26 * We want to save pc/sp in "prev", and get the new pc/sp from "next". ··· 39 39 */ 40 40 41 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 43 #endif 44 44 #define FRAME_SIZE ((2 + CALLEE_SAVED_REGS_COUNT) * 4) 45 45
+2 -2
arch/tile/kernel/regs_64.S
··· 20 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 24 * "prev" is returned in r0 for _switch_to and also for ret_from_fork. 25 25 * 26 26 * We want to save pc/sp in "prev", and get the new pc/sp from "next". ··· 39 39 */ 40 40 41 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 43 #endif 44 44 #define FRAME_SIZE ((2 + CALLEE_SAVED_REGS_COUNT) * 8) 45 45
+8 -19
arch/tile/kernel/relocate_kernel_32.S
··· 20 20 #include <asm/page.h> 21 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 23 #undef RELOCATE_NEW_KERNEL_VERBOSE 33 24 34 25 STD_ENTRY(relocate_new_kernel) ··· 34 43 addi sp, sp, -8 35 44 /* we now have a stack (whether we need one or not) */ 36 45 37 - moveli r40, lo16(___hv_console_putc) 38 - auli r40, r40, ha16(___hv_console_putc) 46 + moveli r40, lo16(hv_console_putc) 47 + auli r40, r40, ha16(hv_console_putc) 39 48 40 49 #ifdef RELOCATE_NEW_KERNEL_VERBOSE 41 50 moveli r0, 'r' ··· 77 86 move r30, sp 78 87 addi sp, sp, -8 79 88 80 - #if CHIP_HAS_CBOX_HOME_MAP() 81 89 /* 82 90 * On TILEPro, we need to flush all tiles' caches, since we may 83 91 * have been doing hash-for-home caching there. Note that we ··· 104 114 } 105 115 { 106 116 move r8, zero /* asids */ 107 - moveli r20, lo16(___hv_flush_remote) 117 + moveli r20, lo16(hv_flush_remote) 108 118 } 109 119 { 110 120 move r9, zero /* asidcount */ 111 - auli r20, r20, ha16(___hv_flush_remote) 121 + auli r20, r20, ha16(hv_flush_remote) 112 122 } 113 123 114 124 jalr r20 115 - #endif 116 125 117 126 /* r33 is destination pointer, default to zero */ 118 127 ··· 164 175 move r0, r32 165 176 moveli r1, 0 /* arg to hv_reexec is 64 bits */ 166 177 167 - moveli r41, lo16(___hv_reexec) 168 - auli r41, r41, ha16(___hv_reexec) 178 + moveli r41, lo16(hv_reexec) 179 + auli r41, r41, ha16(hv_reexec) 169 180 170 181 jalr r41 171 182 ··· 256 267 moveli r0, '\n' 257 268 jalr r40 258 269 .Lhalt: 259 - moveli r41, lo16(___hv_halt) 260 - auli r41, r41, ha16(___hv_halt) 270 + moveli r41, lo16(hv_halt) 271 + auli r41, r41, ha16(hv_halt) 261 272 262 273 jalr r41 263 274 STD_ENDPROC(relocate_new_kernel)
+7 -4
arch/tile/kernel/relocate_kernel_64.S
··· 34 34 addi sp, sp, -8 35 35 /* we now have a stack (whether we need one or not) */ 36 36 37 + #ifdef RELOCATE_NEW_KERNEL_VERBOSE 37 38 moveli r40, hw2_last(hv_console_putc) 38 39 shl16insli r40, r40, hw1(hv_console_putc) 39 40 shl16insli r40, r40, hw0(hv_console_putc) 40 41 41 - #ifdef RELOCATE_NEW_KERNEL_VERBOSE 42 42 moveli r0, 'r' 43 43 jalr r40 44 44 ··· 78 78 move r30, sp 79 79 addi sp, sp, -16 80 80 81 - #if CHIP_HAS_CBOX_HOME_MAP() 82 81 /* 83 82 * On TILE-GX, we need to flush all tiles' caches, since we may 84 83 * have been doing hash-for-home caching there. Note that we ··· 115 116 shl16insli r20, r20, hw0(hv_flush_remote) 116 117 117 118 jalr r20 118 - #endif 119 119 120 120 /* r33 is destination pointer, default to zero */ 121 121 ··· 174 176 175 177 /* we should not get here */ 176 178 179 + #ifdef RELOCATE_NEW_KERNEL_VERBOSE 177 180 moveli r0, '?' 178 181 jalr r40 179 182 moveli r0, '\n' 180 183 jalr r40 184 + #endif 181 185 182 186 j .Lhalt 183 187 ··· 237 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 243 jalr r40 242 244 moveli r0, 'r' 243 245 jalr r40 ··· 247 245 jalr r40 248 246 moveli r0, '\n' 249 247 jalr r40 248 + #endif 250 249 .Lhalt: 251 250 moveli r41, hw2_last(hv_halt) 252 251 shl16insli r41, r41, hw1(hv_halt)
+134 -28
arch/tile/kernel/setup.c
··· 154 154 } 155 155 early_param("maxnodemem", setup_maxnodemem); 156 156 157 + struct memmap_entry { 158 + u64 addr; /* start of memory segment */ 159 + u64 size; /* size of memory segment */ 160 + }; 161 + static struct memmap_entry memmap_map[64]; 162 + static int memmap_nr; 163 + 164 + static 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 + 175 + static 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 + } 208 + early_param("memmap", setup_memmap); 209 + 210 + static int __init setup_mem(char *str) 211 + { 212 + return setup_maxmem(str); 213 + } 214 + early_param("mem", setup_mem); /* compatibility with x86 */ 215 + 157 216 static int __init setup_isolnodes(char *str) 158 217 { 159 218 char buf[MAX_NUMNODES * 5]; ··· 268 209 /* 269 210 * Determine for each controller where its lowmem is mapped and how much of 270 211 * it is mapped there. On controller zero, the first few megabytes are 271 - * already mapped in as code at MEM_SV_INTRPT, so in principle we could 212 + * already mapped in as code at MEM_SV_START, so in principle we could 272 213 * start our data mappings higher up, but for now we don't bother, to avoid 273 214 * additional confusion. 274 215 * ··· 673 614 /* 674 615 * Throw away any memory aliased by the PCI region. 675 616 */ 676 - if (pci_reserve_start_pfn < end && pci_reserve_end_pfn > start) 677 - reserve_bootmem(PFN_PHYS(pci_reserve_start_pfn), 678 - PFN_PHYS(pci_reserve_end_pfn - 679 - pci_reserve_start_pfn), 617 + if (pci_reserve_start_pfn < end && pci_reserve_end_pfn > start) { 618 + start = max(pci_reserve_start_pfn, start); 619 + end = min(pci_reserve_end_pfn, end); 620 + reserve_bootmem(PFN_PHYS(start), PFN_PHYS(end - start), 680 621 BOOTMEM_EXCLUSIVE); 622 + } 681 623 #endif 682 624 } 683 625 ··· 687 627 int i; 688 628 for (i = 0; i < MAX_NUMNODES; ++i) 689 629 setup_bootmem_allocator_node(i); 630 + 631 + /* Reserve any memory excluded by "memmap" arguments. */ 632 + for (i = 0; i < memmap_nr; ++i) { 633 + struct memmap_entry *m = &memmap_map[i]; 634 + reserve_bootmem(m->addr, m->size, 0); 635 + } 636 + 637 + #ifdef CONFIG_BLK_DEV_INITRD 638 + if (initrd_start) { 639 + /* Make sure the initrd memory region is not modified. */ 640 + if (reserve_bootmem(initrd_start, initrd_end - initrd_start, 641 + BOOTMEM_EXCLUSIVE)) { 642 + pr_crit("The initrd memory region has been polluted. Disabling it.\n"); 643 + initrd_start = 0; 644 + initrd_end = 0; 645 + } else { 646 + /* 647 + * Translate initrd_start & initrd_end from PA to VA for 648 + * future access. 649 + */ 650 + initrd_start += PAGE_OFFSET; 651 + initrd_end += PAGE_OFFSET; 652 + } 653 + } 654 + #endif 690 655 691 656 #ifdef CONFIG_KEXEC 692 657 if (crashk_res.start != crashk_res.end) ··· 1046 961 arch_local_irq_unmask(INT_DMATLB_MISS); 1047 962 arch_local_irq_unmask(INT_DMATLB_ACCESS); 1048 963 #endif 1049 - #if CHIP_HAS_SN_PROC() 1050 - arch_local_irq_unmask(INT_SNITLB_MISS); 1051 - #endif 1052 964 #ifdef __tilegx__ 1053 965 arch_local_irq_unmask(INT_SINGLE_STEP_K); 1054 966 #endif ··· 1059 977 #if CHIP_HAS_SN() 1060 978 /* Static network is not restricted. */ 1061 979 __insn_mtspr(SPR_MPL_SN_ACCESS_SET_0, 1); 1062 - #endif 1063 - #if CHIP_HAS_SN_PROC() 1064 - __insn_mtspr(SPR_MPL_SN_NOTIFY_SET_0, 1); 1065 - __insn_mtspr(SPR_MPL_SN_CPL_SET_0, 1); 1066 980 #endif 1067 981 1068 982 /* ··· 1107 1029 int fd, rc; 1108 1030 void *initrd; 1109 1031 1032 + /* If initrd has already been set, skip initramfs file in hvfs. */ 1033 + if (initrd_start) 1034 + return; 1035 + 1110 1036 fd = hv_fs_findfile((HV_VirtAddr) initramfs_file); 1111 1037 if (fd == HV_ENOENT) { 1112 1038 if (set_initramfs_file) { ··· 1148 1066 { 1149 1067 free_bootmem(__pa(begin), end - begin); 1150 1068 } 1069 + 1070 + static int __init setup_initrd(char *str) 1071 + { 1072 + char *endp; 1073 + unsigned long initrd_size; 1074 + 1075 + initrd_size = str ? simple_strtoul(str, &endp, 0) : 0; 1076 + if (initrd_size == 0 || *endp != '@') 1077 + return -EINVAL; 1078 + 1079 + initrd_start = simple_strtoul(endp+1, &endp, 0); 1080 + if (initrd_start == 0) 1081 + return -EINVAL; 1082 + 1083 + initrd_end = initrd_start + initrd_size; 1084 + 1085 + return 0; 1086 + } 1087 + early_param("initrd", setup_initrd); 1151 1088 1152 1089 #else 1153 1090 static inline void load_hv_initrd(void) {} ··· 1235 1134 #ifndef __tilegx__ /* FIXME: GX: probably some validation relevant here */ 1236 1135 /* 1237 1136 * Similarly, make sure we're only using allowed VAs. 1238 - * We assume we can contiguously use MEM_USER_INTRPT .. MEM_HV_INTRPT, 1137 + * We assume we can contiguously use MEM_USER_INTRPT .. MEM_HV_START, 1239 1138 * and 0 .. KERNEL_HIGH_VADDR. 1240 1139 * In addition, make sure we CAN'T use the end of memory, since 1241 1140 * we use the last chunk of each pgd for the pgd_list. ··· 1250 1149 if (range.size == 0) 1251 1150 break; 1252 1151 if (range.start <= MEM_USER_INTRPT && 1253 - range.start + range.size >= MEM_HV_INTRPT) 1152 + range.start + range.size >= MEM_HV_START) 1254 1153 user_kernel_ok = 1; 1255 1154 if (range.start == 0) 1256 1155 max_va = range.size; ··· 1284 1183 struct cpumask __write_once cpu_lotar_map; 1285 1184 EXPORT_SYMBOL(cpu_lotar_map); 1286 1185 1287 - #if CHIP_HAS_CBOX_HOME_MAP() 1288 1186 /* 1289 1187 * hash_for_home_map lists all the tiles that hash-for-home data 1290 1188 * will be cached on. Note that this may includes tiles that are not ··· 1293 1193 */ 1294 1194 struct cpumask hash_for_home_map; 1295 1195 EXPORT_SYMBOL(hash_for_home_map); 1296 - #endif 1297 1196 1298 1197 /* 1299 1198 * cpu_cacheable_map lists all the cpus whose caches the hypervisor can ··· 1385 1286 cpu_lotar_map = *cpu_possible_mask; 1386 1287 } 1387 1288 1388 - #if CHIP_HAS_CBOX_HOME_MAP() 1389 1289 /* Retrieve set of CPUs used for hash-for-home caching */ 1390 1290 rc = hv_inquire_tiles(HV_INQ_TILES_HFH_CACHE, 1391 1291 (HV_VirtAddr) hash_for_home_map.bits, ··· 1392 1294 if (rc < 0) 1393 1295 early_panic("hv_inquire_tiles(HFH_CACHE) failed: rc %d\n", rc); 1394 1296 cpumask_or(&cpu_cacheable_map, cpu_possible_mask, &hash_for_home_map); 1395 - #else 1396 - cpu_cacheable_map = *cpu_possible_mask; 1397 - #endif 1398 1297 } 1399 1298 1400 1299 ··· 1587 1492 1588 1493 /* Update the vmalloc mapping and page home. */ 1589 1494 unsigned long addr = (unsigned long)ptr + i; 1590 - pte_t *ptep = virt_to_pte(NULL, addr); 1495 + pte_t *ptep = virt_to_kpte(addr); 1591 1496 pte_t pte = *ptep; 1592 1497 BUG_ON(pfn != pte_pfn(pte)); 1593 1498 pte = hv_pte_set_mode(pte, HV_PTE_MODE_CACHE_TILE_L3); ··· 1596 1501 1597 1502 /* Update the lowmem mapping for consistency. */ 1598 1503 lowmem_va = (unsigned long)pfn_to_kaddr(pfn); 1599 - ptep = virt_to_pte(NULL, lowmem_va); 1504 + ptep = virt_to_kpte(lowmem_va); 1600 1505 if (pte_huge(*ptep)) { 1601 1506 printk(KERN_DEBUG "early shatter of huge page" 1602 1507 " at %#lx\n", lowmem_va); 1603 1508 shatter_pmd((pmd_t *)ptep); 1604 - ptep = virt_to_pte(NULL, lowmem_va); 1509 + ptep = virt_to_kpte(lowmem_va); 1605 1510 BUG_ON(pte_huge(*ptep)); 1606 1511 } 1607 1512 BUG_ON(pfn != pte_pfn(*ptep)); ··· 1643 1548 { 1644 1549 struct resource *res = 1645 1550 kzalloc(sizeof(struct resource), GFP_ATOMIC); 1551 + if (!res) 1552 + return NULL; 1646 1553 res->name = "Non-Bus Physical Address Space"; 1647 1554 res->start = (1ULL << 32); 1648 1555 res->end = -1LL; ··· 1658 1561 #endif 1659 1562 1660 1563 static struct resource* __init 1661 - insert_ram_resource(u64 start_pfn, u64 end_pfn) 1564 + insert_ram_resource(u64 start_pfn, u64 end_pfn, bool reserved) 1662 1565 { 1663 1566 struct resource *res = 1664 1567 kzalloc(sizeof(struct resource), GFP_ATOMIC); 1665 - res->name = "System RAM"; 1568 + if (!res) 1569 + return NULL; 1570 + res->name = reserved ? "Reserved" : "System RAM"; 1666 1571 res->start = start_pfn << PAGE_SHIFT; 1667 1572 res->end = (end_pfn << PAGE_SHIFT) - 1; 1668 1573 res->flags = IORESOURCE_BUSY | IORESOURCE_MEM; ··· 1684 1585 static int __init request_standard_resources(void) 1685 1586 { 1686 1587 int i; 1687 - enum { CODE_DELTA = MEM_SV_INTRPT - PAGE_OFFSET }; 1588 + enum { CODE_DELTA = MEM_SV_START - PAGE_OFFSET }; 1688 1589 1689 1590 #if defined(CONFIG_PCI) && !defined(__tilegx__) 1690 1591 insert_non_bus_resource(); ··· 1699 1600 end_pfn > pci_reserve_start_pfn) { 1700 1601 if (end_pfn > pci_reserve_end_pfn) 1701 1602 insert_ram_resource(pci_reserve_end_pfn, 1702 - end_pfn); 1603 + end_pfn, 0); 1703 1604 end_pfn = pci_reserve_start_pfn; 1704 1605 } 1705 1606 #endif 1706 - insert_ram_resource(start_pfn, end_pfn); 1607 + insert_ram_resource(start_pfn, end_pfn, 0); 1707 1608 } 1708 1609 1709 1610 code_resource.start = __pa(_text - CODE_DELTA); ··· 1713 1614 1714 1615 insert_resource(&iomem_resource, &code_resource); 1715 1616 insert_resource(&iomem_resource, &data_resource); 1617 + 1618 + /* Mark any "memmap" regions busy for the resource manager. */ 1619 + for (i = 0; i < memmap_nr; ++i) { 1620 + struct memmap_entry *m = &memmap_map[i]; 1621 + insert_ram_resource(PFN_DOWN(m->addr), 1622 + PFN_UP(m->addr + m->size - 1), 1); 1623 + } 1716 1624 1717 1625 #ifdef CONFIG_KEXEC 1718 1626 insert_resource(&iomem_resource, &crashk_res);
+2 -1
arch/tile/kernel/signal.c
··· 33 33 #include <asm/ucontext.h> 34 34 #include <asm/sigframe.h> 35 35 #include <asm/syscalls.h> 36 + #include <asm/vdso.h> 36 37 #include <arch/interrupts.h> 37 38 38 39 #define DEBUG_SIG 0 ··· 191 190 if (err) 192 191 goto give_sigsegv; 193 192 194 - restorer = VDSO_BASE; 193 + restorer = VDSO_SYM(&__vdso_rt_sigreturn); 195 194 if (ka->sa.sa_flags & SA_RESTORER) 196 195 restorer = (unsigned long) ka->sa.sa_restorer; 197 196
+63 -55
arch/tile/kernel/single_step.c
··· 12 12 * more details. 13 13 * 14 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. */ 19 - 20 - /* These functions are only used on the TILE platform */ 17 + #include <linux/smp.h> 18 + #include <linux/ptrace.h> 21 19 #include <linux/slab.h> 22 20 #include <linux/thread_info.h> 23 21 #include <linux/uaccess.h> 24 22 #include <linux/mman.h> 25 23 #include <linux/types.h> 26 24 #include <linux/err.h> 25 + #include <linux/prctl.h> 27 26 #include <asm/cacheflush.h> 27 + #include <asm/traps.h> 28 + #include <asm/uaccess.h> 28 29 #include <asm/unaligned.h> 29 30 #include <arch/abi.h> 31 + #include <arch/spr_def.h> 30 32 #include <arch/opcode.h> 33 + 34 + 35 + #ifndef __tilegx__ /* Hardware support for single step unavailable. */ 31 36 32 37 #define signExtend17(val) sign_extend((val), 17) 33 38 #define TILE_X1_MASK (0xffffffffULL << 31) 34 - 35 - int unaligned_printk; 36 - 37 - static int __init setup_unaligned_printk(char *str) 38 - { 39 - long val; 40 - if (strict_strtol(str, 0, &val) != 0) 41 - return 0; 42 - unaligned_printk = val; 43 - pr_info("Printk for each unaligned data accesses is %s\n", 44 - unaligned_printk ? "enabled" : "disabled"); 45 - return 1; 46 - } 47 - __setup("unaligned_printk=", setup_unaligned_printk); 48 - 49 - unsigned int unaligned_fixup_count; 50 39 51 40 enum mem_op { 52 41 MEMOP_NONE, ··· 45 56 MEMOP_STORE_POSTINCR 46 57 }; 47 58 48 - static inline tile_bundle_bits set_BrOff_X1(tile_bundle_bits n, s32 offset) 59 + static inline tilepro_bundle_bits set_BrOff_X1(tilepro_bundle_bits n, 60 + s32 offset) 49 61 { 50 - tile_bundle_bits result; 62 + tilepro_bundle_bits result; 51 63 52 64 /* mask out the old offset */ 53 - tile_bundle_bits mask = create_BrOff_X1(-1); 65 + tilepro_bundle_bits mask = create_BrOff_X1(-1); 54 66 result = n & (~mask); 55 67 56 68 /* or in the new offset */ ··· 60 70 return result; 61 71 } 62 72 63 - static inline tile_bundle_bits move_X1(tile_bundle_bits n, int dest, int src) 73 + static inline tilepro_bundle_bits move_X1(tilepro_bundle_bits n, int dest, 74 + int src) 64 75 { 65 - tile_bundle_bits result; 66 - tile_bundle_bits op; 76 + tilepro_bundle_bits result; 77 + tilepro_bundle_bits op; 67 78 68 79 result = n & (~TILE_X1_MASK); 69 80 ··· 78 87 return result; 79 88 } 80 89 81 - static inline tile_bundle_bits nop_X1(tile_bundle_bits n) 90 + static inline tilepro_bundle_bits nop_X1(tilepro_bundle_bits n) 82 91 { 83 92 return move_X1(n, TREG_ZERO, TREG_ZERO); 84 93 } 85 94 86 - static inline tile_bundle_bits addi_X1( 87 - tile_bundle_bits n, int dest, int src, int imm) 95 + static inline tilepro_bundle_bits addi_X1( 96 + tilepro_bundle_bits n, int dest, int src, int imm) 88 97 { 89 98 n &= ~TILE_X1_MASK; 90 99 ··· 98 107 return n; 99 108 } 100 109 101 - static tile_bundle_bits rewrite_load_store_unaligned( 110 + static tilepro_bundle_bits rewrite_load_store_unaligned( 102 111 struct single_step_state *state, 103 - tile_bundle_bits bundle, 112 + tilepro_bundle_bits bundle, 104 113 struct pt_regs *regs, 105 114 enum mem_op mem_op, 106 115 int size, int sign_ext) 107 116 { 108 117 unsigned char __user *addr; 109 118 int val_reg, addr_reg, err, val; 119 + int align_ctl; 120 + 121 + align_ctl = unaligned_fixup; 122 + switch (task_thread_info(current)->align_ctl) { 123 + case PR_UNALIGN_NOPRINT: 124 + align_ctl = 1; 125 + break; 126 + case PR_UNALIGN_SIGBUS: 127 + align_ctl = 0; 128 + break; 129 + } 110 130 111 131 /* Get address and value registers */ 112 132 if (bundle & TILEPRO_BUNDLE_Y_ENCODING_MASK) { ··· 162 160 * tilepro hardware would be doing, if it could provide us with the 163 161 * actual bad address in an SPR, which it doesn't. 164 162 */ 165 - if (unaligned_fixup == 0) { 163 + if (align_ctl == 0) { 166 164 siginfo_t info = { 167 165 .si_signo = SIGBUS, 168 166 .si_code = BUS_ADRALN, ··· 211 209 212 210 if (err) { 213 211 siginfo_t info = { 214 - .si_signo = SIGSEGV, 215 - .si_code = SEGV_MAPERR, 212 + .si_signo = SIGBUS, 213 + .si_code = BUS_ADRALN, 216 214 .si_addr = addr 217 215 }; 218 - trace_unhandled_signal("segfault", regs, 219 - (unsigned long)addr, SIGSEGV); 216 + trace_unhandled_signal("bad address for unaligned fixup", regs, 217 + (unsigned long)addr, SIGBUS); 220 218 force_sig_info(info.si_signo, &info, current); 221 - return (tile_bundle_bits) 0; 219 + return (tilepro_bundle_bits) 0; 222 220 } 223 221 224 222 if (unaligned_printk || unaligned_fixup_count == 0) { ··· 287 285 ti->step_state = NULL; 288 286 } 289 287 290 - /** 288 + /* 291 289 * single_step_once() - entry point when single stepping has been triggered. 292 290 * @regs: The machine register state 293 291 * ··· 306 304 */ 307 305 void single_step_once(struct pt_regs *regs) 308 306 { 309 - extern tile_bundle_bits __single_step_ill_insn; 310 - extern tile_bundle_bits __single_step_j_insn; 311 - extern tile_bundle_bits __single_step_addli_insn; 312 - extern tile_bundle_bits __single_step_auli_insn; 307 + extern tilepro_bundle_bits __single_step_ill_insn; 308 + extern tilepro_bundle_bits __single_step_j_insn; 309 + extern tilepro_bundle_bits __single_step_addli_insn; 310 + extern tilepro_bundle_bits __single_step_auli_insn; 313 311 struct thread_info *info = (void *)current_thread_info(); 314 312 struct single_step_state *state = info->step_state; 315 313 int is_single_step = test_ti_thread_flag(info, TIF_SINGLESTEP); 316 - tile_bundle_bits __user *buffer, *pc; 317 - tile_bundle_bits bundle; 314 + tilepro_bundle_bits __user *buffer, *pc; 315 + tilepro_bundle_bits bundle; 318 316 int temp_reg; 319 317 int target_reg = TREG_LR; 320 318 int err; 321 319 enum mem_op mem_op = MEMOP_NONE; 322 320 int size = 0, sign_ext = 0; /* happy compiler */ 321 + int align_ctl; 322 + 323 + align_ctl = unaligned_fixup; 324 + switch (task_thread_info(current)->align_ctl) { 325 + case PR_UNALIGN_NOPRINT: 326 + align_ctl = 1; 327 + break; 328 + case PR_UNALIGN_SIGBUS: 329 + align_ctl = 0; 330 + break; 331 + } 323 332 324 333 asm( 325 334 " .pushsection .rodata.single_step\n" ··· 403 390 if (regs->faultnum == INT_SWINT_1) 404 391 regs->pc -= 8; 405 392 406 - pc = (tile_bundle_bits __user *)(regs->pc); 393 + pc = (tilepro_bundle_bits __user *)(regs->pc); 407 394 if (get_user(bundle, pc) != 0) { 408 395 pr_err("Couldn't read instruction at %p trying to step\n", pc); 409 396 return; ··· 546 533 } 547 534 break; 548 535 549 - #if CHIP_HAS_WH64() 550 536 /* postincrement operations */ 551 537 case IMM_0_OPCODE_X1: 552 538 switch (get_ImmOpcodeExtension_X1(bundle)) { ··· 580 568 break; 581 569 } 582 570 break; 583 - #endif /* CHIP_HAS_WH64() */ 584 571 } 585 572 586 573 if (state->update) { ··· 638 627 639 628 /* 640 629 * Check if we need to rewrite an unaligned load/store. 641 - * Returning zero is a special value meaning we need to SIGSEGV. 630 + * Returning zero is a special value meaning we generated a signal. 642 631 */ 643 - if (mem_op != MEMOP_NONE && unaligned_fixup >= 0) { 632 + if (mem_op != MEMOP_NONE && align_ctl >= 0) { 644 633 bundle = rewrite_load_store_unaligned(state, bundle, regs, 645 634 mem_op, size, sign_ext); 646 635 if (bundle == 0) ··· 679 668 } 680 669 681 670 /* End with a jump back to the next instruction */ 682 - delta = ((regs->pc + TILE_BUNDLE_SIZE_IN_BYTES) - 671 + delta = ((regs->pc + TILEPRO_BUNDLE_SIZE_IN_BYTES) - 683 672 (unsigned long)buffer) >> 684 - TILE_LOG2_BUNDLE_ALIGNMENT_IN_BYTES; 673 + TILEPRO_LOG2_BUNDLE_ALIGNMENT_IN_BYTES; 685 674 bundle = __single_step_j_insn; 686 675 bundle |= create_JOffLong_X1(delta); 687 676 err |= __put_user(bundle, buffer++); ··· 709 698 } 710 699 711 700 #else 712 - #include <linux/smp.h> 713 - #include <linux/ptrace.h> 714 - #include <arch/spr_def.h> 715 701 716 702 static DEFINE_PER_CPU(unsigned long, ss_saved_pc); 717 703 ··· 751 743 } else if ((*ss_pc != regs->pc) || 752 744 (!(control & SPR_SINGLE_STEP_CONTROL_1__CANCELED_MASK))) { 753 745 754 - ptrace_notify(SIGTRAP); 755 746 control |= SPR_SINGLE_STEP_CONTROL_1__CANCELED_MASK; 756 747 control |= SPR_SINGLE_STEP_CONTROL_1__INHIBIT_MASK; 757 748 __insn_mtspr(SPR_SINGLE_STEP_CONTROL_K, control); 749 + send_sigtrap(current, regs); 758 750 } 759 751 } 760 752
+17 -5
arch/tile/kernel/smp.c
··· 20 20 #include <linux/irq.h> 21 21 #include <linux/module.h> 22 22 #include <asm/cacheflush.h> 23 + #include <asm/homecache.h> 23 24 24 - HV_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 + */ 29 + HV_Topology smp_topology __write_once __aligned(sizeof(long)); 25 30 EXPORT_SYMBOL(smp_topology); 26 31 27 32 #if CHIP_HAS_IPI() ··· 105 100 /* Handler to stop the current cpu. */ 106 101 static void smp_stop_cpu_interrupt(void) 107 102 { 108 - set_cpu_online(smp_processor_id(), 0); 109 103 arch_local_irq_disable_all(); 104 + set_cpu_online(smp_processor_id(), 0); 110 105 for (;;) 111 106 asm("nap; nop"); 112 107 } ··· 172 167 void flush_icache_range(unsigned long start, unsigned long end) 173 168 { 174 169 struct ipi_flush flush = { start, end }; 175 - preempt_disable(); 176 - on_each_cpu(ipi_flush_icache_range, &flush, 1); 177 - preempt_enable(); 170 + 171 + /* If invoked with irqs disabled, we can not issue IPIs. */ 172 + if (irqs_disabled()) 173 + flush_remote(0, HV_FLUSH_EVICT_L1I, NULL, 0, 0, 0, 174 + NULL, NULL, 0); 175 + else { 176 + preempt_disable(); 177 + on_each_cpu(ipi_flush_icache_range, &flush, 1); 178 + preempt_enable(); 179 + } 178 180 } 179 181 180 182
+5 -3
arch/tile/kernel/smpboot.c
··· 142 142 */ 143 143 static 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 151 /* Set our thread pointer appropriately. */ 148 152 set_my_cpu_offset(__per_cpu_offset[cpuid]); 149 - 150 - preempt_disable(); 151 153 152 154 /* 153 155 * In large machines even this will slow us down, since we
+39 -12
arch/tile/kernel/stack.c
··· 29 29 #include <asm/switch_to.h> 30 30 #include <asm/sigframe.h> 31 31 #include <asm/stack.h> 32 + #include <asm/vdso.h> 32 33 #include <arch/abi.h> 33 34 #include <arch/interrupts.h> 34 35 ··· 103 102 p->sp >= sp) { 104 103 if (kbt->verbose) 105 104 pr_err(" <%s while in kernel mode>\n", fault); 106 - } else if (EX1_PL(p->ex1) == USER_PL && 107 - p->pc < PAGE_OFFSET && 108 - p->sp < PAGE_OFFSET) { 105 + } else if (user_mode(p) && 106 + p->sp < PAGE_OFFSET && p->sp != 0) { 109 107 if (kbt->verbose) 110 108 pr_err(" <%s while in user mode>\n", fault); 111 109 } else if (kbt->verbose) { ··· 120 120 /* Is the pc pointing to a sigreturn trampoline? */ 121 121 static 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 126 /* Return a pt_regs pointer for a valid signal handler frame */ ··· 129 129 { 130 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 133 b->sp % sizeof(long) == 0) { 134 134 int retval; 135 135 pagefault_disable(); ··· 195 195 */ 196 196 static void validate_stack(struct pt_regs *regs) 197 197 { 198 - int cpu = smp_processor_id(); 198 + int cpu = raw_smp_processor_id(); 199 199 unsigned long ksp0 = get_current_ksp0(); 200 - unsigned long ksp0_base = ksp0 - THREAD_SIZE; 200 + unsigned long ksp0_base = ksp0 & -THREAD_SIZE; 201 201 unsigned long sp = stack_pointer; 202 202 203 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 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 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 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 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 + */ 359 + static 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 + 369 + static void end_backtrace(void) 370 + { 371 + current->thread.in_backtrace = false; 372 + } 373 + 374 + /* 355 375 * This method wraps the backtracer's more generic support. 356 376 * It is only invoked from the architecture-specific code; show_stack() 357 377 * and dump_stack() (in entry.S) are architecture-independent entry points. ··· 381 361 int i; 382 362 int have_mmap_sem = 0; 383 363 364 + if (!start_backtrace()) 365 + return; 384 366 if (headers) { 385 367 /* 386 368 * Add a blank line since if we are called from panic(), ··· 393 371 pr_err("Starting stack dump of tid %d, pid %d (%s)" 394 372 " on cpu %d at cycle %lld\n", 395 373 kbt->task->pid, kbt->task->tgid, kbt->task->comm, 396 - smp_processor_id(), get_cycles()); 374 + raw_smp_processor_id(), get_cycles()); 397 375 } 398 376 kbt->verbose = 1; 399 377 i = 0; ··· 424 402 pr_err("Stack dump complete\n"); 425 403 if (have_mmap_sem) 426 404 up_read(&kbt->task->mm->mmap_sem); 405 + end_backtrace(); 427 406 } 428 407 EXPORT_SYMBOL(tile_show_stack); 429 408 ··· 486 463 int skip = trace->skip; 487 464 int i = 0; 488 465 466 + if (!start_backtrace()) 467 + goto done; 489 468 if (task == NULL || task == current) 490 469 KBacktraceIterator_init_current(&kbt); 491 470 else ··· 501 476 break; 502 477 trace->entries[i++] = kbt.it.pc; 503 478 } 479 + end_backtrace(); 480 + done: 504 481 trace->nr_entries = i; 505 482 } 506 483 EXPORT_SYMBOL(save_stack_trace_tsk);
+3 -1
arch/tile/kernel/sys.c
··· 38 38 SYSCALL_DEFINE3(cacheflush, unsigned long, addr, unsigned long, len, 39 39 unsigned long, flags) 40 40 { 41 + /* DCACHE is not particularly effective if not bound to one cpu. */ 41 42 if (flags & DCACHE) 42 - homecache_evict(cpumask_of(smp_processor_id())); 43 + homecache_evict(cpumask_of(raw_smp_processor_id())); 44 + 43 45 if (flags & ICACHE) 44 46 flush_remote(0, HV_FLUSH_EVICT_L1I, mm_cpumask(current->mm), 45 47 0, 0, 0, NULL, NULL, 0);
+76
arch/tile/kernel/sysfs.c
··· 157 157 return count; 158 158 } 159 159 160 + static 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 + 175 + static 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 + 187 + static DEVICE_ATTR(hv_stats, 0644, hv_stats_show, hv_stats_store); 188 + 189 + static 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 + 201 + static 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 + 214 + static 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 + 160 221 static int __init create_sysfs_entries(void) 161 222 { 162 223 int err = 0; ··· 247 186 hvconfig_bin.read = hvconfig_bin_read; 248 187 hvconfig_bin.size = PAGE_SIZE; 249 188 err = sysfs_create_bin_file(hypervisor_kobj, &hvconfig_bin); 189 + } 190 + 191 + if (!err) { 192 + /* 193 + * Don't bother adding the hv_stats files on each CPU if 194 + * our hypervisor doesn't supply statistics. 195 + */ 196 + int cpu = raw_smp_processor_id(); 197 + long lotar = HV_XY_TO_LOTAR(cpu_x(cpu), cpu_y(cpu)); 198 + char dummy; 199 + ssize_t n = hv_confstr(HV_CONFSTR_HV_STATS, 200 + (unsigned long) &dummy, 1, 201 + lotar, 0); 202 + if (n >= 0) 203 + err = subsys_interface_register(&hv_stats_interface); 250 204 } 251 205 252 206 return err;
+36 -1
arch/tile/kernel/time.c
··· 23 23 #include <linux/smp.h> 24 24 #include <linux/delay.h> 25 25 #include <linux/module.h> 26 + #include <linux/timekeeper_internal.h> 26 27 #include <asm/irq_regs.h> 27 28 #include <asm/traps.h> 29 + #include <asm/vdso.h> 28 30 #include <hv/hypervisor.h> 29 31 #include <arch/interrupts.h> 30 32 #include <arch/spr_def.h> ··· 111 109 /* Start up the tile-timer interrupt source on the boot cpu. */ 112 110 setup_tile_timer(); 113 111 } 114 - 115 112 116 113 /* 117 114 * Define the tile timer clock event device. The timer is driven by ··· 237 236 */ 238 237 struct clock_event_device *dev = &__raw_get_cpu_var(tile_timer); 239 238 return ((u64)nsecs * dev->mult) >> dev->shift; 239 + } 240 + 241 + void update_vsyscall_tz(void) 242 + { 243 + /* Userspace gettimeofday will spin while this value is odd. */ 244 + ++vdso_data->tz_update_count; 245 + smp_wmb(); 246 + vdso_data->tz_minuteswest = sys_tz.tz_minuteswest; 247 + vdso_data->tz_dsttime = sys_tz.tz_dsttime; 248 + smp_wmb(); 249 + ++vdso_data->tz_update_count; 250 + } 251 + 252 + void update_vsyscall(struct timekeeper *tk) 253 + { 254 + struct timespec wall_time = tk_xtime(tk); 255 + struct timespec *wtm = &tk->wall_to_monotonic; 256 + struct clocksource *clock = tk->clock; 257 + 258 + if (clock != &cycle_counter_cs) 259 + return; 260 + 261 + /* Userspace gettimeofday will spin while this value is odd. */ 262 + ++vdso_data->tb_update_count; 263 + smp_wmb(); 264 + vdso_data->xtime_tod_stamp = clock->cycle_last; 265 + vdso_data->xtime_clock_sec = wall_time.tv_sec; 266 + vdso_data->xtime_clock_nsec = wall_time.tv_nsec; 267 + vdso_data->wtom_clock_sec = wtm->tv_sec; 268 + vdso_data->wtom_clock_nsec = wtm->tv_nsec; 269 + vdso_data->mult = clock->mult; 270 + vdso_data->shift = clock->shift; 271 + smp_wmb(); 272 + ++vdso_data->tb_update_count; 240 273 }
+7 -1
arch/tile/kernel/tlb.c
··· 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 + */ 94 100 void 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 103 start, end - start, PAGE_SIZE, cpu_online_mask, NULL, 0); 98 104 }
+68 -21
arch/tile/kernel/traps.c
··· 15 15 #include <linux/sched.h> 16 16 #include <linux/kernel.h> 17 17 #include <linux/kprobes.h> 18 + #include <linux/kdebug.h> 18 19 #include <linux/module.h> 19 20 #include <linux/reboot.h> 20 21 #include <linux/uaccess.h> ··· 30 29 31 30 void __init trap_init(void) 32 31 { 33 - /* Nothing needed here since we link code at .intrpt1 */ 32 + /* Nothing needed here since we link code at .intrpt */ 34 33 } 35 34 36 35 int unaligned_fixup = 1; ··· 101 100 102 101 #endif /* CHIP_HAS_TILE_DMA() */ 103 102 104 - #ifdef __tilegx__ 105 - #define bundle_bits tilegx_bundle_bits 106 - #else 107 - #define bundle_bits tile_bundle_bits 108 - #endif 109 - 110 - extern bundle_bits bpt_code; 103 + extern tile_bundle_bits bpt_code; 111 104 112 105 asm(".pushsection .rodata.bpt_code,\"a\";" 113 106 ".align 8;" ··· 109 114 ".size bpt_code,.-bpt_code;" 110 115 ".popsection"); 111 116 112 - static int special_ill(bundle_bits bundle, int *sigp, int *codep) 117 + static int special_ill(tile_bundle_bits bundle, int *sigp, int *codep) 113 118 { 114 119 int sig, code, maxcode; 115 120 ··· 209 214 #endif 210 215 }; 211 216 217 + static int do_bpt(struct pt_regs *regs) 218 + { 219 + unsigned long bundle, bcode, bpt; 220 + 221 + bundle = *(unsigned long *)instruction_pointer(regs); 222 + 223 + /* 224 + * bpt shoule be { bpt; nop }, which is 0x286a44ae51485000ULL. 225 + * we encode the unused least significant bits for other purpose. 226 + */ 227 + bpt = bundle & ~((1ULL << 12) - 1); 228 + if (bpt != TILE_BPT_BUNDLE) 229 + return 0; 230 + 231 + bcode = bundle & ((1ULL << 12) - 1); 232 + /* 233 + * notify the kprobe handlers, if instruction is likely to 234 + * pertain to them. 235 + */ 236 + switch (bcode) { 237 + /* breakpoint_insn */ 238 + case 0: 239 + notify_die(DIE_BREAK, "debug", regs, bundle, 240 + INT_ILL, SIGTRAP); 241 + break; 242 + /* compiled_bpt */ 243 + case DIE_COMPILED_BPT: 244 + notify_die(DIE_COMPILED_BPT, "debug", regs, bundle, 245 + INT_ILL, SIGTRAP); 246 + break; 247 + /* breakpoint2_insn */ 248 + case DIE_SSTEPBP: 249 + notify_die(DIE_SSTEPBP, "single_step", regs, bundle, 250 + INT_ILL, SIGTRAP); 251 + break; 252 + default: 253 + return 0; 254 + } 255 + 256 + return 1; 257 + } 258 + 212 259 void __kprobes do_trap(struct pt_regs *regs, int fault_num, 213 260 unsigned long reason) 214 261 { 215 262 siginfo_t info = { 0 }; 216 263 int signo, code; 217 264 unsigned long address = 0; 218 - bundle_bits instr; 265 + tile_bundle_bits instr; 266 + int is_kernel = !user_mode(regs); 219 267 220 - /* Re-enable interrupts. */ 221 - local_irq_enable(); 268 + /* Handle breakpoints, etc. */ 269 + if (is_kernel && fault_num == INT_ILL && do_bpt(regs)) 270 + return; 271 + 272 + /* Re-enable interrupts, if they were previously enabled. */ 273 + if (!(regs->flags & PT_FLAGS_DISABLE_IRQ)) 274 + local_irq_enable(); 222 275 223 276 /* 224 277 * If it hits in kernel mode and we can't fix it up, just exit the 225 278 * current process and hope for the best. 226 279 */ 227 - if (!user_mode(regs)) { 280 + if (is_kernel) { 228 281 const char *name; 229 - if (fixup_exception(regs)) /* only UNALIGN_DATA in practice */ 282 + char buf[100]; 283 + if (fixup_exception(regs)) /* ILL_TRANS or UNALIGN_DATA */ 230 284 return; 231 285 if (fault_num >= 0 && 232 286 fault_num < sizeof(int_name)/sizeof(int_name[0]) && ··· 283 239 name = int_name[fault_num]; 284 240 else 285 241 name = "Unknown interrupt"; 286 - pr_alert("Kernel took bad trap %d (%s) at PC %#lx\n", 287 - fault_num, name, regs->pc); 288 242 if (fault_num == INT_GPV) 289 - pr_alert("GPV_REASON is %#lx\n", reason); 243 + snprintf(buf, sizeof(buf), "; GPV_REASON %#lx", reason); 244 + #ifdef __tilegx__ 245 + else if (fault_num == INT_ILL_TRANS) 246 + snprintf(buf, sizeof(buf), "; address %#lx", reason); 247 + #endif 248 + else 249 + buf[0] = '\0'; 250 + pr_alert("Kernel took bad trap %d (%s) at PC %#lx%s\n", 251 + fault_num, name, regs->pc, buf); 290 252 show_regs(regs); 291 253 do_exit(SIGKILL); /* FIXME: implement i386 die() */ 292 254 return; ··· 374 324 fill_ra_stack(); 375 325 376 326 signo = SIGSEGV; 327 + address = reason; 377 328 code = SEGV_MAPERR; 378 - if (reason & SPR_ILL_TRANS_REASON__I_STREAM_VA_RMASK) 379 - address = regs->pc; 380 - else 381 - address = 0; /* FIXME: GX: single-step for address */ 382 329 break; 383 330 } 384 331 #endif
+1609
arch/tile/kernel/unaligned.c
··· 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 + 42 + int unaligned_printk; 43 + 44 + static 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 + 56 + unsigned 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 + 66 + struct 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 + 76 + static 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 + 96 + static 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 + 116 + static 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 + 136 + static 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 + 156 + static 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 + 165 + static 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 + 178 + static 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 + 326 + static 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}"); 371 + static 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}"); 379 + static 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}"); 387 + static 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}"); 396 + static 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}"); 404 + static 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}"); 413 + static 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}"); 420 + static 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 + 426 + static 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}"); 433 + static 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 + 439 + static 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}"); 446 + static 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}"); 456 + static 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}"); 464 + static 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}"); 474 + static 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}"); 482 + static 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}"); 492 + static 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}"); 502 + static 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}"); 512 + static 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}"); 521 + static 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}"); 531 + static 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}"); 541 + static 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 + 562 + static 563 + void 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 + 1462 + void 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__ */
+212
arch/tile/kernel/vdso.c
··· 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 + 31 + static unsigned int vdso_pages; 32 + static struct page **vdso_pagelist; 33 + 34 + #ifdef CONFIG_COMPAT 35 + static unsigned int vdso32_pages; 36 + static struct page **vdso32_pagelist; 37 + #endif 38 + static int vdso_ready; 39 + 40 + /* 41 + * The vdso data page. 42 + */ 43 + static union { 44 + struct vdso_data data; 45 + u8 page[PAGE_SIZE]; 46 + } vdso_data_store __page_aligned_data; 47 + 48 + struct vdso_data *vdso_data = &vdso_data_store.data; 49 + 50 + static unsigned int __read_mostly vdso_enabled = 1; 51 + 52 + static 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 + 70 + static 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 + } 111 + arch_initcall(vdso_init); 112 + 113 + const 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 + 124 + struct vm_area_struct *get_gate_vma(struct mm_struct *mm) 125 + { 126 + return NULL; 127 + } 128 + 129 + int in_gate_area(struct mm_struct *mm, unsigned long address) 130 + { 131 + return 0; 132 + } 133 + 134 + int in_gate_area_no_mm(unsigned long address) 135 + { 136 + return 0; 137 + } 138 + 139 + int 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 + 208 + static __init int vdso_func(char *s) 209 + { 210 + return kstrtouint(s, 0, &vdso_enabled); 211 + } 212 + __setup("vdso=", vdso_func);
+118
arch/tile/kernel/vdso/Makefile
··· 1 + # Symbols present in the vdso 2 + vdso-syms = rt_sigreturn gettimeofday 3 + 4 + # Files to link into the vdso 5 + obj-vdso = $(patsubst %, v%.o, $(vdso-syms)) 6 + 7 + # Build rules 8 + targets := $(obj-vdso) vdso.so vdso.so.dbg vdso.lds 9 + obj-vdso := $(addprefix $(obj)/, $(obj-vdso)) 10 + 11 + # vdso32 is only for tilegx -m32 compat task. 12 + VDSO32-$(CONFIG_COMPAT) := y 13 + 14 + obj-y += vdso.o 15 + obj-$(VDSO32-y) += vdso32.o 16 + extra-y += vdso.lds 17 + CPPFLAGS_vdso.lds += -P -C -U$(ARCH) 18 + 19 + # vDSO code runs in userspace and -pg doesn't help with profiling anyway. 20 + CFLAGS_REMOVE_vdso.o = -pg 21 + CFLAGS_REMOVE_vdso32.o = -pg 22 + CFLAGS_REMOVE_vrt_sigreturn.o = -pg 23 + CFLAGS_REMOVE_vrt_sigreturn32.o = -pg 24 + CFLAGS_REMOVE_vgettimeofday.o = -pg 25 + CFLAGS_REMOVE_vgettimeofday32.o = -pg 26 + 27 + ifdef CONFIG_FEEDBACK_COLLECT 28 + # vDSO code runs in userspace, not collecting feedback data. 29 + CFLAGS_REMOVE_vdso.o = -ffeedback-generate 30 + CFLAGS_REMOVE_vdso32.o = -ffeedback-generate 31 + CFLAGS_REMOVE_vrt_sigreturn.o = -ffeedback-generate 32 + CFLAGS_REMOVE_vrt_sigreturn32.o = -ffeedback-generate 33 + CFLAGS_REMOVE_vgettimeofday.o = -ffeedback-generate 34 + CFLAGS_REMOVE_vgettimeofday32.o = -ffeedback-generate 35 + endif 36 + 37 + # Disable gcov profiling for VDSO code 38 + GCOV_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 44 + SYSCFLAGS_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. 52 + extra-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 + 56 + SYSCFLAGS_vdso.so.dbg = -shared -s -Wl,-soname=linux-vdso.so.1 \ 57 + $(call cc-ldoption, -Wl$(comma)--hash-style=sysv) 58 + SYSCFLAGS_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. 72 + quiet_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 79 + quiet_cmd_vdso_install = INSTALL $@ 80 + cmd_vdso_install = cp $(obj)/$@.dbg $(MODLIB)/vdso/$@ 81 + 82 + vdso.so: $(obj)/vdso.so.dbg 83 + @mkdir -p $(MODLIB)/vdso 84 + $(call cmd,vdso_install) 85 + 86 + vdso32.so: $(obj)/vdso32.so.dbg 87 + $(call cmd,vdso_install) 88 + 89 + vdso_install: vdso.so 90 + vdso32_install: vdso32.so 91 + 92 + 93 + KBUILD_AFLAGS_32 := $(filter-out -m64,$(KBUILD_AFLAGS)) 94 + KBUILD_AFLAGS_32 += -m32 -s 95 + KBUILD_CFLAGS_32 := $(filter-out -m64,$(KBUILD_CFLAGS)) 96 + KBUILD_CFLAGS_32 += -m32 -fPIC -shared 97 + 98 + obj-vdso32 = $(patsubst %, v%32.o, $(vdso-syms)) 99 + obj-vdso32 := $(addprefix $(obj)/, $(obj-vdso32)) 100 + 101 + targets += $(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 + 115 + SYSCFLAGS_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)
+28
arch/tile/kernel/vdso/vdso.S
··· 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 23 + vdso_start: 24 + .incbin "arch/tile/kernel/vdso/vdso.so" 25 + .align PAGE_SIZE 26 + vdso_end: 27 + 28 + .previous
+87
arch/tile/kernel/vdso/vdso.lds.S
··· 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 + 18 + OUTPUT_ARCH(tile) 19 + 20 + /* The ELF entry point can be used to set the AT_SYSINFO value. */ 21 + ENTRY(__vdso_rt_sigreturn); 22 + 23 + 24 + SECTIONS 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 + */ 66 + PHDRS 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 + */ 78 + VERSION 79 + { 80 + VDSO_VERSION_STRING { 81 + global: 82 + __vdso_rt_sigreturn; 83 + __vdso_gettimeofday; 84 + gettimeofday; 85 + local:*; 86 + }; 87 + }
+107
arch/tile/kernel/vdso/vgettimeofday.c
··· 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() 21 + static 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 + */ 41 + inline 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 + 53 + int __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 + 106 + int gettimeofday(struct timeval *tv, struct timezone *tz) 107 + __attribute__((weak, alias("__vdso_gettimeofday")));
+30
arch/tile/kernel/vdso/vrt_sigreturn.S
··· 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 + */ 24 + ENTRY(__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)
+13 -18
arch/tile/kernel/vmlinux.lds.S
··· 5 5 #include <hv/hypervisor.h> 6 6 7 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 10 10 OUTPUT_ARCH(tile) 11 11 ENTRY(_start) ··· 13 13 14 14 PHDRS 15 15 { 16 - intrpt1 PT_LOAD ; 16 + intrpt PT_LOAD ; 17 17 text PT_LOAD ; 18 18 data PT_LOAD ; 19 19 } ··· 24 24 #define LOAD_OFFSET TEXT_OFFSET 25 25 26 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 29 _text = .; 30 - *(.intrpt1) 31 - } :intrpt1 =0 30 + *(.intrpt) 31 + } :intrpt =0 32 32 33 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 39 /* Now the real code */ 37 40 . = ALIGN(0x20000); ··· 43 40 HEAD_TEXT 44 41 SCHED_TEXT 45 42 LOCK_TEXT 43 + KPROBES_TEXT 44 + IRQENTRY_TEXT 46 45 __fix_text_end = .; /* tile-cpack won't rearrange before this */ 46 + ALIGN_FUNCTION(); 47 + *(.hottext*) 47 48 TEXT_TEXT 48 49 *(.text.*) 49 50 *(.coldtext*) ··· 74 67 __init_end = .; 75 68 76 69 _sdata = .; /* Start of data section */ 77 - 78 70 RO_DATA_SECTION(PAGE_SIZE) 79 - 80 - /* initially writeable, then read-only */ 81 - . = ALIGN(PAGE_SIZE); 82 - __w1data_begin = .; 83 - .w1data : AT(ADDR(.w1data) - LOAD_OFFSET) { 84 - VMLINUX_SYMBOL(__w1data_begin) = .; 85 - *(.w1data) 86 - VMLINUX_SYMBOL(__w1data_end) = .; 87 - } 88 - 89 71 RW_DATA_SECTION(L2_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE) 90 - 91 72 _edata = .; 92 73 93 74 EXCEPTION_TABLE(L2_CACHE_BYTES)
+8 -8
arch/tile/lib/Makefile
··· 4 4 5 5 lib-y = cacheflush.o checksum.o cpumask.o delay.o uaccess.o \ 6 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 8 9 - ifeq ($(CONFIG_TILEGX),y) 10 - CFLAGS_REMOVE_memcpy_user_64.o = -fno-omit-frame-pointer 11 - lib-y += memcpy_user_64.o 12 - else 13 - lib-y += atomic_32.o atomic_asm_32.o memcpy_tile64.o 14 - endif 15 - 9 + lib-$(CONFIG_TILEGX) += memcpy_user_64.o 10 + lib-$(CONFIG_TILEPRO) += atomic_32.o atomic_asm_32.o 16 11 lib-$(CONFIG_SMP) += spinlock_$(BITS).o usercopy_$(BITS).o 17 12 18 13 obj-$(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. 17 + CFLAGS_REMOVE_cacheflush.o = -pg 18 + CFLAGS_REMOVE_memcpy_user_64.o = -pg
+16 -117
arch/tile/lib/atomic_32.c
··· 20 20 #include <linux/atomic.h> 21 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 - */ 30 - struct atomic_locks_on_cpu { 31 - int lock[ATOMIC_HASH_L2_SIZE]; 32 - } __attribute__((aligned(ATOMIC_HASH_L2_SIZE * 4))); 33 - 34 - static 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. */ 37 - static 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. */ 40 - struct 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 23 /* This page is remapped on startup to be hash-for-home. */ 48 24 int atomic_locks[PAGE_SIZE / sizeof(int)] __page_aligned_bss; 49 - 50 - #endif /* ATOMIC_LOCKS_FOUND_VIA_TABLE() */ 51 25 52 26 int *__atomic_hashed_lock(volatile void *v) 53 27 { 54 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 30 * Use bits [3, 3 + ATOMIC_HASH_SHIFT) as the lock index. 69 31 * Using mm works here because atomic_locks is page aligned. ··· 34 72 (unsigned long)atomic_locks, 35 73 2, (ATOMIC_HASH_SHIFT + 2) - 1); 36 74 return (int *)ptr; 37 - #endif 38 75 } 39 76 40 77 #ifdef CONFIG_SMP 41 78 /* Return whether the passed pointer is a valid atomic lock pointer. */ 42 79 static int is_atomic_lock(int *p) 43 80 { 44 - #if ATOMIC_LOCKS_FOUND_VIA_TABLE() 45 - int i; 46 - for (i = 0; i < ATOMIC_HASH_L1_SIZE; ++i) { 47 - 48 - if (p >= &atomic_lock_ptr[i]->lock[0] && 49 - p < &atomic_lock_ptr[i]->lock[ATOMIC_HASH_L2_SIZE]) { 50 - return 1; 51 - } 52 - } 53 - return 0; 54 - #else 55 81 return p >= &atomic_locks[0] && p < &atomic_locks[ATOMIC_HASH_SIZE]; 56 - #endif 57 82 } 58 83 59 84 void __atomic_fault_unlock(int *irqlock_word) ··· 59 110 return __atomic_hashed_lock(v); 60 111 } 61 112 62 - int _atomic_xchg(atomic_t *v, int n) 113 + int _atomic_xchg(int *v, int n) 63 114 { 64 - return __atomic_xchg(&v->counter, __atomic_setup(v), n).val; 115 + return __atomic_xchg(v, __atomic_setup(v), n).val; 65 116 } 66 117 EXPORT_SYMBOL(_atomic_xchg); 67 118 68 - int _atomic_xchg_add(atomic_t *v, int i) 119 + int _atomic_xchg_add(int *v, int i) 69 120 { 70 - return __atomic_xchg_add(&v->counter, __atomic_setup(v), i).val; 121 + return __atomic_xchg_add(v, __atomic_setup(v), i).val; 71 122 } 72 123 EXPORT_SYMBOL(_atomic_xchg_add); 73 124 74 - int _atomic_xchg_add_unless(atomic_t *v, int a, int u) 125 + int _atomic_xchg_add_unless(int *v, int a, int u) 75 126 { 76 127 /* 77 128 * Note: argument order is switched here since it is easier 78 129 * to use the first argument consistently as the "old value" 79 130 * in the assembly, as is done for _atomic_cmpxchg(). 80 131 */ 81 - return __atomic_xchg_add_unless(&v->counter, __atomic_setup(v), u, a) 82 - .val; 132 + return __atomic_xchg_add_unless(v, __atomic_setup(v), u, a).val; 83 133 } 84 134 EXPORT_SYMBOL(_atomic_xchg_add_unless); 85 135 86 - int _atomic_cmpxchg(atomic_t *v, int o, int n) 136 + int _atomic_cmpxchg(int *v, int o, int n) 87 137 { 88 - return __atomic_cmpxchg(&v->counter, __atomic_setup(v), o, n).val; 138 + return __atomic_cmpxchg(v, __atomic_setup(v), o, n).val; 89 139 } 90 140 EXPORT_SYMBOL(_atomic_cmpxchg); 91 141 ··· 107 159 EXPORT_SYMBOL(_atomic_xor); 108 160 109 161 110 - u64 _atomic64_xchg(atomic64_t *v, u64 n) 162 + u64 _atomic64_xchg(u64 *v, u64 n) 111 163 { 112 - return __atomic64_xchg(&v->counter, __atomic_setup(v), n); 164 + return __atomic64_xchg(v, __atomic_setup(v), n); 113 165 } 114 166 EXPORT_SYMBOL(_atomic64_xchg); 115 167 116 - u64 _atomic64_xchg_add(atomic64_t *v, u64 i) 168 + u64 _atomic64_xchg_add(u64 *v, u64 i) 117 169 { 118 - return __atomic64_xchg_add(&v->counter, __atomic_setup(v), i); 170 + return __atomic64_xchg_add(v, __atomic_setup(v), i); 119 171 } 120 172 EXPORT_SYMBOL(_atomic64_xchg_add); 121 173 122 - u64 _atomic64_xchg_add_unless(atomic64_t *v, u64 a, u64 u) 174 + u64 _atomic64_xchg_add_unless(u64 *v, u64 a, u64 u) 123 175 { 124 176 /* 125 177 * Note: argument order is switched here since it is easier 126 178 * to use the first argument consistently as the "old value" 127 179 * in the assembly, as is done for _atomic_cmpxchg(). 128 180 */ 129 - return __atomic64_xchg_add_unless(&v->counter, __atomic_setup(v), 130 - u, a); 181 + return __atomic64_xchg_add_unless(v, __atomic_setup(v), u, a); 131 182 } 132 183 EXPORT_SYMBOL(_atomic64_xchg_add_unless); 133 184 134 - u64 _atomic64_cmpxchg(atomic64_t *v, u64 o, u64 n) 185 + u64 _atomic64_cmpxchg(u64 *v, u64 o, u64 n) 135 186 { 136 - return __atomic64_cmpxchg(&v->counter, __atomic_setup(v), o, n); 187 + return __atomic64_cmpxchg(v, __atomic_setup(v), o, n); 137 188 } 138 189 EXPORT_SYMBOL(_atomic64_cmpxchg); 139 190 ··· 155 208 } 156 209 157 210 158 - #if CHIP_HAS_CBOX_HOME_MAP() 159 - static int __init noatomichash(char *str) 160 - { 161 - pr_warning("noatomichash is deprecated.\n"); 162 - return 1; 163 - } 164 - __setup("noatomichash", noatomichash); 165 - #endif 166 - 167 211 void __init __init_atomic_per_cpu(void) 168 212 { 169 - #if ATOMIC_LOCKS_FOUND_VIA_TABLE() 170 - 171 - unsigned int i; 172 - int actual_cpu; 173 - 174 - /* 175 - * Before this is called from setup, we just have one lock for 176 - * all atomic objects/operations. Here we replace the 177 - * elements of atomic_lock_ptr so that they point at per_cpu 178 - * integers. This seemingly over-complex approach stems from 179 - * the fact that DEFINE_PER_CPU defines an entry for each cpu 180 - * in the grid, not each cpu from 0..ATOMIC_HASH_SIZE-1. But 181 - * for efficient hashing of atomics to their locks we want a 182 - * compile time constant power of 2 for the size of this 183 - * table, so we use ATOMIC_HASH_SIZE. 184 - * 185 - * Here we populate atomic_lock_ptr from the per cpu 186 - * atomic_lock_pool, interspersing by actual cpu so that 187 - * subsequent elements are homed on consecutive cpus. 188 - */ 189 - 190 - actual_cpu = cpumask_first(cpu_possible_mask); 191 - 192 - for (i = 0; i < ATOMIC_HASH_L1_SIZE; ++i) { 193 - /* 194 - * Preincrement to slightly bias against using cpu 0, 195 - * which has plenty of stuff homed on it already. 196 - */ 197 - actual_cpu = cpumask_next(actual_cpu, cpu_possible_mask); 198 - if (actual_cpu >= nr_cpu_ids) 199 - actual_cpu = cpumask_first(cpu_possible_mask); 200 - 201 - atomic_lock_ptr[i] = &per_cpu(atomic_lock_pool, actual_cpu); 202 - } 203 - 204 - #else /* ATOMIC_LOCKS_FOUND_VIA_TABLE() */ 205 - 206 213 /* Validate power-of-two and "bigger than cpus" assumption */ 207 214 BUILD_BUG_ON(ATOMIC_HASH_SIZE & (ATOMIC_HASH_SIZE-1)); 208 215 BUG_ON(ATOMIC_HASH_SIZE < nr_cpu_ids); ··· 180 279 * That should not produce more indices than ATOMIC_HASH_SIZE. 181 280 */ 182 281 BUILD_BUG_ON((PAGE_SIZE >> 3) > ATOMIC_HASH_SIZE); 183 - 184 - #endif /* ATOMIC_LOCKS_FOUND_VIA_TABLE() */ 185 282 }
+1
arch/tile/lib/atomic_asm_32.S
··· 164 164 STD_ENDPROC(__atomic\name) 165 165 .ifc \bitwidth,32 166 166 .pushsection __ex_table,"a" 167 + .align 4 167 168 .word 1b, __atomic\name 168 169 .word 2b, __atomic\name 169 170 .word __atomic\name, __atomic_bad_address
+10 -6
arch/tile/lib/cacheflush.c
··· 36 36 * core (if "!hfh") or homed via hash-for-home (if "hfh"), waiting 37 37 * until the memory controller holds the flushed values. 38 38 */ 39 - void finv_buffer_remote(void *buffer, size_t size, int hfh) 39 + void __attribute__((optimize("omit-frame-pointer"))) 40 + finv_buffer_remote(void *buffer, size_t size, int hfh) 40 41 { 41 42 char *p, *base; 42 43 size_t step_size, load_count; ··· 148 147 force_load(p); 149 148 150 149 /* 151 - * Repeat, but with inv's instead of loads, to get rid of the 150 + * Repeat, but with finv's instead of loads, to get rid of the 152 151 * data we just loaded into our own cache and the old home L3. 153 - * No need to unroll since inv's don't target a register. 152 + * No need to unroll since finv's don't target a register. 153 + * The finv's are guaranteed not to actually flush the data in 154 + * the buffer back to their home, since we just read it, so the 155 + * lines are clean in cache; we will only invalidate those lines. 154 156 */ 155 157 p = (char *)buffer + size - 1; 156 - __insn_inv(p); 158 + __insn_finv(p); 157 159 p -= step_size; 158 160 p = (char *)((unsigned long)p | (step_size - 1)); 159 161 for (; p >= base; p -= step_size) 160 - __insn_inv(p); 162 + __insn_finv(p); 161 163 162 - /* Wait for the load+inv's (and thus finvs) to have completed. */ 164 + /* Wait for these finv's (and thus the first finvs) to be done. */ 163 165 __insn_mf(); 164 166 165 167 #ifdef __tilegx__
+6 -1
arch/tile/lib/exports.c
··· 22 22 EXPORT_SYMBOL(strncpy_from_user_asm); 23 23 EXPORT_SYMBOL(clear_user_asm); 24 24 EXPORT_SYMBOL(flush_user_asm); 25 - EXPORT_SYMBOL(inv_user_asm); 26 25 EXPORT_SYMBOL(finv_user_asm); 27 26 28 27 /* arch/tile/kernel/entry.S */ ··· 32 33 33 34 /* arch/tile/kernel/head.S */ 34 35 EXPORT_SYMBOL(empty_zero_page); 36 + 37 + #ifdef CONFIG_FUNCTION_TRACER 38 + /* arch/tile/kernel/mcount_64.S */ 39 + #include <asm/ftrace.h> 40 + EXPORT_SYMBOL(__mcount); 41 + #endif /* CONFIG_FUNCTION_TRACER */ 35 42 36 43 /* arch/tile/lib/, various memcpy files */ 37 44 EXPORT_SYMBOL(memcpy);
+1 -1
arch/tile/lib/memchr_64.c
··· 36 36 p = (const uint64_t *)(s_int & -8); 37 37 38 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 41 /* Read the first word, but munge it so that bytes before the array 42 42 * will not match goal.
+2 -61
arch/tile/lib/memcpy_32.S
··· 22 22 23 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 25 #define IS_MEMCPY 0 34 26 #define IS_COPY_FROM_USER 1 35 27 #define IS_COPY_FROM_USER_ZEROING 2 ··· 36 44 */ 37 45 #define EX \ 38 46 .pushsection __ex_table, "a"; \ 47 + .align 4; \ 39 48 .word 9f, memcpy_common_fixup; \ 40 49 .popsection; \ 41 50 9 ··· 151 158 152 159 { addi r3, r1, 60; andi r9, r9, -64 } 153 160 154 - #if CHIP_HAS_WH64() 155 161 /* No need to prefetch dst, we'll just do the wh64 156 162 * right before we copy a line. 157 163 */ 158 - #endif 159 - 160 164 EX: { lw r5, r3; addi r3, r3, 64; movei r4, 1 } 161 165 /* Intentionally stall for a few cycles to leave L2 cache alone. */ 162 166 { bnzt zero, .; move r27, lr } ··· 161 171 /* Intentionally stall for a few cycles to leave L2 cache alone. */ 162 172 { bnzt zero, . } 163 173 EX: { lw r7, r3; addi r3, r3, 64 } 164 - #if !CHIP_HAS_WH64() 165 - /* Prefetch the dest */ 166 - /* Intentionally stall for a few cycles to leave L2 cache alone. */ 167 - { bnzt zero, . } 168 - /* Use a real load to cause a TLB miss if necessary. We aren't using 169 - * r28, so this should be fine. 170 - */ 171 - EX: { lw r28, r9; addi r9, r9, 64 } 172 - /* Intentionally stall for a few cycles to leave L2 cache alone. */ 173 - { bnzt zero, . } 174 - { prefetch r9; addi r9, r9, 64 } 175 - /* Intentionally stall for a few cycles to leave L2 cache alone. */ 176 - { bnzt zero, . } 177 - { prefetch r9; addi r9, r9, 64 } 178 - #endif 179 174 /* Intentionally stall for a few cycles to leave L2 cache alone. */ 180 175 { bz zero, .Lbig_loop2 } 181 176 ··· 261 286 /* Fill second L1D line. */ 262 287 EX: { lw r17, r17; addi r1, r1, 48; mvz r3, r13, r1 } /* r17 = WORD_4 */ 263 288 264 - #if CHIP_HAS_WH64() 265 289 /* Prepare destination line for writing. */ 266 290 EX: { wh64 r9; addi r9, r9, 64 } 267 - #else 268 - /* Prefetch dest line */ 269 - { prefetch r9; addi r9, r9, 64 } 270 - #endif 271 291 /* Load seven words that are L1D hits to cover wh64 L2 usage. */ 272 292 273 293 /* Load the three remaining words from the last L1D line, which ··· 300 330 EX: { sw r0, r16; addi r0, r0, 4; add r16, r0, r2 } /* store(WORD_0) */ 301 331 EX: { sw r0, r13; addi r0, r0, 4; andi r16, r16, -64 } /* store(WORD_1) */ 302 332 EX: { sw r0, r14; addi r0, r0, 4; slt_u r16, r9, r16 } /* store(WORD_2) */ 303 - #if CHIP_HAS_WH64() 304 333 EX: { sw r0, r15; addi r0, r0, 4; addi r13, sp, -64 } /* store(WORD_3) */ 305 - #else 306 - /* Back up the r9 to a cache line we are already storing to 307 - * if it gets past the end of the dest vector. Strictly speaking, 308 - * we don't need to back up to the start of a cache line, but it's free 309 - * and tidy, so why not? 310 - */ 311 - EX: { sw r0, r15; addi r0, r0, 4; andi r13, r0, -64 } /* store(WORD_3) */ 312 - #endif 313 334 /* Store second L1D line. */ 314 335 EX: { sw r0, r17; addi r0, r0, 4; mvz r9, r16, r13 }/* store(WORD_4) */ 315 336 EX: { sw r0, r19; addi r0, r0, 4 } /* store(WORD_5) */ ··· 364 403 365 404 .Ldest_is_word_aligned: 366 405 367 - #if CHIP_HAS_DWORD_ALIGN() 368 406 EX: { andi r8, r0, 63; lwadd_na r6, r1, 4} 369 407 { slti_u r9, r2, 64; bz r8, .Ldest_is_L2_line_aligned } 370 408 ··· 471 511 /* Move r1 back to the point where it corresponds to r0. */ 472 512 { addi r1, r1, -4 } 473 513 474 - #else /* !CHIP_HAS_DWORD_ALIGN() */ 475 - 476 - /* Compute right/left shift counts and load initial source words. */ 477 - { andi r5, r1, -4; andi r3, r1, 3 } 478 - EX: { lw r6, r5; addi r5, r5, 4; shli r3, r3, 3 } 479 - EX: { lw r7, r5; addi r5, r5, 4; sub r4, zero, r3 } 480 - 481 - /* Load and store one word at a time, using shifts and ORs 482 - * to correct for the misaligned src. 483 - */ 484 - .Lcopy_unaligned_src_loop: 485 - { shr r6, r6, r3; shl r8, r7, r4 } 486 - EX: { lw r7, r5; or r8, r8, r6; move r6, r7 } 487 - EX: { sw r0, r8; addi r0, r0, 4; addi r2, r2, -4 } 488 - { addi r5, r5, 4; slti_u r8, r2, 8 } 489 - { bzt r8, .Lcopy_unaligned_src_loop; addi r1, r1, 4 } 490 - 491 - { bz r2, .Lcopy_unaligned_done } 492 - #endif /* !CHIP_HAS_DWORD_ALIGN() */ 493 - 494 514 /* Fall through */ 495 515 496 516 /* ··· 554 614 .size memcpy_common_fixup, . - memcpy_common_fixup 555 615 556 616 .section __ex_table,"a" 617 + .align 4 557 618 .word .Lcfu, .Lcopy_from_user_fixup_zero_remainder 558 619 .word .Lctu, .Lcopy_to_user_fixup_done
+193 -65
arch/tile/lib/memcpy_64.c
··· 18 18 /* EXPORT_SYMBOL() is in arch/tile/lib/exports.c since this should be asm. */ 19 19 20 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 24 - #error "Assumes 64 or 128 byte line size" 23 + /* Threshold value for when to enter the unrolled loops. */ 24 + #define OP_T_THRES 16 25 + 26 + #if CHIP_L2_LINE_SIZE() != 64 27 + #error "Assumes 64 byte line size" 25 28 #endif 26 29 27 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 34 * Provide "base versions" of load and store for the normal code path. ··· 54 51 * macros to return a count of uncopied bytes due to mm fault. 55 52 */ 56 53 #define RETVAL 0 57 - int USERCOPY_FUNC(void *__restrict dstv, const void *__restrict srcv, size_t n) 54 + int __attribute__((optimize("omit-frame-pointer"))) 55 + USERCOPY_FUNC(void *__restrict dstv, const void *__restrict srcv, size_t n) 58 56 #endif 59 57 { 60 58 char *__restrict dst1 = (char *)dstv; 61 59 const char *__restrict src1 = (const char *)srcv; 62 60 const char *__restrict src1_end; 63 61 const char *__restrict prefetch; 64 - word_t *__restrict dst8; /* 8-byte pointer to destination memory. */ 65 - word_t final; /* Final bytes to write to trailing word, if any */ 62 + op_t *__restrict dst8; /* 8-byte pointer to destination memory. */ 63 + op_t final; /* Final bytes to write to trailing word, if any */ 66 64 long i; 67 65 68 66 if (n < 16) { ··· 83 79 for (i = 0; i < PREFETCH_LINES_AHEAD; i++) { 84 80 __insn_prefetch(prefetch); 85 81 prefetch += CHIP_L2_LINE_SIZE(); 86 - prefetch = (prefetch > src1_end) ? prefetch : src1; 82 + prefetch = (prefetch < src1_end) ? prefetch : src1; 87 83 } 88 84 89 85 /* Copy bytes until dst is word-aligned. */ 90 - for (; (uintptr_t)dst1 & (sizeof(word_t) - 1); n--) 86 + for (; (uintptr_t)dst1 & (sizeof(op_t) - 1); n--) 91 87 ST1(dst1++, LD1(src1++)); 92 88 93 89 /* 8-byte pointer to destination memory. */ 94 - dst8 = (word_t *)dst1; 90 + dst8 = (op_t *)dst1; 95 91 96 - if (__builtin_expect((uintptr_t)src1 & (sizeof(word_t) - 1), 0)) { 97 - /* 98 - * Misaligned copy. Copy 8 bytes at a time, but don't 99 - * bother with other fanciness. 100 - * 101 - * TODO: Consider prefetching and using wh64 as well. 102 - */ 92 + if (__builtin_expect((uintptr_t)src1 & (sizeof(op_t) - 1), 0)) { 93 + /* Unaligned copy. */ 103 94 104 - /* Create an aligned src8. */ 105 - const word_t *__restrict src8 = 106 - (const word_t *)((uintptr_t)src1 & -sizeof(word_t)); 107 - word_t b; 95 + op_t tmp0 = 0, tmp1 = 0, tmp2, tmp3; 96 + const op_t *src8 = (const op_t *) ((uintptr_t)src1 & 97 + -sizeof(op_t)); 98 + const void *srci = (void *)src1; 99 + int m; 108 100 109 - word_t a = LD8(src8++); 110 - for (; n >= sizeof(word_t); n -= sizeof(word_t)) { 111 - b = LD8(src8++); 112 - a = __insn_dblalign(a, b, src1); 113 - ST8(dst8++, a); 114 - a = b; 101 + m = (CHIP_L2_LINE_SIZE() << 2) - 102 + (((uintptr_t)dst8) & ((CHIP_L2_LINE_SIZE() << 2) - 1)); 103 + m = (n < m) ? n : m; 104 + m /= sizeof(op_t); 105 + 106 + /* Copy until 'dst' is cache-line-aligned. */ 107 + n -= (sizeof(op_t) * m); 108 + 109 + switch (m % 4) { 110 + case 0: 111 + if (__builtin_expect(!m, 0)) 112 + goto _M0; 113 + tmp1 = LD8(src8++); 114 + tmp2 = LD8(src8++); 115 + goto _8B3; 116 + case 2: 117 + m += 2; 118 + tmp3 = LD8(src8++); 119 + tmp0 = LD8(src8++); 120 + goto _8B1; 121 + case 3: 122 + m += 1; 123 + tmp2 = LD8(src8++); 124 + tmp3 = LD8(src8++); 125 + goto _8B2; 126 + case 1: 127 + m--; 128 + tmp0 = LD8(src8++); 129 + tmp1 = LD8(src8++); 130 + if (__builtin_expect(!m, 0)) 131 + goto _8B0; 132 + } 133 + 134 + do { 135 + tmp2 = LD8(src8++); 136 + tmp0 = __insn_dblalign(tmp0, tmp1, srci); 137 + ST8(dst8++, tmp0); 138 + _8B3: 139 + tmp3 = LD8(src8++); 140 + tmp1 = __insn_dblalign(tmp1, tmp2, srci); 141 + ST8(dst8++, tmp1); 142 + _8B2: 143 + tmp0 = LD8(src8++); 144 + tmp2 = __insn_dblalign(tmp2, tmp3, srci); 145 + ST8(dst8++, tmp2); 146 + _8B1: 147 + tmp1 = LD8(src8++); 148 + tmp3 = __insn_dblalign(tmp3, tmp0, srci); 149 + ST8(dst8++, tmp3); 150 + m -= 4; 151 + } while (m); 152 + 153 + _8B0: 154 + tmp0 = __insn_dblalign(tmp0, tmp1, srci); 155 + ST8(dst8++, tmp0); 156 + src8--; 157 + 158 + _M0: 159 + if (__builtin_expect(n >= CHIP_L2_LINE_SIZE(), 0)) { 160 + op_t tmp4, tmp5, tmp6, tmp7, tmp8; 161 + 162 + prefetch = ((const char *)src8) + 163 + CHIP_L2_LINE_SIZE() * PREFETCH_LINES_AHEAD; 164 + 165 + for (tmp0 = LD8(src8++); n >= CHIP_L2_LINE_SIZE(); 166 + n -= CHIP_L2_LINE_SIZE()) { 167 + /* Prefetch and advance to next line to 168 + prefetch, but don't go past the end. */ 169 + __insn_prefetch(prefetch); 170 + 171 + /* Make sure prefetch got scheduled 172 + earlier. */ 173 + __asm__ ("" : : : "memory"); 174 + 175 + prefetch += CHIP_L2_LINE_SIZE(); 176 + prefetch = (prefetch < src1_end) ? prefetch : 177 + (const char *) src8; 178 + 179 + tmp1 = LD8(src8++); 180 + tmp2 = LD8(src8++); 181 + tmp3 = LD8(src8++); 182 + tmp4 = LD8(src8++); 183 + tmp5 = LD8(src8++); 184 + tmp6 = LD8(src8++); 185 + tmp7 = LD8(src8++); 186 + tmp8 = LD8(src8++); 187 + 188 + tmp0 = __insn_dblalign(tmp0, tmp1, srci); 189 + tmp1 = __insn_dblalign(tmp1, tmp2, srci); 190 + tmp2 = __insn_dblalign(tmp2, tmp3, srci); 191 + tmp3 = __insn_dblalign(tmp3, tmp4, srci); 192 + tmp4 = __insn_dblalign(tmp4, tmp5, srci); 193 + tmp5 = __insn_dblalign(tmp5, tmp6, srci); 194 + tmp6 = __insn_dblalign(tmp6, tmp7, srci); 195 + tmp7 = __insn_dblalign(tmp7, tmp8, srci); 196 + 197 + __insn_wh64(dst8); 198 + 199 + ST8(dst8++, tmp0); 200 + ST8(dst8++, tmp1); 201 + ST8(dst8++, tmp2); 202 + ST8(dst8++, tmp3); 203 + ST8(dst8++, tmp4); 204 + ST8(dst8++, tmp5); 205 + ST8(dst8++, tmp6); 206 + ST8(dst8++, tmp7); 207 + 208 + tmp0 = tmp8; 209 + } 210 + src8--; 211 + } 212 + 213 + /* Copy the rest 8-byte chunks. */ 214 + if (n >= sizeof(op_t)) { 215 + tmp0 = LD8(src8++); 216 + for (; n >= sizeof(op_t); n -= sizeof(op_t)) { 217 + tmp1 = LD8(src8++); 218 + tmp0 = __insn_dblalign(tmp0, tmp1, srci); 219 + ST8(dst8++, tmp0); 220 + tmp0 = tmp1; 221 + } 222 + src8--; 115 223 } 116 224 117 225 if (n == 0) 118 226 return RETVAL; 119 227 120 - b = ((const char *)src8 <= src1_end) ? *src8 : 0; 228 + tmp0 = LD8(src8++); 229 + tmp1 = ((const char *)src8 <= src1_end) 230 + ? LD8((op_t *)src8) : 0; 231 + final = __insn_dblalign(tmp0, tmp1, srci); 121 232 122 - /* 123 - * Final source bytes to write to trailing partial 124 - * word, if any. 125 - */ 126 - final = __insn_dblalign(a, b, src1); 127 233 } else { 128 234 /* Aligned copy. */ 129 235 130 - const word_t* __restrict src8 = (const word_t *)src1; 236 + const op_t *__restrict src8 = (const op_t *)src1; 131 237 132 238 /* src8 and dst8 are both word-aligned. */ 133 239 if (n >= CHIP_L2_LINE_SIZE()) { 134 240 /* Copy until 'dst' is cache-line-aligned. */ 135 241 for (; (uintptr_t)dst8 & (CHIP_L2_LINE_SIZE() - 1); 136 - n -= sizeof(word_t)) 242 + n -= sizeof(op_t)) 137 243 ST8(dst8++, LD8(src8++)); 138 244 139 245 for (; n >= CHIP_L2_LINE_SIZE(); ) { 140 - __insn_wh64(dst8); 246 + op_t tmp0, tmp1, tmp2, tmp3; 247 + op_t tmp4, tmp5, tmp6, tmp7; 141 248 142 249 /* 143 250 * Prefetch and advance to next line 144 - * to prefetch, but don't go past the end 251 + * to prefetch, but don't go past the 252 + * end. 145 253 */ 146 254 __insn_prefetch(prefetch); 255 + 256 + /* Make sure prefetch got scheduled 257 + earlier. */ 258 + __asm__ ("" : : : "memory"); 259 + 147 260 prefetch += CHIP_L2_LINE_SIZE(); 148 - prefetch = (prefetch > src1_end) ? prefetch : 261 + prefetch = (prefetch < src1_end) ? prefetch : 149 262 (const char *)src8; 150 263 151 264 /* 152 - * Copy an entire cache line. Manually 153 - * unrolled to avoid idiosyncracies of 154 - * compiler unrolling. 265 + * Do all the loads before wh64. This 266 + * is necessary if [src8, src8+7] and 267 + * [dst8, dst8+7] share the same cache 268 + * line and dst8 <= src8, as can be 269 + * the case when called from memmove, 270 + * or with code tested on x86 whose 271 + * memcpy always works with forward 272 + * copies. 155 273 */ 156 - #define COPY_WORD(offset) ({ ST8(dst8+offset, LD8(src8+offset)); n -= 8; }) 157 - COPY_WORD(0); 158 - COPY_WORD(1); 159 - COPY_WORD(2); 160 - COPY_WORD(3); 161 - COPY_WORD(4); 162 - COPY_WORD(5); 163 - COPY_WORD(6); 164 - COPY_WORD(7); 165 - #if CHIP_L2_LINE_SIZE() == 128 166 - COPY_WORD(8); 167 - COPY_WORD(9); 168 - COPY_WORD(10); 169 - COPY_WORD(11); 170 - COPY_WORD(12); 171 - COPY_WORD(13); 172 - COPY_WORD(14); 173 - COPY_WORD(15); 174 - #elif CHIP_L2_LINE_SIZE() != 64 175 - # error Fix code that assumes particular L2 cache line sizes 176 - #endif 274 + tmp0 = LD8(src8++); 275 + tmp1 = LD8(src8++); 276 + tmp2 = LD8(src8++); 277 + tmp3 = LD8(src8++); 278 + tmp4 = LD8(src8++); 279 + tmp5 = LD8(src8++); 280 + tmp6 = LD8(src8++); 281 + tmp7 = LD8(src8++); 177 282 178 - dst8 += CHIP_L2_LINE_SIZE() / sizeof(word_t); 179 - src8 += CHIP_L2_LINE_SIZE() / sizeof(word_t); 283 + /* wh64 and wait for tmp7 load completion. */ 284 + __asm__ ("move %0, %0; wh64 %1\n" 285 + : : "r"(tmp7), "r"(dst8)); 286 + 287 + ST8(dst8++, tmp0); 288 + ST8(dst8++, tmp1); 289 + ST8(dst8++, tmp2); 290 + ST8(dst8++, tmp3); 291 + ST8(dst8++, tmp4); 292 + ST8(dst8++, tmp5); 293 + ST8(dst8++, tmp6); 294 + ST8(dst8++, tmp7); 295 + 296 + n -= CHIP_L2_LINE_SIZE(); 180 297 } 298 + #if CHIP_L2_LINE_SIZE() != 64 299 + # error "Fix code that assumes particular L2 cache line size." 300 + #endif 181 301 } 182 302 183 - for (; n >= sizeof(word_t); n -= sizeof(word_t)) 303 + for (; n >= sizeof(op_t); n -= sizeof(op_t)) 184 304 ST8(dst8++, LD8(src8++)); 185 305 186 306 if (__builtin_expect(n == 0, 1))
-276
arch/tile/lib/memcpy_tile64.c
··· 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 */ 29 - extern unsigned long __memcpy_asm(void *to, const void *from, unsigned long n); 30 - extern unsigned long __copy_to_user_inatomic_asm( 31 - void __user *to, const void *from, unsigned long n); 32 - extern unsigned long __copy_from_user_inatomic_asm( 33 - void *to, const void __user *from, unsigned long n); 34 - extern unsigned long __copy_from_user_zeroing_asm( 35 - void *to, const void __user *from, unsigned long n); 36 - 37 - typedef 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 - */ 60 - static 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 - */ 137 - static 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? */ 152 - retry_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? */ 179 - retry_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 - 241 - void *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 - 249 - unsigned 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 - 258 - unsigned 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 - 267 - unsigned 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() */
+2
arch/tile/lib/memcpy_user_64.c
··· 31 31 ".pushsection .coldtext.memcpy,\"ax\";" \ 32 32 "2: { move r0, %2; jrp lr };" \ 33 33 ".section __ex_table,\"a\";" \ 34 + ".align 8;" \ 34 35 ".quad 1b, 2b;" \ 35 36 ".popsection" \ 36 37 : "=m" (*(p)) : "r" (v), "r" (n)); \ ··· 44 43 ".pushsection .coldtext.memcpy,\"ax\";" \ 45 44 "2: { move r0, %2; jrp lr };" \ 46 45 ".section __ex_table,\"a\";" \ 46 + ".align 8;" \ 47 47 ".quad 1b, 2b;" \ 48 48 ".popsection" \ 49 49 : "=r" (__v) : "m" (*(p)), "r" (n)); \
+1 -109
arch/tile/lib/memset_32.c
··· 12 12 * more details. 13 13 */ 14 14 15 - #include <arch/chip.h> 16 - 17 15 #include <linux/types.h> 18 16 #include <linux/string.h> 19 17 #include <linux/module.h> 20 - 21 - #undef memset 18 + #include <arch/chip.h> 22 19 23 20 void *memset(void *s, int c, size_t n) 24 21 { ··· 23 26 int n32; 24 27 uint32_t v16, v32; 25 28 uint8_t *out8 = s; 26 - #if !CHIP_HAS_WH64() 27 - int ahead32; 28 - #else 29 29 int to_align32; 30 - #endif 31 30 32 31 /* Experimentation shows that a trivial tight loop is a win up until 33 32 * around a size of 20, where writing a word at a time starts to win. ··· 54 61 return s; 55 62 } 56 63 57 - #if !CHIP_HAS_WH64() 58 - /* Use a spare issue slot to start prefetching the first cache 59 - * line early. This instruction is free as the store can be buried 60 - * in otherwise idle issue slots doing ALU ops. 61 - */ 62 - __insn_prefetch(out8); 63 - 64 - /* We prefetch the end so that a short memset that spans two cache 65 - * lines gets some prefetching benefit. Again we believe this is free 66 - * to issue. 67 - */ 68 - __insn_prefetch(&out8[n - 1]); 69 - #endif /* !CHIP_HAS_WH64() */ 70 - 71 - 72 64 /* Align 'out8'. We know n >= 3 so this won't write past the end. */ 73 65 while (((uintptr_t) out8 & 3) != 0) { 74 66 *out8++ = c; ··· 73 95 74 96 /* This must be at least 8 or the following loop doesn't work. */ 75 97 #define CACHE_LINE_SIZE_IN_WORDS (CHIP_L2_LINE_SIZE() / 4) 76 - 77 - #if !CHIP_HAS_WH64() 78 - 79 - ahead32 = CACHE_LINE_SIZE_IN_WORDS; 80 - 81 - /* We already prefetched the first and last cache lines, so 82 - * we only need to do more prefetching if we are storing 83 - * to more than two cache lines. 84 - */ 85 - if (n32 > CACHE_LINE_SIZE_IN_WORDS * 2) { 86 - int i; 87 - 88 - /* Prefetch the next several cache lines. 89 - * This is the setup code for the software-pipelined 90 - * loop below. 91 - */ 92 - #define MAX_PREFETCH 5 93 - ahead32 = n32 & -CACHE_LINE_SIZE_IN_WORDS; 94 - if (ahead32 > MAX_PREFETCH * CACHE_LINE_SIZE_IN_WORDS) 95 - ahead32 = MAX_PREFETCH * CACHE_LINE_SIZE_IN_WORDS; 96 - 97 - for (i = CACHE_LINE_SIZE_IN_WORDS; 98 - i < ahead32; i += CACHE_LINE_SIZE_IN_WORDS) 99 - __insn_prefetch(&out32[i]); 100 - } 101 - 102 - if (n32 > ahead32) { 103 - while (1) { 104 - int j; 105 - 106 - /* Prefetch by reading one word several cache lines 107 - * ahead. Since loads are non-blocking this will 108 - * cause the full cache line to be read while we are 109 - * finishing earlier cache lines. Using a store 110 - * here causes microarchitectural performance 111 - * problems where a victimizing store miss goes to 112 - * the head of the retry FIFO and locks the pipe for 113 - * a few cycles. So a few subsequent stores in this 114 - * loop go into the retry FIFO, and then later 115 - * stores see other stores to the same cache line 116 - * are already in the retry FIFO and themselves go 117 - * into the retry FIFO, filling it up and grinding 118 - * to a halt waiting for the original miss to be 119 - * satisfied. 120 - */ 121 - __insn_prefetch(&out32[ahead32]); 122 - 123 - #if CACHE_LINE_SIZE_IN_WORDS % 4 != 0 124 - #error "Unhandled CACHE_LINE_SIZE_IN_WORDS" 125 - #endif 126 - 127 - n32 -= CACHE_LINE_SIZE_IN_WORDS; 128 - 129 - /* Save icache space by only partially unrolling 130 - * this loop. 131 - */ 132 - for (j = CACHE_LINE_SIZE_IN_WORDS / 4; j > 0; j--) { 133 - *out32++ = v32; 134 - *out32++ = v32; 135 - *out32++ = v32; 136 - *out32++ = v32; 137 - } 138 - 139 - /* To save compiled code size, reuse this loop even 140 - * when we run out of prefetching to do by dropping 141 - * ahead32 down. 142 - */ 143 - if (n32 <= ahead32) { 144 - /* Not even a full cache line left, 145 - * so stop now. 146 - */ 147 - if (n32 < CACHE_LINE_SIZE_IN_WORDS) 148 - break; 149 - 150 - /* Choose a small enough value that we don't 151 - * prefetch past the end. There's no sense 152 - * in touching cache lines we don't have to. 153 - */ 154 - ahead32 = CACHE_LINE_SIZE_IN_WORDS - 1; 155 - } 156 - } 157 - } 158 - 159 - #else /* CHIP_HAS_WH64() */ 160 98 161 99 /* Determine how many words we need to emit before the 'out32' 162 100 * pointer becomes aligned modulo the cache line size. ··· 129 235 */ 130 236 n32 &= CACHE_LINE_SIZE_IN_WORDS - 1; 131 237 } 132 - 133 - #endif /* CHIP_HAS_WH64() */ 134 238 135 239 /* Now handle any leftover values. */ 136 240 if (n32 != 0) {
+3 -6
arch/tile/lib/memset_64.c
··· 12 12 * more details. 13 13 */ 14 14 15 - #include <arch/chip.h> 16 - 17 15 #include <linux/types.h> 18 16 #include <linux/string.h> 19 17 #include <linux/module.h> 20 - 21 - #undef memset 18 + #include <arch/chip.h> 19 + #include "string-endian.h" 22 20 23 21 void *memset(void *s, int c, size_t n) 24 22 { ··· 68 70 n64 = n >> 3; 69 71 70 72 /* Tile input byte out to 64 bits. */ 71 - /* KLUDGE */ 72 - v64 = 0x0101010101010101ULL * (uint8_t)c; 73 + v64 = copy_byte(c); 73 74 74 75 /* This must be at least 8 or the following loop doesn't work. */ 75 76 #define CACHE_LINE_SIZE_IN_DOUBLEWORDS (CHIP_L2_LINE_SIZE() / 8)
-2
arch/tile/lib/strchr_32.c
··· 16 16 #include <linux/string.h> 17 17 #include <linux/module.h> 18 18 19 - #undef strchr 20 - 21 19 char *strchr(const char *s, int c) 22 20 { 23 21 int z, g;
+1 -1
arch/tile/lib/strchr_64.c
··· 26 26 const uint64_t *p = (const uint64_t *)(s_int & -8); 27 27 28 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 31 /* Read the first aligned word, but force bytes before the string to 32 32 * match neither zero nor goal (we make sure the high bit of each
+12 -1
arch/tile/lib/string-endian.h
··· 1 1 /* 2 - * Copyright 2011 Tilera Corporation. All Rights Reserved. 2 + * Copyright 2013 Tilera Corporation. All Rights Reserved. 3 3 * 4 4 * This program is free software; you can redistribute it and/or 5 5 * modify it under the terms of the GNU General Public License ··· 31 31 #define CFZ(x) __insn_clz(x) 32 32 #define REVCZ(x) __insn_ctz(x) 33 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 + */ 41 + static inline uint64_t copy_byte(uint8_t byte) 42 + { 43 + return __insn_shufflebytes(byte, 0, 0); 44 + }
-2
arch/tile/lib/strlen_32.c
··· 16 16 #include <linux/string.h> 17 17 #include <linux/module.h> 18 18 19 - #undef strlen 20 - 21 19 size_t strlen(const char *s) 22 20 { 23 21 /* Get an aligned pointer. */
+47
arch/tile/lib/strnlen_32.c
··· 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 + 19 + size_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 + } 47 + EXPORT_SYMBOL(strnlen);
+48
arch/tile/lib/strnlen_64.c
··· 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 + 20 + size_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 + } 48 + EXPORT_SYMBOL(strnlen);
+12 -24
arch/tile/lib/usercopy_32.S
··· 36 36 { move r0, zero; jrp lr } 37 37 ENDPROC(strnlen_user_fault) 38 38 .section __ex_table,"a" 39 + .align 4 39 40 .word 1b, strnlen_user_fault 40 41 .popsection 41 42 ··· 48 47 */ 49 48 STD_ENTRY(strncpy_from_user_asm) 50 49 { bz r2, 2f; move r3, r0 } 51 - 1: { lb_u r4, r1; addi r1, r1, 1; addi r2, r2, -1 } 50 + 1: { lb_u r4, r1; addi r1, r1, 1; addi r2, r2, -1 } 52 51 { sb r0, r4; addi r0, r0, 1 } 53 - bz r2, 2f 54 - bnzt r4, 1b 55 - addi r0, r0, -1 /* don't count the trailing NUL */ 56 - 2: { sub r0, r0, r3; jrp lr } 52 + bz r4, 2f 53 + bnzt r2, 1b 54 + { sub r0, r0, r3; jrp lr } 55 + 2: addi r0, r0, -1 /* don't count the trailing NUL */ 56 + { sub r0, r0, r3; jrp lr } 57 57 STD_ENDPROC(strncpy_from_user_asm) 58 58 .pushsection .fixup,"ax" 59 59 strncpy_from_user_fault: 60 60 { movei r0, -EFAULT; jrp lr } 61 61 ENDPROC(strncpy_from_user_fault) 62 62 .section __ex_table,"a" 63 + .align 4 63 64 .word 1b, strncpy_from_user_fault 64 65 .popsection 65 66 ··· 80 77 bnzt r1, 1b 81 78 2: { move r0, r1; jrp lr } 82 79 .pushsection __ex_table,"a" 80 + .align 4 83 81 .word 1b, 2b 84 82 .popsection 85 83 ··· 90 86 2: { move r0, r1; jrp lr } 91 87 STD_ENDPROC(clear_user_asm) 92 88 .pushsection __ex_table,"a" 89 + .align 4 93 90 .word 1b, 2b 94 91 .popsection 95 92 ··· 110 105 2: { move r0, r1; jrp lr } 111 106 STD_ENDPROC(flush_user_asm) 112 107 .pushsection __ex_table,"a" 113 - .word 1b, 2b 114 - .popsection 115 - 116 - /* 117 - * inv_user_asm takes the user target address in r0 and the 118 - * number of bytes to invalidate in r1. 119 - * It returns the number of not inv'able bytes (hopefully zero) in r0. 120 - */ 121 - STD_ENTRY(inv_user_asm) 122 - bz r1, 2f 123 - { movei r2, L2_CACHE_BYTES; add r1, r0, r1 } 124 - { sub r2, zero, r2; addi r1, r1, L2_CACHE_BYTES-1 } 125 - { and r0, r0, r2; and r1, r1, r2 } 126 - { sub r1, r1, r0 } 127 - 1: { inv r0; addi r1, r1, -CHIP_INV_STRIDE() } 128 - { addi r0, r0, CHIP_INV_STRIDE(); bnzt r1, 1b } 129 - 2: { move r0, r1; jrp lr } 130 - STD_ENDPROC(inv_user_asm) 131 - .pushsection __ex_table,"a" 108 + .align 4 132 109 .word 1b, 2b 133 110 .popsection 134 111 ··· 130 143 2: { move r0, r1; jrp lr } 131 144 STD_ENDPROC(finv_user_asm) 132 145 .pushsection __ex_table,"a" 146 + .align 4 133 147 .word 1b, 2b 134 148 .popsection
+12 -24
arch/tile/lib/usercopy_64.S
··· 36 36 { move r0, zero; jrp lr } 37 37 ENDPROC(strnlen_user_fault) 38 38 .section __ex_table,"a" 39 + .align 8 39 40 .quad 1b, strnlen_user_fault 40 41 .popsection 41 42 ··· 48 47 */ 49 48 STD_ENTRY(strncpy_from_user_asm) 50 49 { beqz r2, 2f; move r3, r0 } 51 - 1: { ld1u r4, r1; addi r1, r1, 1; addi r2, r2, -1 } 50 + 1: { ld1u r4, r1; addi r1, r1, 1; addi r2, r2, -1 } 52 51 { st1 r0, r4; addi r0, r0, 1 } 53 - beqz r2, 2f 54 - bnezt r4, 1b 55 - addi r0, r0, -1 /* don't count the trailing NUL */ 56 - 2: { sub r0, r0, r3; jrp lr } 52 + beqz r4, 2f 53 + bnezt r2, 1b 54 + { sub r0, r0, r3; jrp lr } 55 + 2: addi r0, r0, -1 /* don't count the trailing NUL */ 56 + { sub r0, r0, r3; jrp lr } 57 57 STD_ENDPROC(strncpy_from_user_asm) 58 58 .pushsection .fixup,"ax" 59 59 strncpy_from_user_fault: 60 60 { movei r0, -EFAULT; jrp lr } 61 61 ENDPROC(strncpy_from_user_fault) 62 62 .section __ex_table,"a" 63 + .align 8 63 64 .quad 1b, strncpy_from_user_fault 64 65 .popsection 65 66 ··· 80 77 bnezt r1, 1b 81 78 2: { move r0, r1; jrp lr } 82 79 .pushsection __ex_table,"a" 80 + .align 8 83 81 .quad 1b, 2b 84 82 .popsection 85 83 ··· 90 86 2: { move r0, r1; jrp lr } 91 87 STD_ENDPROC(clear_user_asm) 92 88 .pushsection __ex_table,"a" 89 + .align 8 93 90 .quad 1b, 2b 94 91 .popsection 95 92 ··· 110 105 2: { move r0, r1; jrp lr } 111 106 STD_ENDPROC(flush_user_asm) 112 107 .pushsection __ex_table,"a" 113 - .quad 1b, 2b 114 - .popsection 115 - 116 - /* 117 - * inv_user_asm takes the user target address in r0 and the 118 - * number of bytes to invalidate in r1. 119 - * It returns the number of not inv'able bytes (hopefully zero) in r0. 120 - */ 121 - STD_ENTRY(inv_user_asm) 122 - beqz r1, 2f 123 - { movei r2, L2_CACHE_BYTES; add r1, r0, r1 } 124 - { sub r2, zero, r2; addi r1, r1, L2_CACHE_BYTES-1 } 125 - { and r0, r0, r2; and r1, r1, r2 } 126 - { sub r1, r1, r0 } 127 - 1: { inv r0; addi r1, r1, -CHIP_INV_STRIDE() } 128 - { addi r0, r0, CHIP_INV_STRIDE(); bnezt r1, 1b } 129 - 2: { move r0, r1; jrp lr } 130 - STD_ENDPROC(inv_user_asm) 131 - .pushsection __ex_table,"a" 108 + .align 8 132 109 .quad 1b, 2b 133 110 .popsection 134 111 ··· 130 143 2: { move r0, r1; jrp lr } 131 144 STD_ENDPROC(finv_user_asm) 132 145 .pushsection __ex_table,"a" 146 + .align 8 133 147 .quad 1b, 2b 134 148 .popsection
+49 -48
arch/tile/mm/elf.c
··· 21 21 #include <asm/pgtable.h> 22 22 #include <asm/pgalloc.h> 23 23 #include <asm/sections.h> 24 - #include <arch/sim_def.h> 24 + #include <asm/vdso.h> 25 + #include <arch/sim.h> 25 26 26 27 /* Notify a running simulator, if any, that an exec just occurred. */ 27 28 static void sim_notify_exec(const char *binary_name) ··· 39 38 40 39 static int notify_exec(struct mm_struct *mm) 41 40 { 42 - int retval = 0; /* failure */ 41 + char *buf, *path; 42 + struct vm_area_struct *vma; 43 43 44 - if (mm->exe_file) { 45 - char *buf = (char *) __get_free_page(GFP_KERNEL); 46 - if (buf) { 47 - char *path = d_path(&mm->exe_file->f_path, 48 - buf, PAGE_SIZE); 49 - if (!IS_ERR(path)) { 50 - sim_notify_exec(path); 51 - retval = 1; 52 - } 53 - free_page((unsigned long)buf); 44 + if (!sim_is_simulator()) 45 + return 1; 46 + 47 + if (mm->exe_file == NULL) 48 + return 0; 49 + 50 + for (vma = current->mm->mmap; ; vma = vma->vm_next) { 51 + if (vma == NULL) 52 + return 0; 53 + if (vma->vm_file == mm->exe_file) 54 + break; 55 + } 56 + 57 + buf = (char *) __get_free_page(GFP_KERNEL); 58 + if (buf == NULL) 59 + return 0; 60 + 61 + path = d_path(&mm->exe_file->f_path, buf, PAGE_SIZE); 62 + if (IS_ERR(path)) { 63 + free_page((unsigned long)buf); 64 + return 0; 65 + } 66 + 67 + /* 68 + * Notify simulator of an ET_DYN object so we know the load address. 69 + * The somewhat cryptic overuse of SIM_CONTROL_DLOPEN allows us 70 + * to be backward-compatible with older simulator releases. 71 + */ 72 + if (vma->vm_start == (ELF_ET_DYN_BASE & PAGE_MASK)) { 73 + char buf[64]; 74 + int i; 75 + 76 + snprintf(buf, sizeof(buf), "0x%lx:@", vma->vm_start); 77 + for (i = 0; ; ++i) { 78 + char c = buf[i]; 79 + __insn_mtspr(SPR_SIM_CONTROL, 80 + (SIM_CONTROL_DLOPEN 81 + | (c << _SIM_CONTROL_OPERATOR_BITS))); 82 + if (c == '\0') 83 + break; 54 84 } 55 85 } 56 - return retval; 86 + 87 + sim_notify_exec(path); 88 + free_page((unsigned long)buf); 89 + return 1; 57 90 } 58 91 59 92 /* Notify a running simulator, if any, that we loaded an interpreter. */ ··· 103 68 } 104 69 105 70 106 - /* Kernel address of page used to map read-only kernel data into userspace. */ 107 - static void *vdso_page; 108 - 109 - /* One-entry array used for install_special_mapping. */ 110 - static struct page *vdso_pages[1]; 111 - 112 - static int __init vdso_setup(void) 113 - { 114 - vdso_page = (void *)get_zeroed_page(GFP_ATOMIC); 115 - memcpy(vdso_page, __rt_sigreturn, __rt_sigreturn_end - __rt_sigreturn); 116 - vdso_pages[0] = virt_to_page(vdso_page); 117 - return 0; 118 - } 119 - device_initcall(vdso_setup); 120 - 121 - const char *arch_vma_name(struct vm_area_struct *vma) 122 - { 123 - if (vma->vm_private_data == vdso_pages) 124 - return "[vdso]"; 125 - #ifndef __tilegx__ 126 - if (vma->vm_start == MEM_USER_INTRPT) 127 - return "[intrpt]"; 128 - #endif 129 - return NULL; 130 - } 131 - 132 71 int arch_setup_additional_pages(struct linux_binprm *bprm, 133 72 int executable_stack) 134 73 { 135 74 struct mm_struct *mm = current->mm; 136 - unsigned long vdso_base; 137 75 int retval = 0; 138 76 139 77 down_write(&mm->mmap_sem); ··· 119 111 if (!notify_exec(mm)) 120 112 sim_notify_exec(bprm->filename); 121 113 122 - /* 123 - * MAYWRITE to allow gdb to COW and set breakpoints 124 - */ 125 - vdso_base = VDSO_BASE; 126 - retval = install_special_mapping(mm, vdso_base, PAGE_SIZE, 127 - VM_READ|VM_EXEC| 128 - VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC, 129 - vdso_pages); 114 + retval = setup_vdso_pages(); 130 115 131 116 #ifndef __tilegx__ 132 117 /*
+76 -59
arch/tile/mm/fault.c
··· 34 34 #include <linux/hugetlb.h> 35 35 #include <linux/syscalls.h> 36 36 #include <linux/uaccess.h> 37 + #include <linux/kdebug.h> 37 38 38 39 #include <asm/pgalloc.h> 39 40 #include <asm/sections.h> ··· 123 122 pmd_k = pmd_offset(pud_k, address); 124 123 if (!pmd_present(*pmd_k)) 125 124 return NULL; 126 - if (!pmd_present(*pmd)) { 125 + if (!pmd_present(*pmd)) 127 126 set_pmd(pmd, *pmd_k); 128 - arch_flush_lazy_mmu_mode(); 129 - } else 127 + else 130 128 BUG_ON(pmd_ptfn(*pmd) != pmd_ptfn(*pmd_k)); 131 129 return pmd_k; 132 130 } ··· 283 283 flags = (FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE | 284 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 288 tsk = validate_current(); 289 289 ··· 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 469 #if CHIP_HAS_TILE_DMA() 470 + /* If this was a DMA TLB fault, restart the DMA engine. */ 471 + switch (fault_num) { 476 472 case INT_DMATLB_MISS: 477 473 case INT_DMATLB_MISS_DWNCL: 478 474 case INT_DMATLB_ACCESS: 479 475 case INT_DMATLB_ACCESS_DWNCL: 480 476 __insn_mtspr(SPR_DMA_CTR, SPR_DMA_CTR__REQUEST_MASK); 481 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 479 #endif 493 480 ··· 709 722 { 710 723 int is_page_fault; 711 724 725 + #ifdef CONFIG_KPROBES 726 + /* 727 + * This is to notify the fault handler of the kprobes. The 728 + * exception code is redundant as it is also carried in REGS, 729 + * but we pass it anyhow. 730 + */ 731 + if (notify_die(DIE_PAGE_FAULT, "page fault", regs, -1, 732 + regs->faultnum, SIGSEGV) == NOTIFY_STOP) 733 + return; 734 + #endif 735 + 736 + #ifdef __tilegx__ 737 + /* 738 + * We don't need early do_page_fault_ics() support, since unlike 739 + * Pro we don't need to worry about unlocking the atomic locks. 740 + * There is only one current case in GX where we touch any memory 741 + * under ICS other than our own kernel stack, and we handle that 742 + * here. (If we crash due to trying to touch our own stack, 743 + * we're in too much trouble for C code to help out anyway.) 744 + */ 745 + if (write & ~1) { 746 + unsigned long pc = write & ~1; 747 + if (pc >= (unsigned long) __start_unalign_asm_code && 748 + pc < (unsigned long) __end_unalign_asm_code) { 749 + struct thread_info *ti = current_thread_info(); 750 + /* 751 + * Our EX_CONTEXT is still what it was from the 752 + * initial unalign exception, but now we've faulted 753 + * on the JIT page. We would like to complete the 754 + * page fault however is appropriate, and then retry 755 + * the instruction that caused the unalign exception. 756 + * Our state has been "corrupted" by setting the low 757 + * bit in "sp", and stashing r0..r3 in the 758 + * thread_info area, so we revert all of that, then 759 + * continue as if this were a normal page fault. 760 + */ 761 + regs->sp &= ~1UL; 762 + regs->regs[0] = ti->unalign_jit_tmp[0]; 763 + regs->regs[1] = ti->unalign_jit_tmp[1]; 764 + regs->regs[2] = ti->unalign_jit_tmp[2]; 765 + regs->regs[3] = ti->unalign_jit_tmp[3]; 766 + write &= 1; 767 + } else { 768 + pr_alert("%s/%d: ICS set at page fault at %#lx: %#lx\n", 769 + current->comm, current->pid, pc, address); 770 + show_regs(regs); 771 + do_group_exit(SIGKILL); 772 + return; 773 + } 774 + } 775 + #else 712 776 /* This case should have been handled by do_page_fault_ics(). */ 713 777 BUG_ON(write & ~1); 778 + #endif 714 779 715 780 #if CHIP_HAS_TILE_DMA() 716 781 /* ··· 791 752 case INT_DMATLB_MISS: 792 753 case INT_DMATLB_MISS_DWNCL: 793 754 #endif 794 - #if CHIP_HAS_SN_PROC() 795 - case INT_SNITLB_MISS: 796 - case INT_SNITLB_MISS_DWNCL: 797 - #endif 798 755 is_page_fault = 1; 799 756 break; 800 757 ··· 806 771 panic("Bad fault number %d in do_page_fault", fault_num); 807 772 } 808 773 809 - #if CHIP_HAS_TILE_DMA() || CHIP_HAS_SN_PROC() 810 - if (EX1_PL(regs->ex1) != USER_PL) { 774 + #if CHIP_HAS_TILE_DMA() 775 + if (!user_mode(regs)) { 811 776 struct async_tlb *async; 812 777 switch (fault_num) { 813 778 #if CHIP_HAS_TILE_DMA() ··· 816 781 case INT_DMATLB_MISS_DWNCL: 817 782 case INT_DMATLB_ACCESS_DWNCL: 818 783 async = &current->thread.dma_async_tlb; 819 - break; 820 - #endif 821 - #if CHIP_HAS_SN_PROC() 822 - case INT_SNITLB_MISS: 823 - case INT_SNITLB_MISS_DWNCL: 824 - async = &current->thread.sn_async_tlb; 825 784 break; 826 785 #endif 827 786 default: ··· 850 821 } 851 822 852 823 853 - #if CHIP_HAS_TILE_DMA() || CHIP_HAS_SN_PROC() 824 + #if CHIP_HAS_TILE_DMA() 854 825 /* 855 - * Check an async_tlb structure to see if a deferred fault is waiting, 856 - * and if so pass it to the page-fault code. 826 + * This routine effectively re-issues asynchronous page faults 827 + * when we are returning to user space. 857 828 */ 858 - static void handle_async_page_fault(struct pt_regs *regs, 859 - struct async_tlb *async) 829 + void do_async_page_fault(struct pt_regs *regs) 860 830 { 831 + struct async_tlb *async = &current->thread.dma_async_tlb; 832 + 833 + /* 834 + * Clear thread flag early. If we re-interrupt while processing 835 + * code here, we will reset it and recall this routine before 836 + * returning to user space. 837 + */ 838 + clear_thread_flag(TIF_ASYNC_TLB); 839 + 861 840 if (async->fault_num) { 862 841 /* 863 842 * Clear async->fault_num before calling the page-fault ··· 879 842 async->address, async->is_write); 880 843 } 881 844 } 882 - 883 - /* 884 - * This routine effectively re-issues asynchronous page faults 885 - * when we are returning to user space. 886 - */ 887 - void do_async_page_fault(struct pt_regs *regs) 888 - { 889 - /* 890 - * Clear thread flag early. If we re-interrupt while processing 891 - * code here, we will reset it and recall this routine before 892 - * returning to user space. 893 - */ 894 - clear_thread_flag(TIF_ASYNC_TLB); 895 - 896 - #if CHIP_HAS_TILE_DMA() 897 - handle_async_page_fault(regs, &current->thread.dma_async_tlb); 898 - #endif 899 - #if CHIP_HAS_SN_PROC() 900 - handle_async_page_fault(regs, &current->thread.sn_async_tlb); 901 - #endif 902 - } 903 - #endif /* CHIP_HAS_TILE_DMA() || CHIP_HAS_SN_PROC() */ 845 + #endif /* CHIP_HAS_TILE_DMA() */ 904 846 905 847 906 848 void vmalloc_sync_all(void) 907 849 { 908 850 #ifdef __tilegx__ 909 851 /* Currently all L1 kernel pmd's are static and shared. */ 910 - BUG_ON(pgd_index(VMALLOC_END) != pgd_index(VMALLOC_START)); 852 + BUILD_BUG_ON(pgd_index(VMALLOC_END - PAGE_SIZE) != 853 + pgd_index(VMALLOC_START)); 911 854 #else 912 855 /* 913 856 * Note that races in the updates of insync and start aren't
-2
arch/tile/mm/highmem.c
··· 114 114 115 115 list_add(&amp->list, &amp_list); 116 116 set_pte(ptep, pteval); 117 - arch_flush_lazy_mmu_mode(); 118 117 119 118 spin_unlock(&amp_lock); 120 119 homecache_kpte_unlock(flags); ··· 258 259 BUG_ON(vaddr >= (unsigned long)high_memory); 259 260 } 260 261 261 - arch_flush_lazy_mmu_mode(); 262 262 pagefault_enable(); 263 263 } 264 264 EXPORT_SYMBOL(__kunmap_atomic);
+9 -30
arch/tile/mm/homecache.c
··· 43 43 #include "migrate.h" 44 44 45 45 46 - #if CHIP_HAS_COHERENT_LOCAL_CACHE() 47 - 48 46 /* 49 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 51 - * don't have coherent local caching, though. 48 + * locally from a remote home. 52 49 */ 53 50 static int __write_once noallocl2; 54 51 static int __init set_noallocl2(char *str) ··· 54 57 return 0; 55 58 } 56 59 early_param("noallocl2", set_noallocl2); 57 - 58 - #else 59 - 60 - #define noallocl2 0 61 - 62 - #endif 63 60 64 61 65 62 /* ··· 163 172 164 173 static void homecache_finv_page_va(void* va, int home) 165 174 { 166 - if (home == smp_processor_id()) { 175 + int cpu = get_cpu(); 176 + if (home == cpu) { 167 177 finv_buffer_local(va, PAGE_SIZE); 168 178 } else if (home == PAGE_HOME_HASH) { 169 179 finv_buffer_remote(va, PAGE_SIZE, 1); ··· 172 180 BUG_ON(home < 0 || home >= NR_CPUS); 173 181 finv_buffer_remote(va, PAGE_SIZE, 0); 174 182 } 183 + put_cpu(); 175 184 } 176 185 177 186 void homecache_finv_map_page(struct page *page, int home) ··· 191 198 #else 192 199 va = __fix_to_virt(FIX_HOMECACHE_BEGIN + smp_processor_id()); 193 200 #endif 194 - ptep = virt_to_pte(NULL, (unsigned long)va); 201 + ptep = virt_to_kpte(va); 195 202 pte = pfn_pte(page_to_pfn(page), PAGE_KERNEL); 196 203 __set_pte(ptep, pte_set_home(pte, home)); 197 204 homecache_finv_page_va((void *)va, home); ··· 256 263 return PAGE_HOME_INCOHERENT; 257 264 case HV_PTE_MODE_UNCACHED: 258 265 return PAGE_HOME_UNCACHED; 259 - #if CHIP_HAS_CBOX_HOME_MAP() 260 266 case HV_PTE_MODE_CACHE_HASH_L3: 261 267 return PAGE_HOME_HASH; 262 - #endif 263 268 } 264 269 panic("Bad PTE %#llx\n", pte.val); 265 270 } ··· 314 323 HV_PTE_MODE_CACHE_NO_L3); 315 324 } 316 325 } else 317 - #if CHIP_HAS_CBOX_HOME_MAP() 318 326 if (hash_default) 319 327 pte = hv_pte_set_mode(pte, HV_PTE_MODE_CACHE_HASH_L3); 320 328 else 321 - #endif 322 329 pte = hv_pte_set_mode(pte, HV_PTE_MODE_CACHE_NO_L3); 323 330 pte = hv_pte_set_nc(pte); 324 331 break; 325 332 326 - #if CHIP_HAS_CBOX_HOME_MAP() 327 333 case PAGE_HOME_HASH: 328 334 pte = hv_pte_set_mode(pte, HV_PTE_MODE_CACHE_HASH_L3); 329 335 break; 330 - #endif 331 336 332 337 default: 333 338 BUG_ON(home < 0 || home >= NR_CPUS || ··· 333 346 break; 334 347 } 335 348 336 - #if CHIP_HAS_NC_AND_NOALLOC_BITS() 337 349 if (noallocl2) 338 350 pte = hv_pte_set_no_alloc_l2(pte); 339 351 ··· 341 355 hv_pte_get_mode(pte) == HV_PTE_MODE_CACHE_NO_L3) { 342 356 pte = hv_pte_set_mode(pte, HV_PTE_MODE_UNCACHED); 343 357 } 344 - #endif 345 358 346 359 /* Checking this case here gives a better panic than from the hv. */ 347 360 BUG_ON(hv_pte_get_mode(pte) == 0); ··· 356 371 * so they're not suitable for anything but infrequent use. 357 372 */ 358 373 359 - #if CHIP_HAS_CBOX_HOME_MAP() 360 - static inline int initial_page_home(void) { return PAGE_HOME_HASH; } 361 - #else 362 - static inline int initial_page_home(void) { return 0; } 363 - #endif 364 - 365 374 int page_home(struct page *page) 366 375 { 367 376 if (PageHighMem(page)) { 368 - return initial_page_home(); 377 + return PAGE_HOME_HASH; 369 378 } else { 370 379 unsigned long kva = (unsigned long)page_address(page); 371 - return pte_to_home(*virt_to_pte(NULL, kva)); 380 + return pte_to_home(*virt_to_kpte(kva)); 372 381 } 373 382 } 374 383 EXPORT_SYMBOL(page_home); ··· 381 402 NULL, 0); 382 403 383 404 for (i = 0; i < pages; ++i, kva += PAGE_SIZE) { 384 - pte_t *ptep = virt_to_pte(NULL, kva); 405 + pte_t *ptep = virt_to_kpte(kva); 385 406 pte_t pteval = *ptep; 386 407 BUG_ON(!pte_present(pteval) || pte_huge(pteval)); 387 408 __set_pte(ptep, pte_set_home(pteval, home)); ··· 415 436 void __homecache_free_pages(struct page *page, unsigned int order) 416 437 { 417 438 if (put_page_testzero(page)) { 418 - homecache_change_page_home(page, order, initial_page_home()); 439 + homecache_change_page_home(page, order, PAGE_HOME_HASH); 419 440 if (order == 0) { 420 441 free_hot_cold_page(page, 0); 421 442 } else {
+3 -35
arch/tile/mm/hugetlbpage.c
··· 49 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 - */ 58 - static 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 52 #endif 85 53 86 54 pte_t *huge_pte_alloc(struct mm_struct *mm, ··· 77 109 else { 78 110 if (sz != PAGE_SIZE << huge_shift[HUGE_SHIFT_PAGE]) 79 111 panic("Unexpected page size %#lx\n", sz); 80 - return pte_alloc_hugetlb(mm, pmd, addr); 112 + return pte_alloc_map(mm, NULL, pmd, addr); 81 113 } 82 114 } 83 115 #else ··· 112 144 113 145 /* Get the top-level page table entry. */ 114 146 pgd = (pgd_t *)get_pte((pte_t *)mm->pgd, pgd_index(addr), 0); 115 - if (!pgd_present(*pgd)) 116 - return NULL; 117 147 118 148 /* We don't have four levels. */ 119 149 pud = pud_offset(pgd, addr); 120 150 #ifndef __PAGETABLE_PUD_FOLDED 121 151 # error support fourth page table level 122 152 #endif 153 + if (!pud_present(*pud)) 154 + return NULL; 123 155 124 156 /* Check for an L0 huge PTE, if we have three levels. */ 125 157 #ifndef __PAGETABLE_PMD_FOLDED
+11 -85
arch/tile/mm/init.c
··· 106 106 */ 107 107 static int initial_heap_home(void) 108 108 { 109 - #if CHIP_HAS_CBOX_HOME_MAP() 110 109 if (hash_default) 111 110 return PAGE_HOME_HASH; 112 - #endif 113 111 return smp_processor_id(); 114 112 } 115 113 ··· 188 190 } 189 191 190 192 191 - #if CHIP_HAS_CBOX_HOME_MAP() 192 - 193 193 static int __initdata ktext_hash = 1; /* .text pages */ 194 194 static int __initdata kdata_hash = 1; /* .data and .bss pages */ 195 195 int __write_once hash_default = 1; /* kernel allocator pages */ 196 196 EXPORT_SYMBOL(hash_default); 197 197 int __write_once kstack_hash = 1; /* if no homecaching, use h4h */ 198 - #endif /* CHIP_HAS_CBOX_HOME_MAP */ 199 198 200 199 /* 201 200 * CPUs to use to for striping the pages of kernel data. If hash-for-home ··· 210 215 static pgprot_t __init construct_pgprot(pgprot_t prot, int home) 211 216 { 212 217 prot = pte_set_home(prot, home); 213 - #if CHIP_HAS_CBOX_HOME_MAP() 214 218 if (home == PAGE_HOME_IMMUTABLE) { 215 219 if (ktext_hash) 216 220 prot = hv_pte_set_mode(prot, HV_PTE_MODE_CACHE_HASH_L3); 217 221 else 218 222 prot = hv_pte_set_mode(prot, HV_PTE_MODE_CACHE_NO_L3); 219 223 } 220 - #endif 221 224 return prot; 222 225 } 223 226 ··· 227 234 { 228 235 int cpu; 229 236 unsigned long page; 230 - enum { CODE_DELTA = MEM_SV_INTRPT - PAGE_OFFSET }; 237 + enum { CODE_DELTA = MEM_SV_START - PAGE_OFFSET }; 231 238 232 - #if CHIP_HAS_CBOX_HOME_MAP() 233 239 /* For kdata=huge, everything is just hash-for-home. */ 234 240 if (kdata_huge) 235 241 return construct_pgprot(PAGE_KERNEL, PAGE_HOME_HASH); 236 - #endif 237 242 238 243 /* We map the aliased pages of permanent text inaccessible. */ 239 244 if (address < (ulong) _sinittext - CODE_DELTA) 240 245 return PAGE_NONE; 241 246 242 - /* 243 - * We map read-only data non-coherent for performance. We could 244 - * use neighborhood caching on TILE64, but it's not clear it's a win. 245 - */ 247 + /* We map read-only data non-coherent for performance. */ 246 248 if ((address >= (ulong) __start_rodata && 247 249 address < (ulong) __end_rodata) || 248 250 address == (ulong) empty_zero_page) { ··· 245 257 } 246 258 247 259 #ifndef __tilegx__ 248 - #if !ATOMIC_LOCKS_FOUND_VIA_TABLE() 249 260 /* Force the atomic_locks[] array page to be hash-for-home. */ 250 261 if (address == (ulong) atomic_locks) 251 262 return construct_pgprot(PAGE_KERNEL, PAGE_HOME_HASH); 252 - #endif 253 263 #endif 254 264 255 265 /* ··· 266 280 if (address >= (ulong) _end || address < (ulong) _einitdata) 267 281 return construct_pgprot(PAGE_KERNEL, initial_heap_home()); 268 282 269 - #if CHIP_HAS_CBOX_HOME_MAP() 270 283 /* Use hash-for-home if requested for data/bss. */ 271 284 if (kdata_hash) 272 285 return construct_pgprot(PAGE_KERNEL, PAGE_HOME_HASH); 273 - #endif 274 - 275 - /* 276 - * Make the w1data homed like heap to start with, to avoid 277 - * making it part of the page-striped data area when we're just 278 - * going to convert it to read-only soon anyway. 279 - */ 280 - if (address >= (ulong)__w1data_begin && address < (ulong)__w1data_end) 281 - return construct_pgprot(PAGE_KERNEL, initial_heap_home()); 282 286 283 287 /* 284 288 * Otherwise we just hand out consecutive cpus. To avoid ··· 277 301 * the requested address, while walking cpu home around kdata_mask. 278 302 * This is typically no more than a dozen or so iterations. 279 303 */ 280 - page = (((ulong)__w1data_end) + PAGE_SIZE - 1) & PAGE_MASK; 304 + page = (((ulong)__end_rodata) + PAGE_SIZE - 1) & PAGE_MASK; 281 305 BUG_ON(address < page || address >= (ulong)_end); 282 306 cpu = cpumask_first(&kdata_mask); 283 307 for (; page < address; page += PAGE_SIZE) { ··· 287 311 if (page == (ulong)empty_zero_page) 288 312 continue; 289 313 #ifndef __tilegx__ 290 - #if !ATOMIC_LOCKS_FOUND_VIA_TABLE() 291 314 if (page == (ulong)atomic_locks) 292 315 continue; 293 - #endif 294 316 #endif 295 317 cpu = cpumask_next(cpu, &kdata_mask); 296 318 if (cpu == NR_CPUS) ··· 332 358 333 359 ktext_arg_seen = 1; 334 360 335 - /* Default setting on Tile64: use a huge page */ 361 + /* Default setting: use a huge page */ 336 362 if (strcmp(str, "huge") == 0) 337 363 pr_info("ktext: using one huge locally cached page\n"); 338 364 ··· 378 404 { 379 405 if (!ktext_nocache) 380 406 prot = hv_pte_set_nc(prot); 381 - #if CHIP_HAS_NC_AND_NOALLOC_BITS() 382 407 else 383 408 prot = hv_pte_set_no_alloc_l2(prot); 384 - #endif 385 409 return prot; 386 410 } 387 411 ··· 412 440 struct cpumask kstripe_mask; 413 441 int rc, i; 414 442 415 - #if CHIP_HAS_CBOX_HOME_MAP() 416 443 if (ktext_arg_seen && ktext_hash) { 417 444 pr_warning("warning: \"ktext\" boot argument ignored" 418 445 " if \"kcache_hash\" sets up text hash-for-home\n"); ··· 428 457 " kcache_hash=all or =allbutstack\n"); 429 458 kdata_huge = 0; 430 459 } 431 - #endif 432 460 433 461 /* 434 462 * Set up a mask for cpus to use for kernel striping. ··· 508 538 } 509 539 } 510 540 511 - address = MEM_SV_INTRPT; 541 + address = MEM_SV_START; 512 542 pmd = get_pmd(pgtables, address); 513 543 pfn = 0; /* code starts at PA 0 */ 514 544 if (ktext_small) { ··· 555 585 } else { 556 586 pte_t pteval = pfn_pte(0, PAGE_KERNEL_EXEC); 557 587 pteval = pte_mkhuge(pteval); 558 - #if CHIP_HAS_CBOX_HOME_MAP() 559 588 if (ktext_hash) { 560 589 pteval = hv_pte_set_mode(pteval, 561 590 HV_PTE_MODE_CACHE_HASH_L3); 562 591 pteval = ktext_set_nocache(pteval); 563 592 } else 564 - #endif /* CHIP_HAS_CBOX_HOME_MAP() */ 565 593 if (cpumask_weight(&ktext_mask) == 1) { 566 594 pteval = set_remote_cache_cpu(pteval, 567 595 cpumask_first(&ktext_mask)); ··· 745 777 746 778 kernel_physical_mapping_init(pgd_base); 747 779 748 - /* 749 - * Fixed mappings, only the page table structure has to be 750 - * created - mappings will be set by set_fixmap(): 751 - */ 780 + /* Fixed mappings, only the page table structure has to be created. */ 752 781 page_table_range_init(fix_to_virt(__end_of_fixed_addresses - 1), 753 782 FIXADDR_TOP, pgd_base); 754 783 ··· 906 941 panic("pgtable_cache_init(): Cannot create pgd cache"); 907 942 } 908 943 909 - #if !CHIP_HAS_COHERENT_LOCAL_CACHE() 910 - /* 911 - * The __w1data area holds data that is only written during initialization, 912 - * and is read-only and thus freely cacheable thereafter. Fix the page 913 - * table entries that cover that region accordingly. 914 - */ 915 - static void mark_w1data_ro(void) 916 - { 917 - /* Loop over page table entries */ 918 - unsigned long addr = (unsigned long)__w1data_begin; 919 - BUG_ON((addr & (PAGE_SIZE-1)) != 0); 920 - for (; addr <= (unsigned long)__w1data_end - 1; addr += PAGE_SIZE) { 921 - unsigned long pfn = kaddr_to_pfn((void *)addr); 922 - pte_t *ptep = virt_to_pte(NULL, addr); 923 - BUG_ON(pte_huge(*ptep)); /* not relevant for kdata_huge */ 924 - set_pte_at(&init_mm, addr, ptep, pfn_pte(pfn, PAGE_KERNEL_RO)); 925 - } 926 - } 927 - #endif 928 - 929 944 #ifdef CONFIG_DEBUG_PAGEALLOC 930 945 static long __write_once initfree; 931 946 #else ··· 945 1000 */ 946 1001 int pfn = kaddr_to_pfn((void *)addr); 947 1002 struct page *page = pfn_to_page(pfn); 948 - pte_t *ptep = virt_to_pte(NULL, addr); 1003 + pte_t *ptep = virt_to_kpte(addr); 949 1004 if (!initfree) { 950 1005 /* 951 1006 * If debugging page accesses then do not free ··· 969 1024 970 1025 void free_initmem(void) 971 1026 { 972 - const unsigned long text_delta = MEM_SV_INTRPT - PAGE_OFFSET; 1027 + const unsigned long text_delta = MEM_SV_START - PAGE_OFFSET; 973 1028 974 1029 /* 975 - * Evict the dirty initdata on the boot cpu, evict the w1data 976 - * wherever it's homed, and evict all the init code everywhere. 977 - * We are guaranteed that no one will touch the init pages any 978 - * more, and although other cpus may be touching the w1data, 979 - * we only actually change the caching on tile64, which won't 980 - * be keeping local copies in the other tiles' caches anyway. 1030 + * Evict the cache on all cores to avoid incoherence. 1031 + * We are guaranteed that no one will touch the init pages any more. 981 1032 */ 982 1033 homecache_evict(&cpu_cacheable_map); 983 1034 ··· 984 1043 985 1044 /* 986 1045 * Free the pages mapped from 0xc0000000 that correspond to code 987 - * pages from MEM_SV_INTRPT that we won't use again after init. 1046 + * pages from MEM_SV_START that we won't use again after init. 988 1047 */ 989 1048 free_init_pages("unused kernel text", 990 1049 (unsigned long)_sinittext - text_delta, 991 1050 (unsigned long)_einittext - text_delta); 992 - 993 - #if !CHIP_HAS_COHERENT_LOCAL_CACHE() 994 - /* 995 - * Upgrade the .w1data section to globally cached. 996 - * We don't do this on tilepro, since the cache architecture 997 - * pretty much makes it irrelevant, and in any case we end 998 - * up having racing issues with other tiles that may touch 999 - * the data after we flush the cache but before we update 1000 - * the PTEs and flush the TLBs, causing sharer shootdowns 1001 - * later. Even though this is to clean data, it seems like 1002 - * an unnecessary complication. 1003 - */ 1004 - mark_w1data_ro(); 1005 - #endif 1006 - 1007 1051 /* Do a global TLB flush so everyone sees the changes. */ 1008 1052 flush_tlb_all(); 1009 1053 }
+2 -2
arch/tile/mm/migrate_32.S
··· 136 136 move r8, zero /* asids */ 137 137 move r9, zero /* asidcount */ 138 138 } 139 - jal hv_flush_remote 139 + jal _hv_flush_remote 140 140 bnz r0, .Ldone 141 141 142 142 /* Now install the new page table. */ ··· 152 152 move r4, r_asid 153 153 moveli r5, HV_CTX_DIRECTIO | CTX_PAGE_FLAG 154 154 } 155 - jal hv_install_context 155 + jal _hv_install_context 156 156 bnz r0, .Ldone 157 157 158 158 /* Finally, flush the TLB. */
+2 -2
arch/tile/mm/migrate_64.S
··· 123 123 } 124 124 { 125 125 move r8, zero /* asidcount */ 126 - jal hv_flush_remote 126 + jal _hv_flush_remote 127 127 } 128 128 bnez r0, 1f 129 129 ··· 136 136 move r2, r_asid 137 137 moveli r3, HV_CTX_DIRECTIO | CTX_PAGE_FLAG 138 138 } 139 - jal hv_install_context 139 + jal _hv_install_context 140 140 bnez r0, 1f 141 141 142 142 /* Finally, flush the TLB. */
+22 -2
arch/tile/mm/mmap.c
··· 58 58 #else 59 59 int is_32bit = 0; 60 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 77 * Use standard layout if the expected stack growth is unlimited 64 78 * or we are running native 64 bits. 65 79 */ 66 - if (!is_32bit || rlimit(RLIMIT_STACK) == RLIM_INFINITY) { 67 - mm->mmap_base = TASK_UNMAPPED_BASE; 80 + if (rlimit(RLIMIT_STACK) == RLIM_INFINITY) { 81 + mm->mmap_base = TASK_UNMAPPED_BASE + random_factor; 68 82 mm->get_unmapped_area = arch_get_unmapped_area; 69 83 } else { 70 84 mm->mmap_base = mmap_base(mm); 71 85 mm->get_unmapped_area = arch_get_unmapped_area_topdown; 72 86 } 87 + } 88 + 89 + unsigned 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; 73 93 }
+24 -52
arch/tile/mm/pgtable.c
··· 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 - */ 90 - static 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 - 124 - void __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 87 * shatter_huge_page() - ensure a given address is mapped by a small page. 137 88 * ··· 325 374 326 375 #endif 327 376 377 + /* 378 + * Return a pointer to the PTE that corresponds to the given 379 + * address in the given page table. A NULL page table just uses 380 + * the standard kernel page table; the preferred API in this case 381 + * is virt_to_kpte(). 382 + * 383 + * The returned pointer can point to a huge page in other levels 384 + * of the page table than the bottom, if the huge page is present 385 + * in the page table. For bottom-level PTEs, the returned pointer 386 + * can point to a PTE that is either present or not. 387 + */ 328 388 pte_t *virt_to_pte(struct mm_struct* mm, unsigned long addr) 329 389 { 330 390 pgd_t *pgd; ··· 349 387 pud = pud_offset(pgd, addr); 350 388 if (!pud_present(*pud)) 351 389 return NULL; 390 + if (pud_huge_page(*pud)) 391 + return (pte_t *)pud; 352 392 pmd = pmd_offset(pud, addr); 353 - if (pmd_huge_page(*pmd)) 354 - return (pte_t *)pmd; 355 393 if (!pmd_present(*pmd)) 356 394 return NULL; 395 + if (pmd_huge_page(*pmd)) 396 + return (pte_t *)pmd; 357 397 return pte_offset_kernel(pmd, addr); 358 398 } 399 + EXPORT_SYMBOL(virt_to_pte); 400 + 401 + pte_t *virt_to_kpte(unsigned long kaddr) 402 + { 403 + BUG_ON(kaddr < PAGE_OFFSET); 404 + return virt_to_pte(NULL, kaddr); 405 + } 406 + EXPORT_SYMBOL(virt_to_kpte); 359 407 360 408 pgprot_t set_remote_cache_cpu(pgprot_t prot, int cpu) 361 409 { ··· 540 568 addr = area->addr; 541 569 if (ioremap_page_range((unsigned long)addr, (unsigned long)addr + size, 542 570 phys_addr, pgprot)) { 543 - remove_vm_area((void *)(PAGE_MASK & (unsigned long) addr)); 571 + free_vm_area(area); 544 572 return NULL; 545 573 } 546 574 return (__force void __iomem *) (offset + (char *)addr);
-1
drivers/edac/tile_edac.c
··· 257 257 if (!pdev) 258 258 continue; 259 259 260 - platform_set_drvdata(pdev, NULL); 261 260 platform_device_unregister(pdev); 262 261 } 263 262 platform_driver_unregister(&tile_edac_mc_driver);
+143 -6
drivers/tty/hvc/hvc_tile.c
··· 18 18 #include <linux/delay.h> 19 19 #include <linux/err.h> 20 20 #include <linux/init.h> 21 + #include <linux/interrupt.h> 22 + #include <linux/irq.h> 21 23 #include <linux/moduleparam.h> 24 + #include <linux/platform_device.h> 22 25 #include <linux/types.h> 26 + 27 + #include <asm/setup.h> 28 + #include <arch/sim_def.h> 23 29 24 30 #include <hv/hypervisor.h> 25 31 26 32 #include "hvc_console.h" 27 33 34 + static int use_sim_console; 35 + static int __init sim_console(char *str) 36 + { 37 + use_sim_console = 1; 38 + return 0; 39 + } 40 + early_param("sim_console", sim_console); 41 + 42 + int 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 + 28 58 static 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 33 63 static int hvc_tile_get_chars(uint32_t vt, char *buf, int count) ··· 74 44 return i; 75 45 } 76 46 47 + #ifdef __tilegx__ 48 + /* 49 + * IRQ based callbacks. 50 + */ 51 + static int hvc_tile_notifier_add_irq(struct hvc_struct *hp, int irq) 52 + { 53 + int rc; 54 + int cpu = raw_smp_processor_id(); /* Choose an arbitrary cpu */ 55 + HV_Coord coord = { .x = cpu_x(cpu), .y = cpu_y(cpu) }; 56 + 57 + rc = notifier_add_irq(hp, irq); 58 + if (rc) 59 + return rc; 60 + 61 + /* 62 + * Request that the hypervisor start sending us interrupts. 63 + * If the hypervisor returns an error, we still return 0, so that 64 + * we can fall back to polling. 65 + */ 66 + if (hv_console_set_ipi(KERNEL_PL, irq, coord) < 0) 67 + notifier_del_irq(hp, irq); 68 + 69 + return 0; 70 + } 71 + 72 + static void hvc_tile_notifier_del_irq(struct hvc_struct *hp, int irq) 73 + { 74 + HV_Coord coord = { 0, 0 }; 75 + 76 + /* Tell the hypervisor to stop sending us interrupts. */ 77 + hv_console_set_ipi(KERNEL_PL, -1, coord); 78 + 79 + notifier_del_irq(hp, irq); 80 + } 81 + 82 + static void hvc_tile_notifier_hangup_irq(struct hvc_struct *hp, int irq) 83 + { 84 + hvc_tile_notifier_del_irq(hp, irq); 85 + } 86 + #endif 87 + 77 88 static const struct hv_ops hvc_tile_get_put_ops = { 78 89 .get_chars = hvc_tile_get_chars, 79 90 .put_chars = hvc_tile_put_chars, 91 + #ifdef __tilegx__ 92 + .notifier_add = hvc_tile_notifier_add_irq, 93 + .notifier_del = hvc_tile_notifier_del_irq, 94 + .notifier_hangup = hvc_tile_notifier_hangup_irq, 95 + #endif 80 96 }; 97 + 98 + 99 + #ifdef __tilegx__ 100 + static int hvc_tile_probe(struct platform_device *pdev) 101 + { 102 + struct hvc_struct *hp; 103 + int tile_hvc_irq; 104 + 105 + /* Create our IRQ and register it. */ 106 + tile_hvc_irq = create_irq(); 107 + if (tile_hvc_irq < 0) 108 + return -ENXIO; 109 + 110 + tile_irq_activate(tile_hvc_irq, TILE_IRQ_PERCPU); 111 + hp = hvc_alloc(0, tile_hvc_irq, &hvc_tile_get_put_ops, 128); 112 + if (IS_ERR(hp)) { 113 + destroy_irq(tile_hvc_irq); 114 + return PTR_ERR(hp); 115 + } 116 + dev_set_drvdata(&pdev->dev, hp); 117 + 118 + return 0; 119 + } 120 + 121 + static int hvc_tile_remove(struct platform_device *pdev) 122 + { 123 + int rc; 124 + struct hvc_struct *hp = dev_get_drvdata(&pdev->dev); 125 + 126 + rc = hvc_remove(hp); 127 + if (rc == 0) 128 + destroy_irq(hp->data); 129 + 130 + return rc; 131 + } 132 + 133 + static void hvc_tile_shutdown(struct platform_device *pdev) 134 + { 135 + struct hvc_struct *hp = dev_get_drvdata(&pdev->dev); 136 + 137 + hvc_tile_notifier_del_irq(hp, hp->data); 138 + } 139 + 140 + static struct platform_device hvc_tile_pdev = { 141 + .name = "hvc-tile", 142 + .id = 0, 143 + }; 144 + 145 + static struct platform_driver hvc_tile_driver = { 146 + .probe = hvc_tile_probe, 147 + .remove = hvc_tile_remove, 148 + .shutdown = hvc_tile_shutdown, 149 + .driver = { 150 + .name = "hvc-tile", 151 + .owner = THIS_MODULE, 152 + } 153 + }; 154 + #endif 81 155 82 156 static int __init hvc_tile_console_init(void) 83 157 { 84 - extern void disable_early_printk(void); 85 158 hvc_instantiate(0, 0, &hvc_tile_get_put_ops); 86 159 add_preferred_console("hvc", 0, NULL); 87 - disable_early_printk(); 88 160 return 0; 89 161 } 90 162 console_initcall(hvc_tile_console_init); 91 163 92 164 static int __init hvc_tile_init(void) 93 165 { 94 - struct hvc_struct *s; 95 - s = hvc_alloc(0, 0, &hvc_tile_get_put_ops, 128); 96 - return IS_ERR(s) ? PTR_ERR(s) : 0; 166 + #ifndef __tilegx__ 167 + struct hvc_struct *hp; 168 + hp = hvc_alloc(0, 0, &hvc_tile_get_put_ops, 128); 169 + return IS_ERR(hp) ? PTR_ERR(hp) : 0; 170 + #else 171 + platform_device_register(&hvc_tile_pdev); 172 + return platform_driver_register(&hvc_tile_driver); 173 + #endif 97 174 } 98 175 device_initcall(hvc_tile_init);
+9
drivers/tty/serial/Kconfig
··· 1439 1439 depends on SERIAL_EFM32_UART=y 1440 1440 select SERIAL_CORE_CONSOLE 1441 1441 1442 + config 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 + 1442 1451 config SERIAL_ARC 1443 1452 tristate "ARC UART driver support" 1444 1453 select SERIAL_CORE
+1
drivers/tty/serial/Makefile
··· 66 66 obj-$(CONFIG_SERIAL_OMAP) += omap-serial.o 67 67 obj-$(CONFIG_SERIAL_ALTERA_UART) += altera_uart.o 68 68 obj-$(CONFIG_SERIAL_ST_ASC) += st-asc.o 69 + obj-$(CONFIG_SERIAL_TILEGX) += tilegx.o 69 70 obj-$(CONFIG_KGDB_SERIAL_CONSOLE) += kgdboc.o 70 71 obj-$(CONFIG_SERIAL_QE) += ucc_uart.o 71 72 obj-$(CONFIG_SERIAL_TIMBERDALE) += timbuart.o
+708
drivers/tty/serial/tilegx.c
··· 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 + 44 + struct 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 + 58 + static struct tile_uart_port tile_uart_ports[TILEGX_UART_NR]; 59 + static struct uart_driver tilegx_uart_driver; 60 + 61 + 62 + /* 63 + * Read UART rx fifo, and insert the chars into tty buffer. 64 + */ 65 + static 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 + */ 85 + static 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 + */ 117 + static 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 + */ 132 + static 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 + */ 175 + static 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 + */ 207 + static 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 + */ 230 + static 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 + */ 239 + static 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 + */ 248 + static void tilegx_stop_tx(struct uart_port *port) 249 + { 250 + /* N/A */ 251 + } 252 + 253 + 254 + /* 255 + * Start transmitting. 256 + */ 257 + static 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 + */ 299 + static 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 + */ 321 + static void tilegx_enable_ms(struct uart_port *port) 322 + { 323 + /* N/A */ 324 + } 325 + 326 + /* 327 + * Control the transmission of a break signal. 328 + */ 329 + static 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 + */ 338 + static 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 + 395 + err_free_irq: 396 + free_irq(port->irq, port); 397 + err_dest_irq: 398 + destroy_irq(port->irq); 399 + err_uart_dest: 400 + gxio_uart_destroy(context); 401 + ret = -ENXIO; 402 + err: 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 + */ 412 + static 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 + */ 451 + static void tilegx_flush_buffer(struct uart_port *port) 452 + { 453 + /* N/A */ 454 + } 455 + 456 + 457 + /* 458 + * Change the port parameters. 459 + */ 460 + static 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 + */ 529 + static 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 + */ 538 + static 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 + */ 547 + static 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 + */ 557 + static 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 + */ 567 + static 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 + 583 + static 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 + 597 + static 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 + 610 + static 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 + 635 + static 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 + 654 + static 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 + 664 + static 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 + 689 + static 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 + 703 + module_init(tilegx_init); 704 + module_exit(tilegx_exit); 705 + 706 + MODULE_AUTHOR("Tilera Corporation"); 707 + MODULE_DESCRIPTION("TILEGx serial port driver"); 708 + MODULE_LICENSE("GPL");
+3
include/uapi/linux/serial_core.h
··· 235 235 /* ST ASC type numbers */ 236 236 #define PORT_ASC 105 237 237 238 + /* Tilera TILE-Gx UART */ 239 + #define PORT_TILEGX 106 240 + 238 241 #endif /* _UAPILINUX_SERIAL_CORE_H */
+9
samples/kprobes/kprobe_example.c
··· 37 37 " status = 0x%lx\n", 38 38 p->addr, regs->cp0_epc, regs->cp0_status); 39 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 46 /* A dump_stack() here will give a stack backtrace */ 42 47 return 0; ··· 62 57 #ifdef CONFIG_MIPS 63 58 printk(KERN_INFO "post_handler: p->addr = 0x%p, status = 0x%lx\n", 64 59 p->addr, regs->cp0_status); 60 + #endif 61 + #ifdef CONFIG_TILEGX 62 + printk(KERN_INFO "post_handler: p->addr = 0x%p, ex1 = 0x%lx\n", 63 + p->addr, regs->ex1); 65 64 #endif 66 65 } 67 66
+4
scripts/recordmcount.pl
··· 364 364 } elsif ($arch eq "blackfin") { 365 365 $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\s__mcount\$"; 366 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 371 } else { 368 372 die "Arch $arch is not supported with CONFIG_FTRACE_MCOUNT_RECORD"; 369 373 }