mirror of
https://github.com/joel16/android_kernel_sony_msm8994_rework.git
synced 2024-11-23 20:09:51 +00:00
Merge git://git.kernel.org/pub/scm/linux/kernel/git/cmetcalf/linux-tile
* git://git.kernel.org/pub/scm/linux/kernel/git/cmetcalf/linux-tile: (26 commits) arch/tile: prefer "tilepro" as the name of the 32-bit architecture compat: include aio_abi.h for aio_context_t arch/tile: cleanups for tilegx compat mode arch/tile: allocate PCI IRQs later in boot arch/tile: support signal "exception-trace" hook arch/tile: use better definitions of xchg() and cmpxchg() include/linux/compat.h: coding-style fixes tile: add an RTC driver for the Tilera hypervisor arch/tile: finish enabling support for TILE-Gx 64-bit chip compat: fixes to allow working with tile arch arch/tile: update defconfig file to something more useful tile: do_hardwall_trap: do not play with task->sighand tile: replace mm->cpu_vm_mask with mm_cpumask() tile,mn10300: add device parameter to dma_cache_sync() audit: support the "standard" <asm-generic/unistd.h> arch/tile: clarify flush_buffer()/finv_buffer() function names arch/tile: kernel-related cleanups from removing static page size arch/tile: various header improvements for building drivers arch/tile: disable GX prefetcher during cache flush arch/tile: tolerate disabling CONFIG_BLK_DEV_INITRD ...
This commit is contained in:
commit
0798b1dbfb
8
Makefile
8
Makefile
@ -220,6 +220,14 @@ ifeq ($(ARCH),sh64)
|
||||
SRCARCH := sh
|
||||
endif
|
||||
|
||||
# Additional ARCH settings for tile
|
||||
ifeq ($(ARCH),tilepro)
|
||||
SRCARCH := tile
|
||||
endif
|
||||
ifeq ($(ARCH),tilegx)
|
||||
SRCARCH := tile
|
||||
endif
|
||||
|
||||
# Where to locate arch specific headers
|
||||
hdr-arch := $(SRCARCH)
|
||||
|
||||
|
@ -339,6 +339,14 @@ config NO_IOPORT
|
||||
|
||||
source "drivers/pci/Kconfig"
|
||||
|
||||
config HOTPLUG
|
||||
bool "Support for hot-pluggable devices"
|
||||
---help---
|
||||
Say Y here if you want to plug devices into your computer while
|
||||
the system is running, and be able to use them quickly. In many
|
||||
cases, the devices can likewise be unplugged at any time too.
|
||||
One well-known example of this is USB.
|
||||
|
||||
source "drivers/pci/hotplug/Kconfig"
|
||||
|
||||
endmenu
|
||||
|
@ -1,71 +0,0 @@
|
||||
CONFIG_EXPERIMENTAL=y
|
||||
# CONFIG_SWAP is not set
|
||||
CONFIG_SYSVIPC=y
|
||||
CONFIG_BLK_DEV_INITRD=y
|
||||
CONFIG_INITRAMFS_SOURCE="usr/contents.txt"
|
||||
CONFIG_EXPERT=y
|
||||
# CONFIG_COMPAT_BRK is not set
|
||||
CONFIG_PROFILING=y
|
||||
CONFIG_MODULES=y
|
||||
CONFIG_MODULE_UNLOAD=y
|
||||
# CONFIG_BLK_DEV_BSG is not set
|
||||
# CONFIG_IOSCHED_DEADLINE is not set
|
||||
# CONFIG_IOSCHED_CFQ is not set
|
||||
CONFIG_NO_HZ=y
|
||||
CONFIG_HIGH_RES_TIMERS=y
|
||||
CONFIG_HZ_100=y
|
||||
CONFIG_NET=y
|
||||
CONFIG_PACKET=y
|
||||
CONFIG_UNIX=y
|
||||
CONFIG_INET=y
|
||||
CONFIG_IP_MULTICAST=y
|
||||
# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
|
||||
# CONFIG_INET_XFRM_MODE_TUNNEL is not set
|
||||
# CONFIG_INET_LRO is not set
|
||||
# CONFIG_INET_DIAG is not set
|
||||
CONFIG_IPV6=y
|
||||
# CONFIG_WIRELESS is not set
|
||||
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
|
||||
CONFIG_SCSI=y
|
||||
CONFIG_BLK_DEV_SD=y
|
||||
CONFIG_SCSI_CONSTANTS=y
|
||||
CONFIG_SCSI_LOGGING=y
|
||||
CONFIG_NETDEVICES=y
|
||||
CONFIG_TUN=y
|
||||
# CONFIG_NETDEV_10000 is not set
|
||||
# CONFIG_WLAN is not set
|
||||
# CONFIG_INPUT_MOUSEDEV is not set
|
||||
# CONFIG_INPUT_KEYBOARD is not set
|
||||
# CONFIG_INPUT_MOUSE is not set
|
||||
# CONFIG_SERIO is not set
|
||||
# CONFIG_VT is not set
|
||||
# CONFIG_LEGACY_PTYS is not set
|
||||
# CONFIG_HW_RANDOM is not set
|
||||
CONFIG_WATCHDOG=y
|
||||
CONFIG_WATCHDOG_NOWAYOUT=y
|
||||
# CONFIG_HID_SUPPORT is not set
|
||||
CONFIG_RTC_CLASS=y
|
||||
# CONFIG_RTC_INTF_SYSFS is not set
|
||||
# CONFIG_RTC_INTF_PROC is not set
|
||||
CONFIG_EXT2_FS=y
|
||||
CONFIG_EXT3_FS=y
|
||||
# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
|
||||
CONFIG_FUSE_FS=y
|
||||
CONFIG_MSDOS_FS=y
|
||||
CONFIG_VFAT_FS=m
|
||||
CONFIG_TMPFS=y
|
||||
CONFIG_HUGETLBFS=y
|
||||
CONFIG_NFS_FS=m
|
||||
CONFIG_NFS_V3=y
|
||||
CONFIG_NLS_CODEPAGE_437=y
|
||||
CONFIG_NLS_ISO8859_1=y
|
||||
CONFIG_FRAME_WARN=2048
|
||||
CONFIG_MAGIC_SYSRQ=y
|
||||
CONFIG_DEBUG_KERNEL=y
|
||||
CONFIG_DETECT_HUNG_TASK=y
|
||||
CONFIG_DEBUG_SPINLOCK_SLEEP=y
|
||||
CONFIG_DEBUG_INFO=y
|
||||
CONFIG_DEBUG_VM=y
|
||||
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
|
||||
CONFIG_DEBUG_STACKOVERFLOW=y
|
||||
CONFIG_DEBUG_EXTRA_FLAGS="-femit-struct-debug-baseonly"
|
1833
arch/tile/configs/tilegx_defconfig
Normal file
1833
arch/tile/configs/tilegx_defconfig
Normal file
File diff suppressed because it is too large
Load Diff
1163
arch/tile/configs/tilepro_defconfig
Normal file
1163
arch/tile/configs/tilepro_defconfig
Normal file
File diff suppressed because it is too large
Load Diff
258
arch/tile/include/arch/chip_tilegx.h
Normal file
258
arch/tile/include/arch/chip_tilegx.h
Normal file
@ -0,0 +1,258 @@
|
||||
/*
|
||||
* Copyright 2011 Tilera Corporation. All Rights Reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation, version 2.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
|
||||
* NON INFRINGEMENT. See the GNU General Public License for
|
||||
* more details.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @file
|
||||
* Global header file.
|
||||
* This header file specifies defines for TILE-Gx.
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_CHIP_H__
|
||||
#define __ARCH_CHIP_H__
|
||||
|
||||
/** Specify chip version.
|
||||
* When possible, prefer the CHIP_xxx symbols below for future-proofing.
|
||||
* This is intended for cross-compiling; native compilation should
|
||||
* use the predefined __tile_chip__ symbol.
|
||||
*/
|
||||
#define TILE_CHIP 10
|
||||
|
||||
/** Specify chip revision.
|
||||
* This provides for the case of a respin of a particular chip type;
|
||||
* the normal value for this symbol is "0".
|
||||
* This is intended for cross-compiling; native compilation should
|
||||
* use the predefined __tile_chip_rev__ symbol.
|
||||
*/
|
||||
#define TILE_CHIP_REV 0
|
||||
|
||||
/** The name of this architecture. */
|
||||
#define CHIP_ARCH_NAME "tilegx"
|
||||
|
||||
/** The ELF e_machine type for binaries for this chip. */
|
||||
#define CHIP_ELF_TYPE() EM_TILEGX
|
||||
|
||||
/** The alternate ELF e_machine type for binaries for this chip. */
|
||||
#define CHIP_COMPAT_ELF_TYPE() 0x2597
|
||||
|
||||
/** What is the native word size of the machine? */
|
||||
#define CHIP_WORD_SIZE() 64
|
||||
|
||||
/** How many bits of a virtual address are used. Extra bits must be
|
||||
* the sign extension of the low bits.
|
||||
*/
|
||||
#define CHIP_VA_WIDTH() 42
|
||||
|
||||
/** How many bits are in a physical address? */
|
||||
#define CHIP_PA_WIDTH() 40
|
||||
|
||||
/** Size of the L2 cache, in bytes. */
|
||||
#define CHIP_L2_CACHE_SIZE() 262144
|
||||
|
||||
/** Log size of an L2 cache line in bytes. */
|
||||
#define CHIP_L2_LOG_LINE_SIZE() 6
|
||||
|
||||
/** Size of an L2 cache line, in bytes. */
|
||||
#define CHIP_L2_LINE_SIZE() (1 << CHIP_L2_LOG_LINE_SIZE())
|
||||
|
||||
/** Associativity of the L2 cache. */
|
||||
#define CHIP_L2_ASSOC() 8
|
||||
|
||||
/** Size of the L1 data cache, in bytes. */
|
||||
#define CHIP_L1D_CACHE_SIZE() 32768
|
||||
|
||||
/** Log size of an L1 data cache line in bytes. */
|
||||
#define CHIP_L1D_LOG_LINE_SIZE() 6
|
||||
|
||||
/** Size of an L1 data cache line, in bytes. */
|
||||
#define CHIP_L1D_LINE_SIZE() (1 << CHIP_L1D_LOG_LINE_SIZE())
|
||||
|
||||
/** Associativity of the L1 data cache. */
|
||||
#define CHIP_L1D_ASSOC() 2
|
||||
|
||||
/** Size of the L1 instruction cache, in bytes. */
|
||||
#define CHIP_L1I_CACHE_SIZE() 32768
|
||||
|
||||
/** Log size of an L1 instruction cache line in bytes. */
|
||||
#define CHIP_L1I_LOG_LINE_SIZE() 6
|
||||
|
||||
/** Size of an L1 instruction cache line, in bytes. */
|
||||
#define CHIP_L1I_LINE_SIZE() (1 << CHIP_L1I_LOG_LINE_SIZE())
|
||||
|
||||
/** Associativity of the L1 instruction cache. */
|
||||
#define CHIP_L1I_ASSOC() 2
|
||||
|
||||
/** Stride with which flush instructions must be issued. */
|
||||
#define CHIP_FLUSH_STRIDE() CHIP_L2_LINE_SIZE()
|
||||
|
||||
/** Stride with which inv instructions must be issued. */
|
||||
#define CHIP_INV_STRIDE() CHIP_L2_LINE_SIZE()
|
||||
|
||||
/** Stride with which finv instructions must be issued. */
|
||||
#define CHIP_FINV_STRIDE() CHIP_L2_LINE_SIZE()
|
||||
|
||||
/** Can the local cache coherently cache data that is homed elsewhere? */
|
||||
#define CHIP_HAS_COHERENT_LOCAL_CACHE() 1
|
||||
|
||||
/** How many simultaneous outstanding victims can the L2 cache have? */
|
||||
#define CHIP_MAX_OUTSTANDING_VICTIMS() 128
|
||||
|
||||
/** Does the TLB support the NC and NOALLOC bits? */
|
||||
#define CHIP_HAS_NC_AND_NOALLOC_BITS() 1
|
||||
|
||||
/** Does the chip support hash-for-home caching? */
|
||||
#define CHIP_HAS_CBOX_HOME_MAP() 1
|
||||
|
||||
/** Number of entries in the chip's home map tables. */
|
||||
#define CHIP_CBOX_HOME_MAP_SIZE() 128
|
||||
|
||||
/** Do uncacheable requests miss in the cache regardless of whether
|
||||
* there is matching data? */
|
||||
#define CHIP_HAS_ENFORCED_UNCACHEABLE_REQUESTS() 1
|
||||
|
||||
/** Does the mf instruction wait for victims? */
|
||||
#define CHIP_HAS_MF_WAITS_FOR_VICTIMS() 0
|
||||
|
||||
/** Does the chip have an "inv" instruction that doesn't also flush? */
|
||||
#define CHIP_HAS_INV() 1
|
||||
|
||||
/** Does the chip have a "wh64" instruction? */
|
||||
#define CHIP_HAS_WH64() 1
|
||||
|
||||
/** Does this chip have a 'dword_align' instruction? */
|
||||
#define CHIP_HAS_DWORD_ALIGN() 0
|
||||
|
||||
/** Number of performance counters. */
|
||||
#define CHIP_PERFORMANCE_COUNTERS() 4
|
||||
|
||||
/** Does this chip have auxiliary performance counters? */
|
||||
#define CHIP_HAS_AUX_PERF_COUNTERS() 1
|
||||
|
||||
/** Is the CBOX_MSR1 SPR supported? */
|
||||
#define CHIP_HAS_CBOX_MSR1() 0
|
||||
|
||||
/** Is the TILE_RTF_HWM SPR supported? */
|
||||
#define CHIP_HAS_TILE_RTF_HWM() 1
|
||||
|
||||
/** Is the TILE_WRITE_PENDING SPR supported? */
|
||||
#define CHIP_HAS_TILE_WRITE_PENDING() 0
|
||||
|
||||
/** Is the PROC_STATUS SPR supported? */
|
||||
#define CHIP_HAS_PROC_STATUS_SPR() 1
|
||||
|
||||
/** Is the DSTREAM_PF SPR supported? */
|
||||
#define CHIP_HAS_DSTREAM_PF() 1
|
||||
|
||||
/** Log of the number of mshims we have. */
|
||||
#define CHIP_LOG_NUM_MSHIMS() 2
|
||||
|
||||
/** Are the bases of the interrupt vector areas fixed? */
|
||||
#define CHIP_HAS_FIXED_INTVEC_BASE() 0
|
||||
|
||||
/** Are the interrupt masks split up into 2 SPRs? */
|
||||
#define CHIP_HAS_SPLIT_INTR_MASK() 0
|
||||
|
||||
/** Is the cycle count split up into 2 SPRs? */
|
||||
#define CHIP_HAS_SPLIT_CYCLE() 0
|
||||
|
||||
/** Does the chip have a static network? */
|
||||
#define CHIP_HAS_SN() 0
|
||||
|
||||
/** Does the chip have a static network processor? */
|
||||
#define CHIP_HAS_SN_PROC() 0
|
||||
|
||||
/** Size of the L1 static network processor instruction cache, in bytes. */
|
||||
/* #define CHIP_L1SNI_CACHE_SIZE() -- does not apply to chip 10 */
|
||||
|
||||
/** Does the chip have DMA support in each tile? */
|
||||
#define CHIP_HAS_TILE_DMA() 0
|
||||
|
||||
/** Does the chip have the second revision of the directly accessible
|
||||
* dynamic networks? This encapsulates a number of characteristics,
|
||||
* including the absence of the catch-all, the absence of inline message
|
||||
* tags, the absence of support for network context-switching, and so on.
|
||||
*/
|
||||
#define CHIP_HAS_REV1_XDN() 1
|
||||
|
||||
/** Does the chip have cmpexch and similar (fetchadd, exch, etc.)? */
|
||||
#define CHIP_HAS_CMPEXCH() 1
|
||||
|
||||
/** Does the chip have memory-mapped I/O support? */
|
||||
#define CHIP_HAS_MMIO() 1
|
||||
|
||||
/** Does the chip have post-completion interrupts? */
|
||||
#define CHIP_HAS_POST_COMPLETION_INTERRUPTS() 1
|
||||
|
||||
/** Does the chip have native single step support? */
|
||||
#define CHIP_HAS_SINGLE_STEP() 1
|
||||
|
||||
#ifndef __OPEN_SOURCE__ /* features only relevant to hypervisor-level code */
|
||||
|
||||
/** How many entries are present in the instruction TLB? */
|
||||
#define CHIP_ITLB_ENTRIES() 16
|
||||
|
||||
/** How many entries are present in the data TLB? */
|
||||
#define CHIP_DTLB_ENTRIES() 32
|
||||
|
||||
/** How many MAF entries does the XAUI shim have? */
|
||||
#define CHIP_XAUI_MAF_ENTRIES() 32
|
||||
|
||||
/** Does the memory shim have a source-id table? */
|
||||
#define CHIP_HAS_MSHIM_SRCID_TABLE() 0
|
||||
|
||||
/** Does the L1 instruction cache clear on reset? */
|
||||
#define CHIP_HAS_L1I_CLEAR_ON_RESET() 1
|
||||
|
||||
/** Does the chip come out of reset with valid coordinates on all tiles?
|
||||
* Note that if defined, this also implies that the upper left is 1,1.
|
||||
*/
|
||||
#define CHIP_HAS_VALID_TILE_COORD_RESET() 1
|
||||
|
||||
/** Does the chip have unified packet formats? */
|
||||
#define CHIP_HAS_UNIFIED_PACKET_FORMATS() 1
|
||||
|
||||
/** Does the chip support write reordering? */
|
||||
#define CHIP_HAS_WRITE_REORDERING() 1
|
||||
|
||||
/** Does the chip support Y-X routing as well as X-Y? */
|
||||
#define CHIP_HAS_Y_X_ROUTING() 1
|
||||
|
||||
/** Is INTCTRL_3 managed with the correct MPL? */
|
||||
#define CHIP_HAS_INTCTRL_3_STATUS_FIX() 1
|
||||
|
||||
/** Is it possible to configure the chip to be big-endian? */
|
||||
#define CHIP_HAS_BIG_ENDIAN_CONFIG() 1
|
||||
|
||||
/** Is the CACHE_RED_WAY_OVERRIDDEN SPR supported? */
|
||||
#define CHIP_HAS_CACHE_RED_WAY_OVERRIDDEN() 0
|
||||
|
||||
/** Is the DIAG_TRACE_WAY SPR supported? */
|
||||
#define CHIP_HAS_DIAG_TRACE_WAY() 0
|
||||
|
||||
/** Is the MEM_STRIPE_CONFIG SPR supported? */
|
||||
#define CHIP_HAS_MEM_STRIPE_CONFIG() 1
|
||||
|
||||
/** Are the TLB_PERF SPRs supported? */
|
||||
#define CHIP_HAS_TLB_PERF() 1
|
||||
|
||||
/** Is the VDN_SNOOP_SHIM_CTL SPR supported? */
|
||||
#define CHIP_HAS_VDN_SNOOP_SHIM_CTL() 0
|
||||
|
||||
/** Does the chip support rev1 DMA packets? */
|
||||
#define CHIP_HAS_REV1_DMA_PACKETS() 1
|
||||
|
||||
/** Does the chip have an IPI shim? */
|
||||
#define CHIP_HAS_IPI() 1
|
||||
|
||||
#endif /* !__OPEN_SOURCE__ */
|
||||
#endif /* __ARCH_CHIP_H__ */
|
@ -16,7 +16,7 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* Support for invalidating bytes in the instruction
|
||||
* Support for invalidating bytes in the instruction cache.
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_ICACHE_H__
|
||||
@ -30,11 +30,10 @@
|
||||
*
|
||||
* @param addr The start of memory to be invalidated.
|
||||
* @param size The number of bytes to be invalidated.
|
||||
* @param page_size The system's page size, typically the PAGE_SIZE constant
|
||||
* in sys/page.h. This value must be a power of two no larger
|
||||
* than the page containing the code to be invalidated. If the value
|
||||
* is smaller than the actual page size, this function will still
|
||||
* work, but may run slower than necessary.
|
||||
* @param page_size The system's page size, e.g. getpagesize() in userspace.
|
||||
* This value must be a power of two no larger than the page containing
|
||||
* the code to be invalidated. If the value is smaller than the actual page
|
||||
* size, this function will still work, but may run slower than necessary.
|
||||
*/
|
||||
static __inline void
|
||||
invalidate_icache(const void* addr, unsigned long size,
|
||||
|
276
arch/tile/include/arch/interrupts_64.h
Normal file
276
arch/tile/include/arch/interrupts_64.h
Normal file
@ -0,0 +1,276 @@
|
||||
/*
|
||||
* Copyright 2011 Tilera Corporation. All Rights Reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation, version 2.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
|
||||
* NON INFRINGEMENT. See the GNU General Public License for
|
||||
* more details.
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_INTERRUPTS_H__
|
||||
#define __ARCH_INTERRUPTS_H__
|
||||
|
||||
/** Mask for an interrupt. */
|
||||
#ifdef __ASSEMBLER__
|
||||
/* Note: must handle breaking interrupts into high and low words manually. */
|
||||
#define INT_MASK(intno) (1 << (intno))
|
||||
#else
|
||||
#define INT_MASK(intno) (1ULL << (intno))
|
||||
#endif
|
||||
|
||||
|
||||
/** Where a given interrupt executes */
|
||||
#define INTERRUPT_VECTOR(i, pl) (0xFC000000 + ((pl) << 24) + ((i) << 8))
|
||||
|
||||
/** Where to store a vector for a given interrupt. */
|
||||
#define USER_INTERRUPT_VECTOR(i) INTERRUPT_VECTOR(i, 0)
|
||||
|
||||
/** The base address of user-level interrupts. */
|
||||
#define USER_INTERRUPT_VECTOR_BASE INTERRUPT_VECTOR(0, 0)
|
||||
|
||||
|
||||
/** Additional synthetic interrupt. */
|
||||
#define INT_BREAKPOINT (63)
|
||||
|
||||
#define INT_MEM_ERROR 0
|
||||
#define INT_SINGLE_STEP_3 1
|
||||
#define INT_SINGLE_STEP_2 2
|
||||
#define INT_SINGLE_STEP_1 3
|
||||
#define INT_SINGLE_STEP_0 4
|
||||
#define INT_IDN_COMPLETE 5
|
||||
#define INT_UDN_COMPLETE 6
|
||||
#define INT_ITLB_MISS 7
|
||||
#define INT_ILL 8
|
||||
#define INT_GPV 9
|
||||
#define INT_IDN_ACCESS 10
|
||||
#define INT_UDN_ACCESS 11
|
||||
#define INT_SWINT_3 12
|
||||
#define INT_SWINT_2 13
|
||||
#define INT_SWINT_1 14
|
||||
#define INT_SWINT_0 15
|
||||
#define INT_ILL_TRANS 16
|
||||
#define INT_UNALIGN_DATA 17
|
||||
#define INT_DTLB_MISS 18
|
||||
#define INT_DTLB_ACCESS 19
|
||||
#define INT_IDN_FIREWALL 20
|
||||
#define INT_UDN_FIREWALL 21
|
||||
#define INT_TILE_TIMER 22
|
||||
#define INT_AUX_TILE_TIMER 23
|
||||
#define INT_IDN_TIMER 24
|
||||
#define INT_UDN_TIMER 25
|
||||
#define INT_IDN_AVAIL 26
|
||||
#define INT_UDN_AVAIL 27
|
||||
#define INT_IPI_3 28
|
||||
#define INT_IPI_2 29
|
||||
#define INT_IPI_1 30
|
||||
#define INT_IPI_0 31
|
||||
#define INT_PERF_COUNT 32
|
||||
#define INT_AUX_PERF_COUNT 33
|
||||
#define INT_INTCTRL_3 34
|
||||
#define INT_INTCTRL_2 35
|
||||
#define INT_INTCTRL_1 36
|
||||
#define INT_INTCTRL_0 37
|
||||
#define INT_BOOT_ACCESS 38
|
||||
#define INT_WORLD_ACCESS 39
|
||||
#define INT_I_ASID 40
|
||||
#define INT_D_ASID 41
|
||||
#define INT_DOUBLE_FAULT 42
|
||||
|
||||
#define NUM_INTERRUPTS 43
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
#define QUEUED_INTERRUPTS ( \
|
||||
INT_MASK(INT_MEM_ERROR) | \
|
||||
INT_MASK(INT_IDN_COMPLETE) | \
|
||||
INT_MASK(INT_UDN_COMPLETE) | \
|
||||
INT_MASK(INT_IDN_FIREWALL) | \
|
||||
INT_MASK(INT_UDN_FIREWALL) | \
|
||||
INT_MASK(INT_TILE_TIMER) | \
|
||||
INT_MASK(INT_AUX_TILE_TIMER) | \
|
||||
INT_MASK(INT_IDN_TIMER) | \
|
||||
INT_MASK(INT_UDN_TIMER) | \
|
||||
INT_MASK(INT_IDN_AVAIL) | \
|
||||
INT_MASK(INT_UDN_AVAIL) | \
|
||||
INT_MASK(INT_IPI_3) | \
|
||||
INT_MASK(INT_IPI_2) | \
|
||||
INT_MASK(INT_IPI_1) | \
|
||||
INT_MASK(INT_IPI_0) | \
|
||||
INT_MASK(INT_PERF_COUNT) | \
|
||||
INT_MASK(INT_AUX_PERF_COUNT) | \
|
||||
INT_MASK(INT_INTCTRL_3) | \
|
||||
INT_MASK(INT_INTCTRL_2) | \
|
||||
INT_MASK(INT_INTCTRL_1) | \
|
||||
INT_MASK(INT_INTCTRL_0) | \
|
||||
INT_MASK(INT_BOOT_ACCESS) | \
|
||||
INT_MASK(INT_WORLD_ACCESS) | \
|
||||
INT_MASK(INT_I_ASID) | \
|
||||
INT_MASK(INT_D_ASID) | \
|
||||
INT_MASK(INT_DOUBLE_FAULT) | \
|
||||
0)
|
||||
#define NONQUEUED_INTERRUPTS ( \
|
||||
INT_MASK(INT_SINGLE_STEP_3) | \
|
||||
INT_MASK(INT_SINGLE_STEP_2) | \
|
||||
INT_MASK(INT_SINGLE_STEP_1) | \
|
||||
INT_MASK(INT_SINGLE_STEP_0) | \
|
||||
INT_MASK(INT_ITLB_MISS) | \
|
||||
INT_MASK(INT_ILL) | \
|
||||
INT_MASK(INT_GPV) | \
|
||||
INT_MASK(INT_IDN_ACCESS) | \
|
||||
INT_MASK(INT_UDN_ACCESS) | \
|
||||
INT_MASK(INT_SWINT_3) | \
|
||||
INT_MASK(INT_SWINT_2) | \
|
||||
INT_MASK(INT_SWINT_1) | \
|
||||
INT_MASK(INT_SWINT_0) | \
|
||||
INT_MASK(INT_ILL_TRANS) | \
|
||||
INT_MASK(INT_UNALIGN_DATA) | \
|
||||
INT_MASK(INT_DTLB_MISS) | \
|
||||
INT_MASK(INT_DTLB_ACCESS) | \
|
||||
0)
|
||||
#define CRITICAL_MASKED_INTERRUPTS ( \
|
||||
INT_MASK(INT_MEM_ERROR) | \
|
||||
INT_MASK(INT_SINGLE_STEP_3) | \
|
||||
INT_MASK(INT_SINGLE_STEP_2) | \
|
||||
INT_MASK(INT_SINGLE_STEP_1) | \
|
||||
INT_MASK(INT_SINGLE_STEP_0) | \
|
||||
INT_MASK(INT_IDN_COMPLETE) | \
|
||||
INT_MASK(INT_UDN_COMPLETE) | \
|
||||
INT_MASK(INT_IDN_FIREWALL) | \
|
||||
INT_MASK(INT_UDN_FIREWALL) | \
|
||||
INT_MASK(INT_TILE_TIMER) | \
|
||||
INT_MASK(INT_AUX_TILE_TIMER) | \
|
||||
INT_MASK(INT_IDN_TIMER) | \
|
||||
INT_MASK(INT_UDN_TIMER) | \
|
||||
INT_MASK(INT_IDN_AVAIL) | \
|
||||
INT_MASK(INT_UDN_AVAIL) | \
|
||||
INT_MASK(INT_IPI_3) | \
|
||||
INT_MASK(INT_IPI_2) | \
|
||||
INT_MASK(INT_IPI_1) | \
|
||||
INT_MASK(INT_IPI_0) | \
|
||||
INT_MASK(INT_PERF_COUNT) | \
|
||||
INT_MASK(INT_AUX_PERF_COUNT) | \
|
||||
INT_MASK(INT_INTCTRL_3) | \
|
||||
INT_MASK(INT_INTCTRL_2) | \
|
||||
INT_MASK(INT_INTCTRL_1) | \
|
||||
INT_MASK(INT_INTCTRL_0) | \
|
||||
0)
|
||||
#define CRITICAL_UNMASKED_INTERRUPTS ( \
|
||||
INT_MASK(INT_ITLB_MISS) | \
|
||||
INT_MASK(INT_ILL) | \
|
||||
INT_MASK(INT_GPV) | \
|
||||
INT_MASK(INT_IDN_ACCESS) | \
|
||||
INT_MASK(INT_UDN_ACCESS) | \
|
||||
INT_MASK(INT_SWINT_3) | \
|
||||
INT_MASK(INT_SWINT_2) | \
|
||||
INT_MASK(INT_SWINT_1) | \
|
||||
INT_MASK(INT_SWINT_0) | \
|
||||
INT_MASK(INT_ILL_TRANS) | \
|
||||
INT_MASK(INT_UNALIGN_DATA) | \
|
||||
INT_MASK(INT_DTLB_MISS) | \
|
||||
INT_MASK(INT_DTLB_ACCESS) | \
|
||||
INT_MASK(INT_BOOT_ACCESS) | \
|
||||
INT_MASK(INT_WORLD_ACCESS) | \
|
||||
INT_MASK(INT_I_ASID) | \
|
||||
INT_MASK(INT_D_ASID) | \
|
||||
INT_MASK(INT_DOUBLE_FAULT) | \
|
||||
0)
|
||||
#define MASKABLE_INTERRUPTS ( \
|
||||
INT_MASK(INT_MEM_ERROR) | \
|
||||
INT_MASK(INT_SINGLE_STEP_3) | \
|
||||
INT_MASK(INT_SINGLE_STEP_2) | \
|
||||
INT_MASK(INT_SINGLE_STEP_1) | \
|
||||
INT_MASK(INT_SINGLE_STEP_0) | \
|
||||
INT_MASK(INT_IDN_COMPLETE) | \
|
||||
INT_MASK(INT_UDN_COMPLETE) | \
|
||||
INT_MASK(INT_IDN_FIREWALL) | \
|
||||
INT_MASK(INT_UDN_FIREWALL) | \
|
||||
INT_MASK(INT_TILE_TIMER) | \
|
||||
INT_MASK(INT_AUX_TILE_TIMER) | \
|
||||
INT_MASK(INT_IDN_TIMER) | \
|
||||
INT_MASK(INT_UDN_TIMER) | \
|
||||
INT_MASK(INT_IDN_AVAIL) | \
|
||||
INT_MASK(INT_UDN_AVAIL) | \
|
||||
INT_MASK(INT_IPI_3) | \
|
||||
INT_MASK(INT_IPI_2) | \
|
||||
INT_MASK(INT_IPI_1) | \
|
||||
INT_MASK(INT_IPI_0) | \
|
||||
INT_MASK(INT_PERF_COUNT) | \
|
||||
INT_MASK(INT_AUX_PERF_COUNT) | \
|
||||
INT_MASK(INT_INTCTRL_3) | \
|
||||
INT_MASK(INT_INTCTRL_2) | \
|
||||
INT_MASK(INT_INTCTRL_1) | \
|
||||
INT_MASK(INT_INTCTRL_0) | \
|
||||
0)
|
||||
#define UNMASKABLE_INTERRUPTS ( \
|
||||
INT_MASK(INT_ITLB_MISS) | \
|
||||
INT_MASK(INT_ILL) | \
|
||||
INT_MASK(INT_GPV) | \
|
||||
INT_MASK(INT_IDN_ACCESS) | \
|
||||
INT_MASK(INT_UDN_ACCESS) | \
|
||||
INT_MASK(INT_SWINT_3) | \
|
||||
INT_MASK(INT_SWINT_2) | \
|
||||
INT_MASK(INT_SWINT_1) | \
|
||||
INT_MASK(INT_SWINT_0) | \
|
||||
INT_MASK(INT_ILL_TRANS) | \
|
||||
INT_MASK(INT_UNALIGN_DATA) | \
|
||||
INT_MASK(INT_DTLB_MISS) | \
|
||||
INT_MASK(INT_DTLB_ACCESS) | \
|
||||
INT_MASK(INT_BOOT_ACCESS) | \
|
||||
INT_MASK(INT_WORLD_ACCESS) | \
|
||||
INT_MASK(INT_I_ASID) | \
|
||||
INT_MASK(INT_D_ASID) | \
|
||||
INT_MASK(INT_DOUBLE_FAULT) | \
|
||||
0)
|
||||
#define SYNC_INTERRUPTS ( \
|
||||
INT_MASK(INT_SINGLE_STEP_3) | \
|
||||
INT_MASK(INT_SINGLE_STEP_2) | \
|
||||
INT_MASK(INT_SINGLE_STEP_1) | \
|
||||
INT_MASK(INT_SINGLE_STEP_0) | \
|
||||
INT_MASK(INT_IDN_COMPLETE) | \
|
||||
INT_MASK(INT_UDN_COMPLETE) | \
|
||||
INT_MASK(INT_ITLB_MISS) | \
|
||||
INT_MASK(INT_ILL) | \
|
||||
INT_MASK(INT_GPV) | \
|
||||
INT_MASK(INT_IDN_ACCESS) | \
|
||||
INT_MASK(INT_UDN_ACCESS) | \
|
||||
INT_MASK(INT_SWINT_3) | \
|
||||
INT_MASK(INT_SWINT_2) | \
|
||||
INT_MASK(INT_SWINT_1) | \
|
||||
INT_MASK(INT_SWINT_0) | \
|
||||
INT_MASK(INT_ILL_TRANS) | \
|
||||
INT_MASK(INT_UNALIGN_DATA) | \
|
||||
INT_MASK(INT_DTLB_MISS) | \
|
||||
INT_MASK(INT_DTLB_ACCESS) | \
|
||||
0)
|
||||
#define NON_SYNC_INTERRUPTS ( \
|
||||
INT_MASK(INT_MEM_ERROR) | \
|
||||
INT_MASK(INT_IDN_FIREWALL) | \
|
||||
INT_MASK(INT_UDN_FIREWALL) | \
|
||||
INT_MASK(INT_TILE_TIMER) | \
|
||||
INT_MASK(INT_AUX_TILE_TIMER) | \
|
||||
INT_MASK(INT_IDN_TIMER) | \
|
||||
INT_MASK(INT_UDN_TIMER) | \
|
||||
INT_MASK(INT_IDN_AVAIL) | \
|
||||
INT_MASK(INT_UDN_AVAIL) | \
|
||||
INT_MASK(INT_IPI_3) | \
|
||||
INT_MASK(INT_IPI_2) | \
|
||||
INT_MASK(INT_IPI_1) | \
|
||||
INT_MASK(INT_IPI_0) | \
|
||||
INT_MASK(INT_PERF_COUNT) | \
|
||||
INT_MASK(INT_AUX_PERF_COUNT) | \
|
||||
INT_MASK(INT_INTCTRL_3) | \
|
||||
INT_MASK(INT_INTCTRL_2) | \
|
||||
INT_MASK(INT_INTCTRL_1) | \
|
||||
INT_MASK(INT_INTCTRL_0) | \
|
||||
INT_MASK(INT_BOOT_ACCESS) | \
|
||||
INT_MASK(INT_WORLD_ACCESS) | \
|
||||
INT_MASK(INT_I_ASID) | \
|
||||
INT_MASK(INT_D_ASID) | \
|
||||
INT_MASK(INT_DOUBLE_FAULT) | \
|
||||
0)
|
||||
#endif /* !__ASSEMBLER__ */
|
||||
#endif /* !__ARCH_INTERRUPTS_H__ */
|
@ -12,6 +12,15 @@
|
||||
* more details.
|
||||
*/
|
||||
|
||||
/* Include the proper base SPR definition file. */
|
||||
#ifdef __tilegx__
|
||||
#include <arch/spr_def_64.h>
|
||||
#else
|
||||
#include <arch/spr_def_32.h>
|
||||
#endif
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
/*
|
||||
* In addition to including the proper base SPR definition file, depending
|
||||
* on machine architecture, this file defines several macros which allow
|
||||
@ -29,7 +38,6 @@
|
||||
#define _concat4(a, b, c, d) __concat4(a, b, c, d)
|
||||
|
||||
#ifdef __tilegx__
|
||||
#include <arch/spr_def_64.h>
|
||||
|
||||
/* TILE-Gx dependent, protection-level dependent SPRs. */
|
||||
|
||||
@ -65,7 +73,6 @@
|
||||
_concat4(INT_SINGLE_STEP_, CONFIG_KERNEL_PL,,)
|
||||
|
||||
#else
|
||||
#include <arch/spr_def_32.h>
|
||||
|
||||
/* TILEPro dependent, protection-level dependent SPRs. */
|
||||
|
||||
@ -102,3 +109,5 @@
|
||||
_concat4(SPR_INTCTRL_, CONFIG_KERNEL_PL, _STATUS,)
|
||||
#define INT_INTCTRL_K \
|
||||
_concat4(INT_INTCTRL_, CONFIG_KERNEL_PL,,)
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
173
arch/tile/include/arch/spr_def_64.h
Normal file
173
arch/tile/include/arch/spr_def_64.h
Normal file
@ -0,0 +1,173 @@
|
||||
/*
|
||||
* Copyright 2011 Tilera Corporation. All Rights Reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation, version 2.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
|
||||
* NON INFRINGEMENT. See the GNU General Public License for
|
||||
* more details.
|
||||
*/
|
||||
|
||||
#ifndef __DOXYGEN__
|
||||
|
||||
#ifndef __ARCH_SPR_DEF_H__
|
||||
#define __ARCH_SPR_DEF_H__
|
||||
|
||||
#define SPR_AUX_PERF_COUNT_0 0x2105
|
||||
#define SPR_AUX_PERF_COUNT_1 0x2106
|
||||
#define SPR_AUX_PERF_COUNT_CTL 0x2107
|
||||
#define SPR_AUX_PERF_COUNT_STS 0x2108
|
||||
#define SPR_CMPEXCH_VALUE 0x2780
|
||||
#define SPR_CYCLE 0x2781
|
||||
#define SPR_DONE 0x2705
|
||||
#define SPR_DSTREAM_PF 0x2706
|
||||
#define SPR_EVENT_BEGIN 0x2782
|
||||
#define SPR_EVENT_END 0x2783
|
||||
#define SPR_EX_CONTEXT_0_0 0x2580
|
||||
#define SPR_EX_CONTEXT_0_1 0x2581
|
||||
#define SPR_EX_CONTEXT_0_1__PL_SHIFT 0
|
||||
#define SPR_EX_CONTEXT_0_1__PL_RMASK 0x3
|
||||
#define SPR_EX_CONTEXT_0_1__PL_MASK 0x3
|
||||
#define SPR_EX_CONTEXT_0_1__ICS_SHIFT 2
|
||||
#define SPR_EX_CONTEXT_0_1__ICS_RMASK 0x1
|
||||
#define SPR_EX_CONTEXT_0_1__ICS_MASK 0x4
|
||||
#define SPR_EX_CONTEXT_1_0 0x2480
|
||||
#define SPR_EX_CONTEXT_1_1 0x2481
|
||||
#define SPR_EX_CONTEXT_1_1__PL_SHIFT 0
|
||||
#define SPR_EX_CONTEXT_1_1__PL_RMASK 0x3
|
||||
#define SPR_EX_CONTEXT_1_1__PL_MASK 0x3
|
||||
#define SPR_EX_CONTEXT_1_1__ICS_SHIFT 2
|
||||
#define SPR_EX_CONTEXT_1_1__ICS_RMASK 0x1
|
||||
#define SPR_EX_CONTEXT_1_1__ICS_MASK 0x4
|
||||
#define SPR_EX_CONTEXT_2_0 0x2380
|
||||
#define SPR_EX_CONTEXT_2_1 0x2381
|
||||
#define SPR_EX_CONTEXT_2_1__PL_SHIFT 0
|
||||
#define SPR_EX_CONTEXT_2_1__PL_RMASK 0x3
|
||||
#define SPR_EX_CONTEXT_2_1__PL_MASK 0x3
|
||||
#define SPR_EX_CONTEXT_2_1__ICS_SHIFT 2
|
||||
#define SPR_EX_CONTEXT_2_1__ICS_RMASK 0x1
|
||||
#define SPR_EX_CONTEXT_2_1__ICS_MASK 0x4
|
||||
#define SPR_FAIL 0x2707
|
||||
#define SPR_ILL_TRANS_REASON__I_STREAM_VA_RMASK 0x1
|
||||
#define SPR_INTCTRL_0_STATUS 0x2505
|
||||
#define SPR_INTCTRL_1_STATUS 0x2405
|
||||
#define SPR_INTCTRL_2_STATUS 0x2305
|
||||
#define SPR_INTERRUPT_CRITICAL_SECTION 0x2708
|
||||
#define SPR_INTERRUPT_MASK_0 0x2506
|
||||
#define SPR_INTERRUPT_MASK_1 0x2406
|
||||
#define SPR_INTERRUPT_MASK_2 0x2306
|
||||
#define SPR_INTERRUPT_MASK_RESET_0 0x2507
|
||||
#define SPR_INTERRUPT_MASK_RESET_1 0x2407
|
||||
#define SPR_INTERRUPT_MASK_RESET_2 0x2307
|
||||
#define SPR_INTERRUPT_MASK_SET_0 0x2508
|
||||
#define SPR_INTERRUPT_MASK_SET_1 0x2408
|
||||
#define SPR_INTERRUPT_MASK_SET_2 0x2308
|
||||
#define SPR_INTERRUPT_VECTOR_BASE_0 0x2509
|
||||
#define SPR_INTERRUPT_VECTOR_BASE_1 0x2409
|
||||
#define SPR_INTERRUPT_VECTOR_BASE_2 0x2309
|
||||
#define SPR_INTERRUPT_VECTOR_BASE_3 0x2209
|
||||
#define SPR_IPI_EVENT_0 0x1f05
|
||||
#define SPR_IPI_EVENT_1 0x1e05
|
||||
#define SPR_IPI_EVENT_2 0x1d05
|
||||
#define SPR_IPI_EVENT_RESET_0 0x1f06
|
||||
#define SPR_IPI_EVENT_RESET_1 0x1e06
|
||||
#define SPR_IPI_EVENT_RESET_2 0x1d06
|
||||
#define SPR_IPI_EVENT_SET_0 0x1f07
|
||||
#define SPR_IPI_EVENT_SET_1 0x1e07
|
||||
#define SPR_IPI_EVENT_SET_2 0x1d07
|
||||
#define SPR_IPI_MASK_0 0x1f08
|
||||
#define SPR_IPI_MASK_1 0x1e08
|
||||
#define SPR_IPI_MASK_2 0x1d08
|
||||
#define SPR_IPI_MASK_RESET_0 0x1f09
|
||||
#define SPR_IPI_MASK_RESET_1 0x1e09
|
||||
#define SPR_IPI_MASK_RESET_2 0x1d09
|
||||
#define SPR_IPI_MASK_SET_0 0x1f0a
|
||||
#define SPR_IPI_MASK_SET_1 0x1e0a
|
||||
#define SPR_IPI_MASK_SET_2 0x1d0a
|
||||
#define SPR_MPL_AUX_TILE_TIMER_SET_0 0x1700
|
||||
#define SPR_MPL_AUX_TILE_TIMER_SET_1 0x1701
|
||||
#define SPR_MPL_AUX_TILE_TIMER_SET_2 0x1702
|
||||
#define SPR_MPL_INTCTRL_0_SET_0 0x2500
|
||||
#define SPR_MPL_INTCTRL_0_SET_1 0x2501
|
||||
#define SPR_MPL_INTCTRL_0_SET_2 0x2502
|
||||
#define SPR_MPL_INTCTRL_1_SET_0 0x2400
|
||||
#define SPR_MPL_INTCTRL_1_SET_1 0x2401
|
||||
#define SPR_MPL_INTCTRL_1_SET_2 0x2402
|
||||
#define SPR_MPL_INTCTRL_2_SET_0 0x2300
|
||||
#define SPR_MPL_INTCTRL_2_SET_1 0x2301
|
||||
#define SPR_MPL_INTCTRL_2_SET_2 0x2302
|
||||
#define SPR_MPL_UDN_ACCESS_SET_0 0x0b00
|
||||
#define SPR_MPL_UDN_ACCESS_SET_1 0x0b01
|
||||
#define SPR_MPL_UDN_ACCESS_SET_2 0x0b02
|
||||
#define SPR_MPL_UDN_AVAIL_SET_0 0x1b00
|
||||
#define SPR_MPL_UDN_AVAIL_SET_1 0x1b01
|
||||
#define SPR_MPL_UDN_AVAIL_SET_2 0x1b02
|
||||
#define SPR_MPL_UDN_COMPLETE_SET_0 0x0600
|
||||
#define SPR_MPL_UDN_COMPLETE_SET_1 0x0601
|
||||
#define SPR_MPL_UDN_COMPLETE_SET_2 0x0602
|
||||
#define SPR_MPL_UDN_FIREWALL_SET_0 0x1500
|
||||
#define SPR_MPL_UDN_FIREWALL_SET_1 0x1501
|
||||
#define SPR_MPL_UDN_FIREWALL_SET_2 0x1502
|
||||
#define SPR_MPL_UDN_TIMER_SET_0 0x1900
|
||||
#define SPR_MPL_UDN_TIMER_SET_1 0x1901
|
||||
#define SPR_MPL_UDN_TIMER_SET_2 0x1902
|
||||
#define SPR_MPL_WORLD_ACCESS_SET_0 0x2700
|
||||
#define SPR_MPL_WORLD_ACCESS_SET_1 0x2701
|
||||
#define SPR_MPL_WORLD_ACCESS_SET_2 0x2702
|
||||
#define SPR_PASS 0x2709
|
||||
#define SPR_PERF_COUNT_0 0x2005
|
||||
#define SPR_PERF_COUNT_1 0x2006
|
||||
#define SPR_PERF_COUNT_CTL 0x2007
|
||||
#define SPR_PERF_COUNT_DN_CTL 0x2008
|
||||
#define SPR_PERF_COUNT_STS 0x2009
|
||||
#define SPR_PROC_STATUS 0x2784
|
||||
#define SPR_SIM_CONTROL 0x2785
|
||||
#define SPR_SINGLE_STEP_CONTROL_0 0x0405
|
||||
#define SPR_SINGLE_STEP_CONTROL_0__CANCELED_MASK 0x1
|
||||
#define SPR_SINGLE_STEP_CONTROL_0__INHIBIT_MASK 0x2
|
||||
#define SPR_SINGLE_STEP_CONTROL_1 0x0305
|
||||
#define SPR_SINGLE_STEP_CONTROL_1__CANCELED_MASK 0x1
|
||||
#define SPR_SINGLE_STEP_CONTROL_1__INHIBIT_MASK 0x2
|
||||
#define SPR_SINGLE_STEP_CONTROL_2 0x0205
|
||||
#define SPR_SINGLE_STEP_CONTROL_2__CANCELED_MASK 0x1
|
||||
#define SPR_SINGLE_STEP_CONTROL_2__INHIBIT_MASK 0x2
|
||||
#define SPR_SINGLE_STEP_EN_0_0 0x250a
|
||||
#define SPR_SINGLE_STEP_EN_0_1 0x240a
|
||||
#define SPR_SINGLE_STEP_EN_0_2 0x230a
|
||||
#define SPR_SINGLE_STEP_EN_1_0 0x250b
|
||||
#define SPR_SINGLE_STEP_EN_1_1 0x240b
|
||||
#define SPR_SINGLE_STEP_EN_1_2 0x230b
|
||||
#define SPR_SINGLE_STEP_EN_2_0 0x250c
|
||||
#define SPR_SINGLE_STEP_EN_2_1 0x240c
|
||||
#define SPR_SINGLE_STEP_EN_2_2 0x230c
|
||||
#define SPR_SYSTEM_SAVE_0_0 0x2582
|
||||
#define SPR_SYSTEM_SAVE_0_1 0x2583
|
||||
#define SPR_SYSTEM_SAVE_0_2 0x2584
|
||||
#define SPR_SYSTEM_SAVE_0_3 0x2585
|
||||
#define SPR_SYSTEM_SAVE_1_0 0x2482
|
||||
#define SPR_SYSTEM_SAVE_1_1 0x2483
|
||||
#define SPR_SYSTEM_SAVE_1_2 0x2484
|
||||
#define SPR_SYSTEM_SAVE_1_3 0x2485
|
||||
#define SPR_SYSTEM_SAVE_2_0 0x2382
|
||||
#define SPR_SYSTEM_SAVE_2_1 0x2383
|
||||
#define SPR_SYSTEM_SAVE_2_2 0x2384
|
||||
#define SPR_SYSTEM_SAVE_2_3 0x2385
|
||||
#define SPR_TILE_COORD 0x270b
|
||||
#define SPR_TILE_RTF_HWM 0x270c
|
||||
#define SPR_TILE_TIMER_CONTROL 0x1605
|
||||
#define SPR_UDN_AVAIL_EN 0x1b05
|
||||
#define SPR_UDN_DATA_AVAIL 0x0b80
|
||||
#define SPR_UDN_DEADLOCK_TIMEOUT 0x1906
|
||||
#define SPR_UDN_DEMUX_COUNT_0 0x0b05
|
||||
#define SPR_UDN_DEMUX_COUNT_1 0x0b06
|
||||
#define SPR_UDN_DEMUX_COUNT_2 0x0b07
|
||||
#define SPR_UDN_DEMUX_COUNT_3 0x0b08
|
||||
#define SPR_UDN_DIRECTION_PROTECT 0x1505
|
||||
|
||||
#endif /* !defined(__ARCH_SPR_DEF_H__) */
|
||||
|
||||
#endif /* !defined(__DOXYGEN__) */
|
@ -130,17 +130,52 @@ static inline int atomic_read(const atomic_t *v)
|
||||
*/
|
||||
#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
|
||||
|
||||
|
||||
/*
|
||||
* We define xchg() and cmpxchg() in the included headers.
|
||||
* Note that we do not define __HAVE_ARCH_CMPXCHG, since that would imply
|
||||
* that cmpxchg() is an efficient operation, which is not particularly true.
|
||||
*/
|
||||
|
||||
/* Nonexistent functions intended to cause link errors. */
|
||||
extern unsigned long __xchg_called_with_bad_pointer(void);
|
||||
extern unsigned long __cmpxchg_called_with_bad_pointer(void);
|
||||
|
||||
#define xchg(ptr, x) \
|
||||
({ \
|
||||
typeof(*(ptr)) __x; \
|
||||
switch (sizeof(*(ptr))) { \
|
||||
case 4: \
|
||||
__x = (typeof(__x))(typeof(__x-__x))atomic_xchg( \
|
||||
(atomic_t *)(ptr), \
|
||||
(u32)(typeof((x)-(x)))(x)); \
|
||||
break; \
|
||||
case 8: \
|
||||
__x = (typeof(__x))(typeof(__x-__x))atomic64_xchg( \
|
||||
(atomic64_t *)(ptr), \
|
||||
(u64)(typeof((x)-(x)))(x)); \
|
||||
break; \
|
||||
default: \
|
||||
__xchg_called_with_bad_pointer(); \
|
||||
} \
|
||||
__x; \
|
||||
})
|
||||
|
||||
#define cmpxchg(ptr, o, n) \
|
||||
({ \
|
||||
typeof(*(ptr)) __x; \
|
||||
switch (sizeof(*(ptr))) { \
|
||||
case 4: \
|
||||
__x = (typeof(__x))(typeof(__x-__x))atomic_cmpxchg( \
|
||||
(atomic_t *)(ptr), \
|
||||
(u32)(typeof((o)-(o)))(o), \
|
||||
(u32)(typeof((n)-(n)))(n)); \
|
||||
break; \
|
||||
case 8: \
|
||||
__x = (typeof(__x))(typeof(__x-__x))atomic64_cmpxchg( \
|
||||
(atomic64_t *)(ptr), \
|
||||
(u64)(typeof((o)-(o)))(o), \
|
||||
(u64)(typeof((n)-(n)))(n)); \
|
||||
break; \
|
||||
default: \
|
||||
__cmpxchg_called_with_bad_pointer(); \
|
||||
} \
|
||||
__x; \
|
||||
})
|
||||
|
||||
#define tas(ptr) (xchg((ptr), 1))
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
@ -110,16 +110,6 @@ static inline void atomic_set(atomic_t *v, int n)
|
||||
_atomic_xchg(v, n);
|
||||
}
|
||||
|
||||
#define xchg(ptr, x) ((typeof(*(ptr))) \
|
||||
((sizeof(*(ptr)) == sizeof(atomic_t)) ? \
|
||||
atomic_xchg((atomic_t *)(ptr), (long)(x)) : \
|
||||
__xchg_called_with_bad_pointer()))
|
||||
|
||||
#define cmpxchg(ptr, o, n) ((typeof(*(ptr))) \
|
||||
((sizeof(*(ptr)) == sizeof(atomic_t)) ? \
|
||||
atomic_cmpxchg((atomic_t *)(ptr), (long)(o), (long)(n)) : \
|
||||
__cmpxchg_called_with_bad_pointer()))
|
||||
|
||||
/* A 64bit atomic type */
|
||||
|
||||
typedef struct {
|
||||
|
156
arch/tile/include/asm/atomic_64.h
Normal file
156
arch/tile/include/asm/atomic_64.h
Normal file
@ -0,0 +1,156 @@
|
||||
/*
|
||||
* Copyright 2011 Tilera Corporation. All Rights Reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation, version 2.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
|
||||
* NON INFRINGEMENT. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* Do not include directly; use <asm/atomic.h>.
|
||||
*/
|
||||
|
||||
#ifndef _ASM_TILE_ATOMIC_64_H
|
||||
#define _ASM_TILE_ATOMIC_64_H
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#include <arch/spr_def.h>
|
||||
|
||||
/* First, the 32-bit atomic ops that are "real" on our 64-bit platform. */
|
||||
|
||||
#define atomic_set(v, i) ((v)->counter = (i))
|
||||
|
||||
/*
|
||||
* The smp_mb() operations throughout are to support the fact that
|
||||
* Linux requires memory barriers before and after the operation,
|
||||
* on any routine which updates memory and returns a value.
|
||||
*/
|
||||
|
||||
static inline int atomic_cmpxchg(atomic_t *v, int o, int n)
|
||||
{
|
||||
int val;
|
||||
__insn_mtspr(SPR_CMPEXCH_VALUE, o);
|
||||
smp_mb(); /* barrier for proper semantics */
|
||||
val = __insn_cmpexch4((void *)&v->counter, n);
|
||||
smp_mb(); /* barrier for proper semantics */
|
||||
return val;
|
||||
}
|
||||
|
||||
static inline int atomic_xchg(atomic_t *v, int n)
|
||||
{
|
||||
int val;
|
||||
smp_mb(); /* barrier for proper semantics */
|
||||
val = __insn_exch4((void *)&v->counter, n);
|
||||
smp_mb(); /* barrier for proper semantics */
|
||||
return val;
|
||||
}
|
||||
|
||||
static inline void atomic_add(int i, atomic_t *v)
|
||||
{
|
||||
__insn_fetchadd4((void *)&v->counter, i);
|
||||
}
|
||||
|
||||
static inline int atomic_add_return(int i, atomic_t *v)
|
||||
{
|
||||
int val;
|
||||
smp_mb(); /* barrier for proper semantics */
|
||||
val = __insn_fetchadd4((void *)&v->counter, i) + i;
|
||||
barrier(); /* the "+ i" above will wait on memory */
|
||||
return val;
|
||||
}
|
||||
|
||||
static inline int atomic_add_unless(atomic_t *v, int a, int u)
|
||||
{
|
||||
int guess, oldval = v->counter;
|
||||
do {
|
||||
if (oldval == u)
|
||||
break;
|
||||
guess = oldval;
|
||||
oldval = atomic_cmpxchg(v, guess, guess + a);
|
||||
} while (guess != oldval);
|
||||
return oldval != u;
|
||||
}
|
||||
|
||||
/* Now the true 64-bit operations. */
|
||||
|
||||
#define ATOMIC64_INIT(i) { (i) }
|
||||
|
||||
#define atomic64_read(v) ((v)->counter)
|
||||
#define atomic64_set(v, i) ((v)->counter = (i))
|
||||
|
||||
static inline long atomic64_cmpxchg(atomic64_t *v, long o, long n)
|
||||
{
|
||||
long val;
|
||||
smp_mb(); /* barrier for proper semantics */
|
||||
__insn_mtspr(SPR_CMPEXCH_VALUE, o);
|
||||
val = __insn_cmpexch((void *)&v->counter, n);
|
||||
smp_mb(); /* barrier for proper semantics */
|
||||
return val;
|
||||
}
|
||||
|
||||
static inline long atomic64_xchg(atomic64_t *v, long n)
|
||||
{
|
||||
long val;
|
||||
smp_mb(); /* barrier for proper semantics */
|
||||
val = __insn_exch((void *)&v->counter, n);
|
||||
smp_mb(); /* barrier for proper semantics */
|
||||
return val;
|
||||
}
|
||||
|
||||
static inline void atomic64_add(long i, atomic64_t *v)
|
||||
{
|
||||
__insn_fetchadd((void *)&v->counter, i);
|
||||
}
|
||||
|
||||
static inline long atomic64_add_return(long i, atomic64_t *v)
|
||||
{
|
||||
int val;
|
||||
smp_mb(); /* barrier for proper semantics */
|
||||
val = __insn_fetchadd((void *)&v->counter, i) + i;
|
||||
barrier(); /* the "+ i" above will wait on memory */
|
||||
return val;
|
||||
}
|
||||
|
||||
static inline long atomic64_add_unless(atomic64_t *v, long a, long u)
|
||||
{
|
||||
long guess, oldval = v->counter;
|
||||
do {
|
||||
if (oldval == u)
|
||||
break;
|
||||
guess = oldval;
|
||||
oldval = atomic64_cmpxchg(v, guess, guess + a);
|
||||
} while (guess != oldval);
|
||||
return oldval != u;
|
||||
}
|
||||
|
||||
#define atomic64_sub_return(i, v) atomic64_add_return(-(i), (v))
|
||||
#define atomic64_sub(i, v) atomic64_add(-(i), (v))
|
||||
#define atomic64_inc_return(v) atomic64_add_return(1, (v))
|
||||
#define atomic64_dec_return(v) atomic64_sub_return(1, (v))
|
||||
#define atomic64_inc(v) atomic64_add(1, (v))
|
||||
#define atomic64_dec(v) atomic64_sub(1, (v))
|
||||
|
||||
#define atomic64_inc_and_test(v) (atomic64_inc_return(v) == 0)
|
||||
#define atomic64_dec_and_test(v) (atomic64_dec_return(v) == 0)
|
||||
#define atomic64_sub_and_test(i, v) (atomic64_sub_return((i), (v)) == 0)
|
||||
#define atomic64_add_negative(i, v) (atomic64_add_return((i), (v)) < 0)
|
||||
|
||||
#define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0)
|
||||
|
||||
/* Atomic dec and inc don't implement barrier, so provide them if needed. */
|
||||
#define smp_mb__before_atomic_dec() smp_mb()
|
||||
#define smp_mb__after_atomic_dec() smp_mb()
|
||||
#define smp_mb__before_atomic_inc() smp_mb()
|
||||
#define smp_mb__after_atomic_inc() smp_mb()
|
||||
|
||||
/* Define this to indicate that cmpxchg is an efficient operation. */
|
||||
#define __HAVE_ARCH_CMPXCHG
|
||||
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
|
||||
#endif /* _ASM_TILE_ATOMIC_64_H */
|
@ -12,80 +12,41 @@
|
||||
* more details.
|
||||
*/
|
||||
|
||||
#ifndef _TILE_BACKTRACE_H
|
||||
#define _TILE_BACKTRACE_H
|
||||
|
||||
|
||||
#ifndef _ASM_TILE_BACKTRACE_H
|
||||
#define _ASM_TILE_BACKTRACE_H
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
#include <arch/chip.h>
|
||||
|
||||
#if defined(__tile__)
|
||||
typedef unsigned long VirtualAddress;
|
||||
#elif CHIP_VA_WIDTH() > 32
|
||||
typedef unsigned long long VirtualAddress;
|
||||
#else
|
||||
typedef unsigned int VirtualAddress;
|
||||
#endif
|
||||
|
||||
|
||||
/** Reads 'size' bytes from 'address' and writes the data to 'result'.
|
||||
/* Reads 'size' bytes from 'address' and writes the data to 'result'.
|
||||
* Returns true if successful, else false (e.g. memory not readable).
|
||||
*/
|
||||
typedef bool (*BacktraceMemoryReader)(void *result,
|
||||
VirtualAddress address,
|
||||
unsigned long address,
|
||||
unsigned int size,
|
||||
void *extra);
|
||||
|
||||
typedef struct {
|
||||
/** Current PC. */
|
||||
VirtualAddress pc;
|
||||
/* Current PC. */
|
||||
unsigned long pc;
|
||||
|
||||
/** Current stack pointer value. */
|
||||
VirtualAddress sp;
|
||||
/* Current stack pointer value. */
|
||||
unsigned long sp;
|
||||
|
||||
/** Current frame pointer value (i.e. caller's stack pointer) */
|
||||
VirtualAddress fp;
|
||||
/* Current frame pointer value (i.e. caller's stack pointer) */
|
||||
unsigned long fp;
|
||||
|
||||
/** Internal use only: caller's PC for first frame. */
|
||||
VirtualAddress initial_frame_caller_pc;
|
||||
/* Internal use only: caller's PC for first frame. */
|
||||
unsigned long initial_frame_caller_pc;
|
||||
|
||||
/** Internal use only: callback to read memory. */
|
||||
/* Internal use only: callback to read memory. */
|
||||
BacktraceMemoryReader read_memory_func;
|
||||
|
||||
/** Internal use only: arbitrary argument to read_memory_func. */
|
||||
/* Internal use only: arbitrary argument to read_memory_func. */
|
||||
void *read_memory_func_extra;
|
||||
|
||||
} BacktraceIterator;
|
||||
|
||||
|
||||
/** Initializes a backtracer to start from the given location.
|
||||
*
|
||||
* If the frame pointer cannot be determined it is set to -1.
|
||||
*
|
||||
* @param state The state to be filled in.
|
||||
* @param read_memory_func A callback that reads memory. If NULL, a default
|
||||
* value is provided.
|
||||
* @param read_memory_func_extra An arbitrary argument to read_memory_func.
|
||||
* @param pc The current PC.
|
||||
* @param lr The current value of the 'lr' register.
|
||||
* @param sp The current value of the 'sp' register.
|
||||
* @param r52 The current value of the 'r52' register.
|
||||
*/
|
||||
extern void backtrace_init(BacktraceIterator *state,
|
||||
BacktraceMemoryReader read_memory_func,
|
||||
void *read_memory_func_extra,
|
||||
VirtualAddress pc, VirtualAddress lr,
|
||||
VirtualAddress sp, VirtualAddress r52);
|
||||
|
||||
|
||||
/** Advances the backtracing state to the calling frame, returning
|
||||
* true iff successful.
|
||||
*/
|
||||
extern bool backtrace_next(BacktraceIterator *state);
|
||||
|
||||
|
||||
typedef enum {
|
||||
|
||||
/* We have no idea what the caller's pc is. */
|
||||
@ -138,7 +99,7 @@ enum {
|
||||
};
|
||||
|
||||
|
||||
/** Internal constants used to define 'info' operands. */
|
||||
/* Internal constants used to define 'info' operands. */
|
||||
enum {
|
||||
/* 0 and 1 are reserved, as are all negative numbers. */
|
||||
|
||||
@ -147,13 +108,10 @@ enum {
|
||||
CALLER_SP_IN_R52_BASE = 4,
|
||||
|
||||
CALLER_SP_OFFSET_BASE = 8,
|
||||
|
||||
/* Marks the entry point of certain functions. */
|
||||
ENTRY_POINT_INFO_OP = 16
|
||||
};
|
||||
|
||||
|
||||
/** Current backtracer state describing where it thinks the caller is. */
|
||||
/* Current backtracer state describing where it thinks the caller is. */
|
||||
typedef struct {
|
||||
/*
|
||||
* Public fields
|
||||
@ -192,7 +150,13 @@ typedef struct {
|
||||
|
||||
} CallerLocation;
|
||||
|
||||
extern void backtrace_init(BacktraceIterator *state,
|
||||
BacktraceMemoryReader read_memory_func,
|
||||
void *read_memory_func_extra,
|
||||
unsigned long pc, unsigned long lr,
|
||||
unsigned long sp, unsigned long r52);
|
||||
|
||||
|
||||
extern bool backtrace_next(BacktraceIterator *state);
|
||||
|
||||
#endif /* _TILE_BACKTRACE_H */
|
||||
#endif /* _ASM_TILE_BACKTRACE_H */
|
||||
|
@ -122,6 +122,7 @@ static inline unsigned long __arch_hweight64(__u64 w)
|
||||
#include <asm-generic/bitops/lock.h>
|
||||
#include <asm-generic/bitops/find.h>
|
||||
#include <asm-generic/bitops/sched.h>
|
||||
#include <asm-generic/bitops/non-atomic.h>
|
||||
#include <asm-generic/bitops/le.h>
|
||||
|
||||
#endif /* _ASM_TILE_BITOPS_H */
|
||||
|
@ -126,7 +126,6 @@ static inline int test_and_change_bit(unsigned nr,
|
||||
#define smp_mb__before_clear_bit() smp_mb()
|
||||
#define smp_mb__after_clear_bit() do {} while (0)
|
||||
|
||||
#include <asm-generic/bitops/non-atomic.h>
|
||||
#include <asm-generic/bitops/ext2-atomic.h>
|
||||
|
||||
#endif /* _ASM_TILE_BITOPS_32_H */
|
||||
|
105
arch/tile/include/asm/bitops_64.h
Normal file
105
arch/tile/include/asm/bitops_64.h
Normal file
@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright 2011 Tilera Corporation. All Rights Reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation, version 2.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
|
||||
* NON INFRINGEMENT. See the GNU General Public License for
|
||||
* more details.
|
||||
*/
|
||||
|
||||
#ifndef _ASM_TILE_BITOPS_64_H
|
||||
#define _ASM_TILE_BITOPS_64_H
|
||||
|
||||
#include <linux/compiler.h>
|
||||
#include <asm/atomic.h>
|
||||
#include <asm/system.h>
|
||||
|
||||
/* See <asm/bitops.h> for API comments. */
|
||||
|
||||
static inline void set_bit(unsigned nr, volatile unsigned long *addr)
|
||||
{
|
||||
unsigned long mask = (1UL << (nr % BITS_PER_LONG));
|
||||
__insn_fetchor((void *)(addr + nr / BITS_PER_LONG), mask);
|
||||
}
|
||||
|
||||
static inline void clear_bit(unsigned nr, volatile unsigned long *addr)
|
||||
{
|
||||
unsigned long mask = (1UL << (nr % BITS_PER_LONG));
|
||||
__insn_fetchand((void *)(addr + nr / BITS_PER_LONG), ~mask);
|
||||
}
|
||||
|
||||
#define smp_mb__before_clear_bit() smp_mb()
|
||||
#define smp_mb__after_clear_bit() smp_mb()
|
||||
|
||||
|
||||
static inline void change_bit(unsigned nr, volatile unsigned long *addr)
|
||||
{
|
||||
unsigned long old, mask = (1UL << (nr % BITS_PER_LONG));
|
||||
long guess, oldval;
|
||||
addr += nr / BITS_PER_LONG;
|
||||
old = *addr;
|
||||
do {
|
||||
guess = oldval;
|
||||
oldval = atomic64_cmpxchg((atomic64_t *)addr,
|
||||
guess, guess ^ mask);
|
||||
} while (guess != oldval);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The test_and_xxx_bit() routines require a memory fence before we
|
||||
* start the operation, and after the operation completes. We use
|
||||
* smp_mb() before, and rely on the "!= 0" comparison, plus a compiler
|
||||
* barrier(), to block until the atomic op is complete.
|
||||
*/
|
||||
|
||||
static inline int test_and_set_bit(unsigned nr, volatile unsigned long *addr)
|
||||
{
|
||||
int val;
|
||||
unsigned long mask = (1UL << (nr % BITS_PER_LONG));
|
||||
smp_mb(); /* barrier for proper semantics */
|
||||
val = (__insn_fetchor((void *)(addr + nr / BITS_PER_LONG), mask)
|
||||
& mask) != 0;
|
||||
barrier();
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
static inline int test_and_clear_bit(unsigned nr, volatile unsigned long *addr)
|
||||
{
|
||||
int val;
|
||||
unsigned long mask = (1UL << (nr % BITS_PER_LONG));
|
||||
smp_mb(); /* barrier for proper semantics */
|
||||
val = (__insn_fetchand((void *)(addr + nr / BITS_PER_LONG), ~mask)
|
||||
& mask) != 0;
|
||||
barrier();
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
static inline int test_and_change_bit(unsigned nr,
|
||||
volatile unsigned long *addr)
|
||||
{
|
||||
unsigned long mask = (1UL << (nr % BITS_PER_LONG));
|
||||
long guess, oldval = *addr;
|
||||
addr += nr / BITS_PER_LONG;
|
||||
oldval = *addr;
|
||||
do {
|
||||
guess = oldval;
|
||||
oldval = atomic64_cmpxchg((atomic64_t *)addr,
|
||||
guess, guess ^ mask);
|
||||
} while (guess != oldval);
|
||||
return (oldval & mask) != 0;
|
||||
}
|
||||
|
||||
#define ext2_set_bit_atomic(lock, nr, addr) \
|
||||
test_and_set_bit((nr), (unsigned long *)(addr))
|
||||
#define ext2_clear_bit_atomic(lock, nr, addr) \
|
||||
test_and_clear_bit((nr), (unsigned long *)(addr))
|
||||
|
||||
#endif /* _ASM_TILE_BITOPS_64_H */
|
@ -116,22 +116,28 @@ static inline void __finv_buffer(void *buffer, size_t size)
|
||||
}
|
||||
|
||||
|
||||
/* Invalidate a VA range, then memory fence. */
|
||||
/* Invalidate a VA range and wait for it to be complete. */
|
||||
static inline void inv_buffer(void *buffer, size_t size)
|
||||
{
|
||||
__inv_buffer(buffer, size);
|
||||
mb_incoherent();
|
||||
mb();
|
||||
}
|
||||
|
||||
/* Flush a VA range, then memory fence. */
|
||||
static inline void flush_buffer(void *buffer, size_t size)
|
||||
/*
|
||||
* Flush a locally-homecached VA range and wait for the evicted
|
||||
* cachelines to hit memory.
|
||||
*/
|
||||
static inline void flush_buffer_local(void *buffer, size_t size)
|
||||
{
|
||||
__flush_buffer(buffer, size);
|
||||
mb_incoherent();
|
||||
}
|
||||
|
||||
/* Flush & invalidate a VA range, then memory fence. */
|
||||
static inline void finv_buffer(void *buffer, size_t size)
|
||||
/*
|
||||
* Flush and invalidate a locally-homecached VA range and wait for the
|
||||
* evicted cachelines to hit memory.
|
||||
*/
|
||||
static inline void finv_buffer_local(void *buffer, size_t size)
|
||||
{
|
||||
__finv_buffer(buffer, size);
|
||||
mb_incoherent();
|
||||
|
@ -215,8 +215,8 @@ struct compat_sigaction;
|
||||
struct compat_siginfo;
|
||||
struct compat_sigaltstack;
|
||||
long compat_sys_execve(const char __user *path,
|
||||
const compat_uptr_t __user *argv,
|
||||
const compat_uptr_t __user *envp, struct pt_regs *);
|
||||
compat_uptr_t __user *argv,
|
||||
compat_uptr_t __user *envp, struct pt_regs *);
|
||||
long compat_sys_rt_sigaction(int sig, struct compat_sigaction __user *act,
|
||||
struct compat_sigaction __user *oact,
|
||||
size_t sigsetsize);
|
||||
|
@ -65,7 +65,8 @@ extern void dma_sync_single_range_for_cpu(struct device *, dma_addr_t,
|
||||
extern void dma_sync_single_range_for_device(struct device *, dma_addr_t,
|
||||
unsigned long offset, size_t,
|
||||
enum dma_data_direction);
|
||||
extern void dma_cache_sync(void *vaddr, size_t, enum dma_data_direction);
|
||||
extern void dma_cache_sync(struct device *dev, void *vaddr, size_t,
|
||||
enum dma_data_direction);
|
||||
|
||||
static inline int
|
||||
dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
|
||||
|
1
arch/tile/include/asm/fb.h
Normal file
1
arch/tile/include/asm/fb.h
Normal file
@ -0,0 +1 @@
|
||||
#include <asm-generic/fb.h>
|
@ -52,6 +52,7 @@ extern void iounmap(volatile void __iomem *addr);
|
||||
#endif
|
||||
|
||||
#define ioremap_nocache(physaddr, size) ioremap(physaddr, size)
|
||||
#define ioremap_wc(physaddr, size) ioremap(physaddr, size)
|
||||
#define ioremap_writethrough(physaddr, size) ioremap(physaddr, size)
|
||||
#define ioremap_fullcache(physaddr, size) ioremap(physaddr, size)
|
||||
|
||||
@ -161,6 +162,15 @@ static inline void _tile_writeq(u64 val, unsigned long addr)
|
||||
#define iowrite32 writel
|
||||
#define iowrite64 writeq
|
||||
|
||||
static inline void memset_io(void *dst, int val, size_t len)
|
||||
{
|
||||
int x;
|
||||
BUG_ON((unsigned long)dst & 0x3);
|
||||
val = (val & 0xff) * 0x01010101;
|
||||
for (x = 0; x < len; x += 4)
|
||||
writel(val, dst + x);
|
||||
}
|
||||
|
||||
static inline void memcpy_fromio(void *dst, const volatile void __iomem *src,
|
||||
size_t len)
|
||||
{
|
||||
@ -269,6 +279,11 @@ static inline void outsl(unsigned long addr, const void *buffer, int count)
|
||||
ioport_panic();
|
||||
}
|
||||
|
||||
#define ioread16be(addr) be16_to_cpu(ioread16(addr))
|
||||
#define ioread32be(addr) be32_to_cpu(ioread32(addr))
|
||||
#define iowrite16be(v, addr) iowrite16(be16_to_cpu(v), (addr))
|
||||
#define iowrite32be(v, addr) iowrite32(be32_to_cpu(v), (addr))
|
||||
|
||||
#define ioread8_rep(p, dst, count) \
|
||||
insb((unsigned long) (p), (dst), (count))
|
||||
#define ioread16_rep(p, dst, count) \
|
||||
@ -283,4 +298,7 @@ static inline void outsl(unsigned long addr, const void *buffer, int count)
|
||||
#define iowrite32_rep(p, src, count) \
|
||||
outsl((unsigned long) (p), (src), (count))
|
||||
|
||||
#define virt_to_bus virt_to_phys
|
||||
#define bus_to_virt phys_to_virt
|
||||
|
||||
#endif /* _ASM_TILE_IO_H */
|
||||
|
@ -23,6 +23,8 @@
|
||||
/* IRQ numbers used for linux IPIs. */
|
||||
#define IRQ_RESCHEDULE 1
|
||||
|
||||
#define irq_canonicalize(irq) (irq)
|
||||
|
||||
void ack_bad_irq(unsigned int irq);
|
||||
|
||||
/*
|
||||
|
@ -100,8 +100,8 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
|
||||
__get_cpu_var(current_asid) = asid;
|
||||
|
||||
/* Clear cpu from the old mm, and set it in the new one. */
|
||||
cpumask_clear_cpu(cpu, &prev->cpu_vm_mask);
|
||||
cpumask_set_cpu(cpu, &next->cpu_vm_mask);
|
||||
cpumask_clear_cpu(cpu, mm_cpumask(prev));
|
||||
cpumask_set_cpu(cpu, mm_cpumask(next));
|
||||
|
||||
/* Re-load page tables */
|
||||
install_page_table(next->pgd, asid);
|
||||
|
@ -1502,5 +1502,12 @@ extern int parse_insn_tile(tile_bundle_bits bits,
|
||||
decoded[TILE_MAX_INSTRUCTIONS_PER_BUNDLE]);
|
||||
|
||||
|
||||
/* Given a set of bundle bits and a specific pipe, returns which
|
||||
* instruction the bundle contains in that pipe.
|
||||
*/
|
||||
extern const struct tile_opcode *
|
||||
find_opcode(tile_bundle_bits bits, tile_pipeline pipe);
|
||||
|
||||
|
||||
|
||||
#endif /* opcode_tile_h */
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -16,7 +16,8 @@
|
||||
#define _ASM_TILE_PAGE_H
|
||||
|
||||
#include <linux/const.h>
|
||||
#include <hv/pagesize.h>
|
||||
#include <hv/hypervisor.h>
|
||||
#include <arch/chip.h>
|
||||
|
||||
/* PAGE_SHIFT and HPAGE_SHIFT determine the page sizes. */
|
||||
#define PAGE_SHIFT HV_LOG2_PAGE_SIZE_SMALL
|
||||
@ -28,8 +29,6 @@
|
||||
#define PAGE_MASK (~(PAGE_SIZE - 1))
|
||||
#define HPAGE_MASK (~(HPAGE_SIZE - 1))
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
/*
|
||||
* If the Kconfig doesn't specify, set a maximum zone order that
|
||||
* is enough so that we can create huge pages from small pages given
|
||||
@ -39,9 +38,6 @@
|
||||
#define CONFIG_FORCE_MAX_ZONEORDER (HPAGE_SHIFT - PAGE_SHIFT + 1)
|
||||
#endif
|
||||
|
||||
#include <hv/hypervisor.h>
|
||||
#include <arch/chip.h>
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#include <linux/types.h>
|
||||
@ -91,6 +87,10 @@ typedef struct page *pgtable_t;
|
||||
/* Must be a macro since it is used to create constants. */
|
||||
#define __pgprot(val) hv_pte(val)
|
||||
|
||||
/* Rarely-used initializers, typically with a "zero" value. */
|
||||
#define __pte(x) hv_pte(x)
|
||||
#define __pgd(x) hv_pte(x)
|
||||
|
||||
static inline u64 pgprot_val(pgprot_t pgprot)
|
||||
{
|
||||
return hv_pte_val(pgprot);
|
||||
@ -110,6 +110,8 @@ static inline u64 pgd_val(pgd_t pgd)
|
||||
|
||||
typedef HV_PTE pmd_t;
|
||||
|
||||
#define __pmd(x) hv_pte(x)
|
||||
|
||||
static inline u64 pmd_val(pmd_t pmd)
|
||||
{
|
||||
return hv_pte_val(pmd);
|
||||
@ -318,7 +320,7 @@ static inline int pfn_valid(unsigned long pfn)
|
||||
|
||||
/* Provide as macros since these require some other headers included. */
|
||||
#define page_to_pa(page) ((phys_addr_t)(page_to_pfn(page)) << PAGE_SHIFT)
|
||||
#define virt_to_page(kaddr) pfn_to_page(kaddr_to_pfn(kaddr))
|
||||
#define virt_to_page(kaddr) pfn_to_page(kaddr_to_pfn((void *)(kaddr)))
|
||||
#define page_to_virt(page) pfn_to_kaddr(page_to_pfn(page))
|
||||
|
||||
struct mm_struct;
|
||||
@ -331,6 +333,4 @@ extern pte_t *virt_to_pte(struct mm_struct *mm, unsigned long addr);
|
||||
|
||||
#include <asm-generic/memory_model.h>
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#endif /* _ASM_TILE_PAGE_H */
|
||||
|
1
arch/tile/include/asm/parport.h
Normal file
1
arch/tile/include/asm/parport.h
Normal file
@ -0,0 +1 @@
|
||||
#include <asm-generic/parport.h>
|
@ -46,7 +46,8 @@ struct pci_controller {
|
||||
*/
|
||||
#define PCI_DMA_BUS_IS_PHYS 1
|
||||
|
||||
int __init tile_pci_init(void);
|
||||
int __devinit tile_pci_init(void);
|
||||
int __devinit pcibios_init(void);
|
||||
|
||||
void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max);
|
||||
static inline void pci_iounmap(struct pci_dev *dev, void __iomem *addr) {}
|
||||
|
175
arch/tile/include/asm/pgtable_64.h
Normal file
175
arch/tile/include/asm/pgtable_64.h
Normal file
@ -0,0 +1,175 @@
|
||||
/*
|
||||
* Copyright 2011 Tilera Corporation. All Rights Reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation, version 2.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
|
||||
* NON INFRINGEMENT. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _ASM_TILE_PGTABLE_64_H
|
||||
#define _ASM_TILE_PGTABLE_64_H
|
||||
|
||||
/* The level-0 page table breaks the address space into 32-bit chunks. */
|
||||
#define PGDIR_SHIFT HV_LOG2_L1_SPAN
|
||||
#define PGDIR_SIZE HV_L1_SPAN
|
||||
#define PGDIR_MASK (~(PGDIR_SIZE-1))
|
||||
#define PTRS_PER_PGD HV_L0_ENTRIES
|
||||
#define SIZEOF_PGD (PTRS_PER_PGD * sizeof(pgd_t))
|
||||
|
||||
/*
|
||||
* The level-1 index is defined by the huge page size. A PMD is composed
|
||||
* of PTRS_PER_PMD pgd_t's and is the middle level of the page table.
|
||||
*/
|
||||
#define PMD_SHIFT HV_LOG2_PAGE_SIZE_LARGE
|
||||
#define PMD_SIZE HV_PAGE_SIZE_LARGE
|
||||
#define PMD_MASK (~(PMD_SIZE-1))
|
||||
#define PTRS_PER_PMD (1 << (PGDIR_SHIFT - PMD_SHIFT))
|
||||
#define SIZEOF_PMD (PTRS_PER_PMD * sizeof(pmd_t))
|
||||
|
||||
/*
|
||||
* The level-2 index is defined by the difference between the huge
|
||||
* page size and the normal page size. A PTE is composed of
|
||||
* PTRS_PER_PTE pte_t's and is the bottom level of the page table.
|
||||
* Note that the hypervisor docs use PTE for what we call pte_t, so
|
||||
* this nomenclature is somewhat confusing.
|
||||
*/
|
||||
#define PTRS_PER_PTE (1 << (HV_LOG2_PAGE_SIZE_LARGE - HV_LOG2_PAGE_SIZE_SMALL))
|
||||
#define SIZEOF_PTE (PTRS_PER_PTE * sizeof(pte_t))
|
||||
|
||||
/*
|
||||
* Align the vmalloc area to an L2 page table, and leave a guard page
|
||||
* at the beginning and end. The vmalloc code also puts in an internal
|
||||
* guard page between each allocation.
|
||||
*/
|
||||
#define _VMALLOC_END HUGE_VMAP_BASE
|
||||
#define VMALLOC_END (_VMALLOC_END - PAGE_SIZE)
|
||||
#define VMALLOC_START (_VMALLOC_START + PAGE_SIZE)
|
||||
|
||||
#define HUGE_VMAP_END (HUGE_VMAP_BASE + PGDIR_SIZE)
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
/* We have no pud since we are a three-level page table. */
|
||||
#include <asm-generic/pgtable-nopud.h>
|
||||
|
||||
static inline int pud_none(pud_t pud)
|
||||
{
|
||||
return pud_val(pud) == 0;
|
||||
}
|
||||
|
||||
static inline int pud_present(pud_t pud)
|
||||
{
|
||||
return pud_val(pud) & _PAGE_PRESENT;
|
||||
}
|
||||
|
||||
#define pmd_ERROR(e) \
|
||||
pr_err("%s:%d: bad pmd 0x%016llx.\n", __FILE__, __LINE__, pmd_val(e))
|
||||
|
||||
static inline void pud_clear(pud_t *pudp)
|
||||
{
|
||||
__pte_clear(&pudp->pgd);
|
||||
}
|
||||
|
||||
static inline int pud_bad(pud_t pud)
|
||||
{
|
||||
return ((pud_val(pud) & _PAGE_ALL) != _PAGE_TABLE);
|
||||
}
|
||||
|
||||
/* Return the page-table frame number (ptfn) that a pud_t points at. */
|
||||
#define pud_ptfn(pud) hv_pte_get_ptfn((pud).pgd)
|
||||
|
||||
/*
|
||||
* A given kernel pud_t maps to a kernel pmd_t table at a specific
|
||||
* virtual address. Since kernel pmd_t tables can be aligned at
|
||||
* sub-page granularity, this macro can return non-page-aligned
|
||||
* pointers, despite its name.
|
||||
*/
|
||||
#define pud_page_vaddr(pud) \
|
||||
(__va((phys_addr_t)pud_ptfn(pud) << HV_LOG2_PAGE_TABLE_ALIGN))
|
||||
|
||||
/*
|
||||
* A pud_t points to a pmd_t array. Since we can have multiple per
|
||||
* page, we don't have a one-to-one mapping of pud_t's to pages.
|
||||
*/
|
||||
#define pud_page(pud) pfn_to_page(HV_PTFN_TO_PFN(pud_ptfn(pud)))
|
||||
|
||||
static inline unsigned long pud_index(unsigned long address)
|
||||
{
|
||||
return (address >> PUD_SHIFT) & (PTRS_PER_PUD - 1);
|
||||
}
|
||||
|
||||
#define pmd_offset(pud, address) \
|
||||
((pmd_t *)pud_page_vaddr(*(pud)) + pmd_index(address))
|
||||
|
||||
static inline void __set_pmd(pmd_t *pmdp, pmd_t pmdval)
|
||||
{
|
||||
set_pte(pmdp, pmdval);
|
||||
}
|
||||
|
||||
/* Create a pmd from a PTFN and pgprot. */
|
||||
static inline pmd_t ptfn_pmd(unsigned long ptfn, pgprot_t prot)
|
||||
{
|
||||
return hv_pte_set_ptfn(prot, ptfn);
|
||||
}
|
||||
|
||||
/* Return the page-table frame number (ptfn) that a pmd_t points at. */
|
||||
static inline unsigned long pmd_ptfn(pmd_t pmd)
|
||||
{
|
||||
return hv_pte_get_ptfn(pmd);
|
||||
}
|
||||
|
||||
static inline void pmd_clear(pmd_t *pmdp)
|
||||
{
|
||||
__pte_clear(pmdp);
|
||||
}
|
||||
|
||||
/* Normalize an address to having the correct high bits set. */
|
||||
#define pgd_addr_normalize pgd_addr_normalize
|
||||
static inline unsigned long pgd_addr_normalize(unsigned long addr)
|
||||
{
|
||||
return ((long)addr << (CHIP_WORD_SIZE() - CHIP_VA_WIDTH())) >>
|
||||
(CHIP_WORD_SIZE() - CHIP_VA_WIDTH());
|
||||
}
|
||||
|
||||
/* We don't define any pgds for these addresses. */
|
||||
static inline int pgd_addr_invalid(unsigned long addr)
|
||||
{
|
||||
return addr >= MEM_HV_START ||
|
||||
(addr > MEM_LOW_END && addr < MEM_HIGH_START);
|
||||
}
|
||||
|
||||
/*
|
||||
* Use atomic instructions to provide atomicity against the hypervisor.
|
||||
*/
|
||||
#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
|
||||
static inline int ptep_test_and_clear_young(struct vm_area_struct *vma,
|
||||
unsigned long addr, pte_t *ptep)
|
||||
{
|
||||
return (__insn_fetchand(&ptep->val, ~HV_PTE_ACCESSED) >>
|
||||
HV_PTE_INDEX_ACCESSED) & 0x1;
|
||||
}
|
||||
|
||||
#define __HAVE_ARCH_PTEP_SET_WRPROTECT
|
||||
static inline void ptep_set_wrprotect(struct mm_struct *mm,
|
||||
unsigned long addr, pte_t *ptep)
|
||||
{
|
||||
__insn_fetchand(&ptep->val, ~HV_PTE_WRITABLE);
|
||||
}
|
||||
|
||||
#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
|
||||
static inline pte_t ptep_get_and_clear(struct mm_struct *mm,
|
||||
unsigned long addr, pte_t *ptep)
|
||||
{
|
||||
return hv_pte(__insn_exch(&ptep->val, 0UL));
|
||||
}
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#endif /* _ASM_TILE_PGTABLE_64_H */
|
@ -215,6 +215,8 @@ static inline void release_thread(struct task_struct *dead_task)
|
||||
|
||||
extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
|
||||
|
||||
extern int do_work_pending(struct pt_regs *regs, u32 flags);
|
||||
|
||||
|
||||
/*
|
||||
* Return saved (kernel) PC of a blocked thread.
|
||||
@ -255,10 +257,6 @@ static inline void cpu_relax(void)
|
||||
barrier();
|
||||
}
|
||||
|
||||
struct siginfo;
|
||||
extern void arch_coredump_signal(struct siginfo *, struct pt_regs *);
|
||||
#define arch_coredump_signal arch_coredump_signal
|
||||
|
||||
/* Info on this processor (see fs/proc/cpuinfo.c) */
|
||||
struct seq_operations;
|
||||
extern const struct seq_operations cpuinfo_op;
|
||||
@ -269,9 +267,6 @@ extern char chip_model[64];
|
||||
/* Data on which physical memory controller corresponds to which NUMA node. */
|
||||
extern int node_controller[];
|
||||
|
||||
/* Do we dump information to the console when a user application crashes? */
|
||||
extern int show_crashinfo;
|
||||
|
||||
#if CHIP_HAS_CBOX_HOME_MAP()
|
||||
/* Does the heap allocator return hash-for-home pages by default? */
|
||||
extern int hash_default;
|
||||
|
1
arch/tile/include/asm/serial.h
Normal file
1
arch/tile/include/asm/serial.h
Normal file
@ -0,0 +1 @@
|
||||
#include <asm-generic/serial.h>
|
@ -28,6 +28,10 @@ struct pt_regs;
|
||||
int restore_sigcontext(struct pt_regs *, struct sigcontext __user *);
|
||||
int setup_sigcontext(struct sigcontext __user *, struct pt_regs *);
|
||||
void do_signal(struct pt_regs *regs);
|
||||
void signal_fault(const char *type, struct pt_regs *,
|
||||
void __user *frame, int sig);
|
||||
void trace_unhandled_signal(const char *type, struct pt_regs *regs,
|
||||
unsigned long address, int signo);
|
||||
#endif
|
||||
|
||||
#endif /* _ASM_TILE_SIGNAL_H */
|
||||
|
161
arch/tile/include/asm/spinlock_64.h
Normal file
161
arch/tile/include/asm/spinlock_64.h
Normal file
@ -0,0 +1,161 @@
|
||||
/*
|
||||
* Copyright 2011 Tilera Corporation. All Rights Reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation, version 2.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
|
||||
* NON INFRINGEMENT. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* 64-bit SMP ticket spinlocks, allowing only a single CPU anywhere
|
||||
* (the type definitions are in asm/spinlock_types.h)
|
||||
*/
|
||||
|
||||
#ifndef _ASM_TILE_SPINLOCK_64_H
|
||||
#define _ASM_TILE_SPINLOCK_64_H
|
||||
|
||||
/* Shifts and masks for the various fields in "lock". */
|
||||
#define __ARCH_SPIN_CURRENT_SHIFT 17
|
||||
#define __ARCH_SPIN_NEXT_MASK 0x7fff
|
||||
#define __ARCH_SPIN_NEXT_OVERFLOW 0x8000
|
||||
|
||||
/*
|
||||
* Return the "current" portion of a ticket lock value,
|
||||
* i.e. the number that currently owns the lock.
|
||||
*/
|
||||
static inline int arch_spin_current(u32 val)
|
||||
{
|
||||
return val >> __ARCH_SPIN_CURRENT_SHIFT;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the "next" portion of a ticket lock value,
|
||||
* i.e. the number that the next task to try to acquire the lock will get.
|
||||
*/
|
||||
static inline int arch_spin_next(u32 val)
|
||||
{
|
||||
return val & __ARCH_SPIN_NEXT_MASK;
|
||||
}
|
||||
|
||||
/* The lock is locked if a task would have to wait to get it. */
|
||||
static inline int arch_spin_is_locked(arch_spinlock_t *lock)
|
||||
{
|
||||
u32 val = lock->lock;
|
||||
return arch_spin_current(val) != arch_spin_next(val);
|
||||
}
|
||||
|
||||
/* Bump the current ticket so the next task owns the lock. */
|
||||
static inline void arch_spin_unlock(arch_spinlock_t *lock)
|
||||
{
|
||||
wmb(); /* guarantee anything modified under the lock is visible */
|
||||
__insn_fetchadd4(&lock->lock, 1U << __ARCH_SPIN_CURRENT_SHIFT);
|
||||
}
|
||||
|
||||
void arch_spin_unlock_wait(arch_spinlock_t *lock);
|
||||
|
||||
void arch_spin_lock_slow(arch_spinlock_t *lock, u32 val);
|
||||
|
||||
/* Grab the "next" ticket number and bump it atomically.
|
||||
* If the current ticket is not ours, go to the slow path.
|
||||
* We also take the slow path if the "next" value overflows.
|
||||
*/
|
||||
static inline void arch_spin_lock(arch_spinlock_t *lock)
|
||||
{
|
||||
u32 val = __insn_fetchadd4(&lock->lock, 1);
|
||||
u32 ticket = val & (__ARCH_SPIN_NEXT_MASK | __ARCH_SPIN_NEXT_OVERFLOW);
|
||||
if (unlikely(arch_spin_current(val) != ticket))
|
||||
arch_spin_lock_slow(lock, ticket);
|
||||
}
|
||||
|
||||
/* Try to get the lock, and return whether we succeeded. */
|
||||
int arch_spin_trylock(arch_spinlock_t *lock);
|
||||
|
||||
/* We cannot take an interrupt after getting a ticket, so don't enable them. */
|
||||
#define arch_spin_lock_flags(lock, flags) arch_spin_lock(lock)
|
||||
|
||||
/*
|
||||
* Read-write spinlocks, allowing multiple readers
|
||||
* but only one writer.
|
||||
*
|
||||
* We use fetchadd() for readers, and fetchor() with the sign bit
|
||||
* for writers.
|
||||
*/
|
||||
|
||||
#define __WRITE_LOCK_BIT (1 << 31)
|
||||
|
||||
static inline int arch_write_val_locked(int val)
|
||||
{
|
||||
return val < 0; /* Optimize "val & __WRITE_LOCK_BIT". */
|
||||
}
|
||||
|
||||
/**
|
||||
* read_can_lock - would read_trylock() succeed?
|
||||
* @lock: the rwlock in question.
|
||||
*/
|
||||
static inline int arch_read_can_lock(arch_rwlock_t *rw)
|
||||
{
|
||||
return !arch_write_val_locked(rw->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* write_can_lock - would write_trylock() succeed?
|
||||
* @lock: the rwlock in question.
|
||||
*/
|
||||
static inline int arch_write_can_lock(arch_rwlock_t *rw)
|
||||
{
|
||||
return rw->lock == 0;
|
||||
}
|
||||
|
||||
extern void __read_lock_failed(arch_rwlock_t *rw);
|
||||
|
||||
static inline void arch_read_lock(arch_rwlock_t *rw)
|
||||
{
|
||||
u32 val = __insn_fetchaddgez4(&rw->lock, 1);
|
||||
if (unlikely(arch_write_val_locked(val)))
|
||||
__read_lock_failed(rw);
|
||||
}
|
||||
|
||||
extern void __write_lock_failed(arch_rwlock_t *rw, u32 val);
|
||||
|
||||
static inline void arch_write_lock(arch_rwlock_t *rw)
|
||||
{
|
||||
u32 val = __insn_fetchor4(&rw->lock, __WRITE_LOCK_BIT);
|
||||
if (unlikely(val != 0))
|
||||
__write_lock_failed(rw, val);
|
||||
}
|
||||
|
||||
static inline void arch_read_unlock(arch_rwlock_t *rw)
|
||||
{
|
||||
__insn_mf();
|
||||
__insn_fetchadd4(&rw->lock, -1);
|
||||
}
|
||||
|
||||
static inline void arch_write_unlock(arch_rwlock_t *rw)
|
||||
{
|
||||
__insn_mf();
|
||||
rw->lock = 0;
|
||||
}
|
||||
|
||||
static inline int arch_read_trylock(arch_rwlock_t *rw)
|
||||
{
|
||||
return !arch_write_val_locked(__insn_fetchaddgez4(&rw->lock, 1));
|
||||
}
|
||||
|
||||
static inline int arch_write_trylock(arch_rwlock_t *rw)
|
||||
{
|
||||
u32 val = __insn_fetchor4(&rw->lock, __WRITE_LOCK_BIT);
|
||||
if (likely(val == 0))
|
||||
return 1;
|
||||
if (!arch_write_val_locked(val))
|
||||
__insn_fetchand4(&rw->lock, ~__WRITE_LOCK_BIT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define arch_read_lock_flags(lock, flags) arch_read_lock(lock)
|
||||
#define arch_write_lock_flags(lock, flags) arch_write_lock(lock)
|
||||
|
||||
#endif /* _ASM_TILE_SPINLOCK_64_H */
|
@ -1,4 +1,4 @@
|
||||
#ifdef CONFIG_COMPAT
|
||||
#if defined(__KERNEL__) && defined(CONFIG_COMPAT)
|
||||
#define __ARCH_WANT_STAT64 /* Used for compat_sys_stat64() etc. */
|
||||
#endif
|
||||
#include <asm-generic/stat.h>
|
||||
|
@ -18,12 +18,6 @@
|
||||
/* Tile gcc is always >= 4.3.0, so we use __builtin_bswap. */
|
||||
#define __arch_swab32(x) __builtin_bswap32(x)
|
||||
#define __arch_swab64(x) __builtin_bswap64(x)
|
||||
|
||||
/* Use the variant that is natural for the wordsize. */
|
||||
#ifdef CONFIG_64BIT
|
||||
#define __arch_swab16(x) (__builtin_bswap64(x) >> 48)
|
||||
#else
|
||||
#define __arch_swab16(x) (__builtin_bswap32(x) >> 16)
|
||||
#endif
|
||||
|
||||
#endif /* _ASM_TILE_SWAB_H */
|
||||
|
@ -125,6 +125,7 @@ extern void cpu_idle_on_new_stack(struct thread_info *old_ti,
|
||||
#define TIF_SYSCALL_AUDIT 5 /* syscall auditing active */
|
||||
#define TIF_SECCOMP 6 /* secure computing */
|
||||
#define TIF_MEMDIE 7 /* OOM killer at work */
|
||||
#define TIF_NOTIFY_RESUME 8 /* callback before returning to user */
|
||||
|
||||
#define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
|
||||
#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
|
||||
@ -134,10 +135,12 @@ extern void cpu_idle_on_new_stack(struct thread_info *old_ti,
|
||||
#define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT)
|
||||
#define _TIF_SECCOMP (1<<TIF_SECCOMP)
|
||||
#define _TIF_MEMDIE (1<<TIF_MEMDIE)
|
||||
#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
|
||||
|
||||
/* Work to do on any return to user space. */
|
||||
#define _TIF_ALLWORK_MASK \
|
||||
(_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_SINGLESTEP|_TIF_ASYNC_TLB)
|
||||
(_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_SINGLESTEP|\
|
||||
_TIF_ASYNC_TLB|_TIF_NOTIFY_RESUME)
|
||||
|
||||
/*
|
||||
* Thread-synchronous status.
|
||||
|
@ -44,25 +44,64 @@ static inline const struct cpumask *cpumask_of_node(int node)
|
||||
/* For now, use numa node -1 for global allocation. */
|
||||
#define pcibus_to_node(bus) ((void)(bus), -1)
|
||||
|
||||
/*
|
||||
* TILE architecture has many cores integrated in one processor, so we need
|
||||
* setup bigger balance_interval for both CPU/NODE scheduling domains to
|
||||
* reduce process scheduling costs.
|
||||
*/
|
||||
|
||||
/* sched_domains SD_CPU_INIT for TILE architecture */
|
||||
#define SD_CPU_INIT (struct sched_domain) { \
|
||||
.min_interval = 4, \
|
||||
.max_interval = 128, \
|
||||
.busy_factor = 64, \
|
||||
.imbalance_pct = 125, \
|
||||
.cache_nice_tries = 1, \
|
||||
.busy_idx = 2, \
|
||||
.idle_idx = 1, \
|
||||
.newidle_idx = 0, \
|
||||
.wake_idx = 0, \
|
||||
.forkexec_idx = 0, \
|
||||
\
|
||||
.flags = 1*SD_LOAD_BALANCE \
|
||||
| 1*SD_BALANCE_NEWIDLE \
|
||||
| 1*SD_BALANCE_EXEC \
|
||||
| 1*SD_BALANCE_FORK \
|
||||
| 0*SD_BALANCE_WAKE \
|
||||
| 0*SD_WAKE_AFFINE \
|
||||
| 0*SD_PREFER_LOCAL \
|
||||
| 0*SD_SHARE_CPUPOWER \
|
||||
| 0*SD_SHARE_PKG_RESOURCES \
|
||||
| 0*SD_SERIALIZE \
|
||||
, \
|
||||
.last_balance = jiffies, \
|
||||
.balance_interval = 32, \
|
||||
}
|
||||
|
||||
/* sched_domains SD_NODE_INIT for TILE architecture */
|
||||
#define SD_NODE_INIT (struct sched_domain) { \
|
||||
.min_interval = 8, \
|
||||
.max_interval = 32, \
|
||||
.busy_factor = 32, \
|
||||
.imbalance_pct = 125, \
|
||||
.cache_nice_tries = 1, \
|
||||
.busy_idx = 3, \
|
||||
.idle_idx = 1, \
|
||||
.newidle_idx = 2, \
|
||||
.wake_idx = 1, \
|
||||
.flags = SD_LOAD_BALANCE \
|
||||
| SD_BALANCE_NEWIDLE \
|
||||
| SD_BALANCE_EXEC \
|
||||
| SD_BALANCE_FORK \
|
||||
| SD_WAKE_AFFINE \
|
||||
| SD_SERIALIZE, \
|
||||
.last_balance = jiffies, \
|
||||
.balance_interval = 1, \
|
||||
#define SD_NODE_INIT (struct sched_domain) { \
|
||||
.min_interval = 16, \
|
||||
.max_interval = 512, \
|
||||
.busy_factor = 32, \
|
||||
.imbalance_pct = 125, \
|
||||
.cache_nice_tries = 1, \
|
||||
.busy_idx = 3, \
|
||||
.idle_idx = 1, \
|
||||
.newidle_idx = 2, \
|
||||
.wake_idx = 1, \
|
||||
.flags = 1*SD_LOAD_BALANCE \
|
||||
| 1*SD_BALANCE_NEWIDLE \
|
||||
| 1*SD_BALANCE_EXEC \
|
||||
| 1*SD_BALANCE_FORK \
|
||||
| 0*SD_BALANCE_WAKE \
|
||||
| 0*SD_WAKE_AFFINE \
|
||||
| 0*SD_PREFER_LOCAL \
|
||||
| 0*SD_SHARE_CPUPOWER \
|
||||
| 0*SD_SHARE_PKG_RESOURCES \
|
||||
| 1*SD_SERIALIZE \
|
||||
, \
|
||||
.last_balance = jiffies, \
|
||||
.balance_interval = 128, \
|
||||
}
|
||||
|
||||
/* By definition, we create nodes based on online memory. */
|
||||
|
@ -15,10 +15,14 @@
|
||||
#ifndef _ASM_TILE_TRAPS_H
|
||||
#define _ASM_TILE_TRAPS_H
|
||||
|
||||
#include <arch/chip.h>
|
||||
|
||||
/* mm/fault.c */
|
||||
void do_page_fault(struct pt_regs *, int fault_num,
|
||||
unsigned long address, unsigned long write);
|
||||
#if CHIP_HAS_TILE_DMA() || CHIP_HAS_SN_PROC()
|
||||
void do_async_page_fault(struct pt_regs *);
|
||||
#endif
|
||||
|
||||
#ifndef __tilegx__
|
||||
/*
|
||||
|
@ -15,7 +15,7 @@
|
||||
#if !defined(_ASM_TILE_UNISTD_H) || defined(__SYSCALL)
|
||||
#define _ASM_TILE_UNISTD_H
|
||||
|
||||
#ifndef __LP64__
|
||||
#if !defined(__LP64__) || defined(__SYSCALL_COMPAT)
|
||||
/* Use the flavor of this syscall that matches the 32-bit API better. */
|
||||
#define __ARCH_WANT_SYNC_FILE_RANGE2
|
||||
#endif
|
||||
|
@ -10,23 +10,30 @@
|
||||
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
|
||||
* NON INFRINGEMENT. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* Access to VGA videoram.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file pagesize.h
|
||||
*/
|
||||
#ifndef _ASM_TILE_VGA_H
|
||||
#define _ASM_TILE_VGA_H
|
||||
|
||||
#ifndef _HV_PAGESIZE_H
|
||||
#define _HV_PAGESIZE_H
|
||||
#include <asm/io.h>
|
||||
|
||||
/** The log2 of the size of small pages, in bytes. This value should
|
||||
* be verified at runtime by calling hv_sysconf(HV_SYSCONF_PAGE_SIZE_SMALL).
|
||||
*/
|
||||
#define HV_LOG2_PAGE_SIZE_SMALL 16
|
||||
#define VT_BUF_HAVE_RW
|
||||
|
||||
/** The log2 of the size of large pages, in bytes. This value should be
|
||||
* verified at runtime by calling hv_sysconf(HV_SYSCONF_PAGE_SIZE_LARGE).
|
||||
*/
|
||||
#define HV_LOG2_PAGE_SIZE_LARGE 24
|
||||
static inline void scr_writew(u16 val, volatile u16 *addr)
|
||||
{
|
||||
__raw_writew(val, (volatile u16 __iomem *) addr);
|
||||
}
|
||||
|
||||
#endif /* _HV_PAGESIZE_H */
|
||||
static inline u16 scr_readw(volatile const u16 *addr)
|
||||
{
|
||||
return __raw_readw((volatile const u16 __iomem *) addr);
|
||||
}
|
||||
|
||||
#define vga_readb(a) readb((u8 __iomem *)(a))
|
||||
#define vga_writeb(v,a) writeb(v, (u8 __iomem *)(a))
|
||||
|
||||
#define VGA_MAP_MEM(x,s) ((unsigned long) ioremap(x, s))
|
||||
|
||||
#endif
|
@ -22,8 +22,6 @@
|
||||
|
||||
#include <arch/chip.h>
|
||||
|
||||
#include <hv/pagesize.h>
|
||||
|
||||
/* Linux builds want unsigned long constants, but assembler wants numbers */
|
||||
#ifdef __ASSEMBLER__
|
||||
/** One, for assembler */
|
||||
@ -44,11 +42,21 @@
|
||||
*/
|
||||
#define HV_L1_SPAN (__HV_SIZE_ONE << HV_LOG2_L1_SPAN)
|
||||
|
||||
/** The log2 of the size of small pages, in bytes. This value should
|
||||
* be verified at runtime by calling hv_sysconf(HV_SYSCONF_PAGE_SIZE_SMALL).
|
||||
*/
|
||||
#define HV_LOG2_PAGE_SIZE_SMALL 16
|
||||
|
||||
/** The size of small pages, in bytes. This value should be verified
|
||||
* at runtime by calling hv_sysconf(HV_SYSCONF_PAGE_SIZE_SMALL).
|
||||
*/
|
||||
#define HV_PAGE_SIZE_SMALL (__HV_SIZE_ONE << HV_LOG2_PAGE_SIZE_SMALL)
|
||||
|
||||
/** The log2 of the size of large pages, in bytes. This value should be
|
||||
* verified at runtime by calling hv_sysconf(HV_SYSCONF_PAGE_SIZE_LARGE).
|
||||
*/
|
||||
#define HV_LOG2_PAGE_SIZE_LARGE 24
|
||||
|
||||
/** The size of large pages, in bytes. This value should be verified
|
||||
* at runtime by calling hv_sysconf(HV_SYSCONF_PAGE_SIZE_LARGE).
|
||||
*/
|
||||
|
@ -14,19 +14,11 @@
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/string.h>
|
||||
|
||||
#include <asm/backtrace.h>
|
||||
|
||||
#include <arch/chip.h>
|
||||
|
||||
#include <asm/opcode-tile.h>
|
||||
#include <arch/abi.h>
|
||||
|
||||
|
||||
#define TREG_SP 54
|
||||
#define TREG_LR 55
|
||||
|
||||
|
||||
#if TILE_CHIP >= 10
|
||||
#ifdef __tilegx__
|
||||
#define tile_bundle_bits tilegx_bundle_bits
|
||||
#define TILE_MAX_INSTRUCTIONS_PER_BUNDLE TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE
|
||||
#define TILE_BUNDLE_ALIGNMENT_IN_BYTES TILEGX_BUNDLE_ALIGNMENT_IN_BYTES
|
||||
@ -47,7 +39,7 @@ typedef long long bt_int_reg_t;
|
||||
typedef int bt_int_reg_t;
|
||||
#endif
|
||||
|
||||
/** A decoded bundle used for backtracer analysis. */
|
||||
/* A decoded bundle used for backtracer analysis. */
|
||||
struct BacktraceBundle {
|
||||
tile_bundle_bits bits;
|
||||
int num_insns;
|
||||
@ -56,23 +48,7 @@ struct BacktraceBundle {
|
||||
};
|
||||
|
||||
|
||||
/* This implementation only makes sense for native tools. */
|
||||
/** Default function to read memory. */
|
||||
static bool bt_read_memory(void *result, VirtualAddress addr,
|
||||
unsigned int size, void *extra)
|
||||
{
|
||||
/* FIXME: this should do some horrible signal stuff to catch
|
||||
* SEGV cleanly and fail.
|
||||
*
|
||||
* Or else the caller should do the setjmp for efficiency.
|
||||
*/
|
||||
|
||||
memcpy(result, (const void *)addr, size);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/** Locates an instruction inside the given bundle that
|
||||
/* Locates an instruction inside the given bundle that
|
||||
* has the specified mnemonic, and whose first 'num_operands_to_match'
|
||||
* operands exactly match those in 'operand_values'.
|
||||
*/
|
||||
@ -107,13 +83,13 @@ static const struct tile_decoded_instruction *find_matching_insn(
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/** Does this bundle contain an 'iret' instruction? */
|
||||
/* Does this bundle contain an 'iret' instruction? */
|
||||
static inline bool bt_has_iret(const struct BacktraceBundle *bundle)
|
||||
{
|
||||
return find_matching_insn(bundle, TILE_OPC_IRET, NULL, 0) != NULL;
|
||||
}
|
||||
|
||||
/** Does this bundle contain an 'addi sp, sp, OFFSET' or
|
||||
/* Does this bundle contain an 'addi sp, sp, OFFSET' or
|
||||
* 'addli sp, sp, OFFSET' instruction, and if so, what is OFFSET?
|
||||
*/
|
||||
static bool bt_has_addi_sp(const struct BacktraceBundle *bundle, int *adjust)
|
||||
@ -124,7 +100,7 @@ static bool bt_has_addi_sp(const struct BacktraceBundle *bundle, int *adjust)
|
||||
find_matching_insn(bundle, TILE_OPC_ADDI, vals, 2);
|
||||
if (insn == NULL)
|
||||
insn = find_matching_insn(bundle, TILE_OPC_ADDLI, vals, 2);
|
||||
#if TILE_CHIP >= 10
|
||||
#ifdef __tilegx__
|
||||
if (insn == NULL)
|
||||
insn = find_matching_insn(bundle, TILEGX_OPC_ADDXLI, vals, 2);
|
||||
if (insn == NULL)
|
||||
@ -137,7 +113,7 @@ static bool bt_has_addi_sp(const struct BacktraceBundle *bundle, int *adjust)
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Does this bundle contain any 'info OP' or 'infol OP'
|
||||
/* Does this bundle contain any 'info OP' or 'infol OP'
|
||||
* instruction, and if so, what are their OP? Note that OP is interpreted
|
||||
* as an unsigned value by this code since that's what the caller wants.
|
||||
* Returns the number of info ops found.
|
||||
@ -161,7 +137,7 @@ static int bt_get_info_ops(const struct BacktraceBundle *bundle,
|
||||
return num_ops;
|
||||
}
|
||||
|
||||
/** Does this bundle contain a jrp instruction, and if so, to which
|
||||
/* Does this bundle contain a jrp instruction, and if so, to which
|
||||
* register is it jumping?
|
||||
*/
|
||||
static bool bt_has_jrp(const struct BacktraceBundle *bundle, int *target_reg)
|
||||
@ -175,7 +151,7 @@ static bool bt_has_jrp(const struct BacktraceBundle *bundle, int *target_reg)
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Does this bundle modify the specified register in any way? */
|
||||
/* Does this bundle modify the specified register in any way? */
|
||||
static bool bt_modifies_reg(const struct BacktraceBundle *bundle, int reg)
|
||||
{
|
||||
int i, j;
|
||||
@ -195,34 +171,34 @@ static bool bt_modifies_reg(const struct BacktraceBundle *bundle, int reg)
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Does this bundle modify sp? */
|
||||
/* Does this bundle modify sp? */
|
||||
static inline bool bt_modifies_sp(const struct BacktraceBundle *bundle)
|
||||
{
|
||||
return bt_modifies_reg(bundle, TREG_SP);
|
||||
}
|
||||
|
||||
/** Does this bundle modify lr? */
|
||||
/* Does this bundle modify lr? */
|
||||
static inline bool bt_modifies_lr(const struct BacktraceBundle *bundle)
|
||||
{
|
||||
return bt_modifies_reg(bundle, TREG_LR);
|
||||
}
|
||||
|
||||
/** Does this bundle contain the instruction 'move fp, sp'? */
|
||||
/* Does this bundle contain the instruction 'move fp, sp'? */
|
||||
static inline bool bt_has_move_r52_sp(const struct BacktraceBundle *bundle)
|
||||
{
|
||||
static const int vals[2] = { 52, TREG_SP };
|
||||
return find_matching_insn(bundle, TILE_OPC_MOVE, vals, 2) != NULL;
|
||||
}
|
||||
|
||||
/** Does this bundle contain a store of lr to sp? */
|
||||
/* Does this bundle contain a store of lr to sp? */
|
||||
static inline bool bt_has_sw_sp_lr(const struct BacktraceBundle *bundle)
|
||||
{
|
||||
static const int vals[2] = { TREG_SP, TREG_LR };
|
||||
return find_matching_insn(bundle, OPCODE_STORE, vals, 2) != NULL;
|
||||
}
|
||||
|
||||
#if TILE_CHIP >= 10
|
||||
/** Track moveli values placed into registers. */
|
||||
#ifdef __tilegx__
|
||||
/* Track moveli values placed into registers. */
|
||||
static inline void bt_update_moveli(const struct BacktraceBundle *bundle,
|
||||
int moveli_args[])
|
||||
{
|
||||
@ -238,7 +214,7 @@ static inline void bt_update_moveli(const struct BacktraceBundle *bundle,
|
||||
}
|
||||
}
|
||||
|
||||
/** Does this bundle contain an 'add sp, sp, reg' instruction
|
||||
/* Does this bundle contain an 'add sp, sp, reg' instruction
|
||||
* from a register that we saw a moveli into, and if so, what
|
||||
* is the value in the register?
|
||||
*/
|
||||
@ -260,11 +236,11 @@ static bool bt_has_add_sp(const struct BacktraceBundle *bundle, int *adjust,
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Locates the caller's PC and SP for a program starting at the
|
||||
/* Locates the caller's PC and SP for a program starting at the
|
||||
* given address.
|
||||
*/
|
||||
static void find_caller_pc_and_caller_sp(CallerLocation *location,
|
||||
const VirtualAddress start_pc,
|
||||
const unsigned long start_pc,
|
||||
BacktraceMemoryReader read_memory_func,
|
||||
void *read_memory_func_extra)
|
||||
{
|
||||
@ -288,9 +264,9 @@ static void find_caller_pc_and_caller_sp(CallerLocation *location,
|
||||
tile_bundle_bits prefetched_bundles[32];
|
||||
int num_bundles_prefetched = 0;
|
||||
int next_bundle = 0;
|
||||
VirtualAddress pc;
|
||||
unsigned long pc;
|
||||
|
||||
#if TILE_CHIP >= 10
|
||||
#ifdef __tilegx__
|
||||
/* Naively try to track moveli values to support addx for -m32. */
|
||||
int moveli_args[TILEGX_NUM_REGISTERS] = { 0 };
|
||||
#endif
|
||||
@ -369,10 +345,6 @@ static void find_caller_pc_and_caller_sp(CallerLocation *location,
|
||||
/* Weird; reserved value, ignore it. */
|
||||
continue;
|
||||
}
|
||||
if (info_operand & ENTRY_POINT_INFO_OP) {
|
||||
/* This info op is ignored by the backtracer. */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Skip info ops which are not in the
|
||||
* "one_ago" mode we want right now.
|
||||
@ -453,7 +425,7 @@ static void find_caller_pc_and_caller_sp(CallerLocation *location,
|
||||
if (!sp_determined) {
|
||||
int adjust;
|
||||
if (bt_has_addi_sp(&bundle, &adjust)
|
||||
#if TILE_CHIP >= 10
|
||||
#ifdef __tilegx__
|
||||
|| bt_has_add_sp(&bundle, &adjust, moveli_args)
|
||||
#endif
|
||||
) {
|
||||
@ -504,7 +476,7 @@ static void find_caller_pc_and_caller_sp(CallerLocation *location,
|
||||
}
|
||||
}
|
||||
|
||||
#if TILE_CHIP >= 10
|
||||
#ifdef __tilegx__
|
||||
/* Track moveli arguments for -m32 mode. */
|
||||
bt_update_moveli(&bundle, moveli_args);
|
||||
#endif
|
||||
@ -546,18 +518,26 @@ static void find_caller_pc_and_caller_sp(CallerLocation *location,
|
||||
}
|
||||
}
|
||||
|
||||
/* Initializes a backtracer to start from the given location.
|
||||
*
|
||||
* If the frame pointer cannot be determined it is set to -1.
|
||||
*
|
||||
* state: The state to be filled in.
|
||||
* read_memory_func: A callback that reads memory.
|
||||
* read_memory_func_extra: An arbitrary argument to read_memory_func.
|
||||
* pc: The current PC.
|
||||
* lr: The current value of the 'lr' register.
|
||||
* sp: The current value of the 'sp' register.
|
||||
* r52: The current value of the 'r52' register.
|
||||
*/
|
||||
void backtrace_init(BacktraceIterator *state,
|
||||
BacktraceMemoryReader read_memory_func,
|
||||
void *read_memory_func_extra,
|
||||
VirtualAddress pc, VirtualAddress lr,
|
||||
VirtualAddress sp, VirtualAddress r52)
|
||||
unsigned long pc, unsigned long lr,
|
||||
unsigned long sp, unsigned long r52)
|
||||
{
|
||||
CallerLocation location;
|
||||
VirtualAddress fp, initial_frame_caller_pc;
|
||||
|
||||
if (read_memory_func == NULL) {
|
||||
read_memory_func = bt_read_memory;
|
||||
}
|
||||
unsigned long fp, initial_frame_caller_pc;
|
||||
|
||||
/* Find out where we are in the initial frame. */
|
||||
find_caller_pc_and_caller_sp(&location, pc,
|
||||
@ -630,12 +610,15 @@ void backtrace_init(BacktraceIterator *state,
|
||||
/* Handle the case where the register holds more bits than the VA. */
|
||||
static bool valid_addr_reg(bt_int_reg_t reg)
|
||||
{
|
||||
return ((VirtualAddress)reg == reg);
|
||||
return ((unsigned long)reg == reg);
|
||||
}
|
||||
|
||||
/* Advances the backtracing state to the calling frame, returning
|
||||
* true iff successful.
|
||||
*/
|
||||
bool backtrace_next(BacktraceIterator *state)
|
||||
{
|
||||
VirtualAddress next_fp, next_pc;
|
||||
unsigned long next_fp, next_pc;
|
||||
bt_int_reg_t next_frame[2];
|
||||
|
||||
if (state->fp == -1) {
|
||||
|
@ -135,26 +135,15 @@ long tile_compat_sys_msgrcv(int msqid,
|
||||
|
||||
/* Provide the compat syscall number to call mapping. */
|
||||
#undef __SYSCALL
|
||||
#define __SYSCALL(nr, call) [nr] = (compat_##call),
|
||||
#define __SYSCALL(nr, call) [nr] = (call),
|
||||
|
||||
/* The generic versions of these don't work for Tile. */
|
||||
#define compat_sys_msgrcv tile_compat_sys_msgrcv
|
||||
#define compat_sys_msgsnd tile_compat_sys_msgsnd
|
||||
|
||||
/* See comments in sys.c */
|
||||
#define compat_sys_fadvise64 sys32_fadvise64
|
||||
#define compat_sys_fadvise64_64 sys32_fadvise64_64
|
||||
#define compat_sys_readahead sys32_readahead
|
||||
#define compat_sys_sync_file_range compat_sys_sync_file_range2
|
||||
|
||||
/* We leverage the "struct stat64" type for 32-bit time_t/nsec. */
|
||||
#define compat_sys_stat64 sys_stat64
|
||||
#define compat_sys_lstat64 sys_lstat64
|
||||
#define compat_sys_fstat64 sys_fstat64
|
||||
#define compat_sys_fstatat64 sys_fstatat64
|
||||
|
||||
/* The native sys_ptrace dynamically handles compat binaries. */
|
||||
#define compat_sys_ptrace sys_ptrace
|
||||
|
||||
/* Call the trampolines to manage pt_regs where necessary. */
|
||||
#define compat_sys_execve _compat_sys_execve
|
||||
|
@ -317,7 +317,7 @@ long compat_sys_rt_sigreturn(struct pt_regs *regs)
|
||||
return 0;
|
||||
|
||||
badframe:
|
||||
force_sig(SIGSEGV, current);
|
||||
signal_fault("bad sigreturn frame", regs, frame, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -431,6 +431,6 @@ int compat_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
|
||||
return 0;
|
||||
|
||||
give_sigsegv:
|
||||
force_sigsegv(sig, current);
|
||||
signal_fault("bad setup frame", regs, frame, sig);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
55
arch/tile/kernel/futex_64.S
Normal file
55
arch/tile/kernel/futex_64.S
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 2011 Tilera Corporation. All Rights Reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation, version 2.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
|
||||
* NON INFRINGEMENT. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* Atomically access user memory, but use MMU to avoid propagating
|
||||
* kernel exceptions.
|
||||
*/
|
||||
|
||||
#include <linux/linkage.h>
|
||||
#include <asm/errno.h>
|
||||
#include <asm/futex.h>
|
||||
#include <asm/page.h>
|
||||
#include <asm/processor.h>
|
||||
|
||||
/*
|
||||
* Provide a set of atomic memory operations supporting <asm/futex.h>.
|
||||
*
|
||||
* r0: user address to manipulate
|
||||
* r1: new value to write, or for cmpxchg, old value to compare against
|
||||
* r2: (cmpxchg only) new value to write
|
||||
*
|
||||
* Return __get_user struct, r0 with value, r1 with error.
|
||||
*/
|
||||
#define FUTEX_OP(name, ...) \
|
||||
STD_ENTRY(futex_##name) \
|
||||
__VA_ARGS__; \
|
||||
{ \
|
||||
move r1, zero; \
|
||||
jrp lr \
|
||||
}; \
|
||||
STD_ENDPROC(futex_##name); \
|
||||
.pushsection __ex_table,"a"; \
|
||||
.quad 1b, get_user_fault; \
|
||||
.popsection
|
||||
|
||||
.pushsection .fixup,"ax"
|
||||
get_user_fault:
|
||||
{ movei r1, -EFAULT; jrp lr }
|
||||
ENDPROC(get_user_fault)
|
||||
.popsection
|
||||
|
||||
FUTEX_OP(cmpxchg, mtspr CMPEXCH_VALUE, r1; 1: cmpexch4 r0, r0, r2)
|
||||
FUTEX_OP(set, 1: exch4 r0, r0, r1)
|
||||
FUTEX_OP(add, 1: fetchadd4 r0, r0, r1)
|
||||
FUTEX_OP(or, 1: fetchor4 r0, r0, r1)
|
||||
FUTEX_OP(andn, nor r1, r1, zero; 1: fetchand4 r0, r0, r1)
|
@ -268,12 +268,10 @@ void __kprobes do_hardwall_trap(struct pt_regs* regs, int fault_num)
|
||||
found_processes = 0;
|
||||
list_for_each_entry(p, &rect->task_head, thread.hardwall_list) {
|
||||
BUG_ON(p->thread.hardwall != rect);
|
||||
if (p->sighand) {
|
||||
if (!(p->flags & PF_EXITING)) {
|
||||
found_processes = 1;
|
||||
pr_notice("hardwall: killing %d\n", p->pid);
|
||||
spin_lock(&p->sighand->siglock);
|
||||
__group_send_sig_info(info.si_signo, &info, p);
|
||||
spin_unlock(&p->sighand->siglock);
|
||||
do_send_sig_info(info.si_signo, &info, p, false);
|
||||
}
|
||||
}
|
||||
if (!found_processes)
|
||||
|
269
arch/tile/kernel/head_64.S
Normal file
269
arch/tile/kernel/head_64.S
Normal file
@ -0,0 +1,269 @@
|
||||
/*
|
||||
* Copyright 2011 Tilera Corporation. All Rights Reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation, version 2.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
|
||||
* NON INFRINGEMENT. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* TILE startup code.
|
||||
*/
|
||||
|
||||
#include <linux/linkage.h>
|
||||
#include <linux/init.h>
|
||||
#include <asm/page.h>
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/thread_info.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/asm-offsets.h>
|
||||
#include <hv/hypervisor.h>
|
||||
#include <arch/chip.h>
|
||||
#include <arch/spr_def.h>
|
||||
|
||||
/*
|
||||
* This module contains the entry code for kernel images. It performs the
|
||||
* minimal setup needed to call the generic C routines.
|
||||
*/
|
||||
|
||||
__HEAD
|
||||
ENTRY(_start)
|
||||
/* Notify the hypervisor of what version of the API we want */
|
||||
{
|
||||
movei r1, TILE_CHIP
|
||||
movei r2, TILE_CHIP_REV
|
||||
}
|
||||
{
|
||||
moveli r0, _HV_VERSION
|
||||
jal hv_init
|
||||
}
|
||||
/* Get a reasonable default ASID in r0 */
|
||||
{
|
||||
move r0, zero
|
||||
jal hv_inquire_asid
|
||||
}
|
||||
|
||||
/*
|
||||
* Install the default page table. The relocation required to
|
||||
* statically define the table is a bit too complex, so we have
|
||||
* to plug in the pointer from the L0 to the L1 table by hand.
|
||||
* We only do this on the first cpu to boot, though, since the
|
||||
* other CPUs should see a properly-constructed page table.
|
||||
*/
|
||||
{
|
||||
v4int_l r2, zero, r0 /* ASID for hv_install_context */
|
||||
moveli r4, hw1_last(swapper_pgprot - PAGE_OFFSET)
|
||||
}
|
||||
{
|
||||
shl16insli r4, r4, hw0(swapper_pgprot - PAGE_OFFSET)
|
||||
}
|
||||
{
|
||||
ld r1, r4 /* access_pte for hv_install_context */
|
||||
}
|
||||
{
|
||||
moveli r0, hw1_last(.Lsv_data_pmd - PAGE_OFFSET)
|
||||
moveli r6, hw1_last(temp_data_pmd - PAGE_OFFSET)
|
||||
}
|
||||
{
|
||||
/* After initializing swapper_pgprot, HV_PTE_GLOBAL is set. */
|
||||
bfextu r7, r1, HV_PTE_INDEX_GLOBAL, HV_PTE_INDEX_GLOBAL
|
||||
inv r4
|
||||
}
|
||||
bnez r7, .Lno_write
|
||||
{
|
||||
shl16insli r0, r0, hw0(.Lsv_data_pmd - PAGE_OFFSET)
|
||||
shl16insli r6, r6, hw0(temp_data_pmd - PAGE_OFFSET)
|
||||
}
|
||||
{
|
||||
/* Cut off the low bits of the PT address. */
|
||||
shrui r6, r6, HV_LOG2_PAGE_TABLE_ALIGN
|
||||
/* Start with our access pte. */
|
||||
move r5, r1
|
||||
}
|
||||
{
|
||||
/* Stuff the address into the page table pointer slot of the PTE. */
|
||||
bfins r5, r6, HV_PTE_INDEX_PTFN, \
|
||||
HV_PTE_INDEX_PTFN + HV_PTE_PTFN_BITS - 1
|
||||
}
|
||||
{
|
||||
/* Store the L0 data PTE. */
|
||||
st r0, r5
|
||||
addli r6, r6, (temp_code_pmd - temp_data_pmd) >> \
|
||||
HV_LOG2_PAGE_TABLE_ALIGN
|
||||
}
|
||||
{
|
||||
addli r0, r0, .Lsv_code_pmd - .Lsv_data_pmd
|
||||
bfins r5, r6, HV_PTE_INDEX_PTFN, \
|
||||
HV_PTE_INDEX_PTFN + HV_PTE_PTFN_BITS - 1
|
||||
}
|
||||
/* Store the L0 code PTE. */
|
||||
st r0, r5
|
||||
|
||||
.Lno_write:
|
||||
moveli lr, hw2_last(1f)
|
||||
{
|
||||
shl16insli lr, lr, hw1(1f)
|
||||
moveli r0, hw1_last(swapper_pg_dir - PAGE_OFFSET)
|
||||
}
|
||||
{
|
||||
shl16insli lr, lr, hw0(1f)
|
||||
shl16insli r0, r0, hw0(swapper_pg_dir - PAGE_OFFSET)
|
||||
}
|
||||
{
|
||||
move r3, zero
|
||||
j hv_install_context
|
||||
}
|
||||
1:
|
||||
|
||||
/* Install the interrupt base. */
|
||||
moveli r0, hw2_last(MEM_SV_START)
|
||||
shl16insli r0, r0, hw1(MEM_SV_START)
|
||||
shl16insli r0, r0, hw0(MEM_SV_START)
|
||||
mtspr SPR_INTERRUPT_VECTOR_BASE_K, r0
|
||||
|
||||
/*
|
||||
* Get our processor number and save it away in SAVE_K_0.
|
||||
* Extract stuff from the topology structure: r4 = y, r6 = x,
|
||||
* r5 = width. FIXME: consider whether we want to just make these
|
||||
* 64-bit values (and if so fix smp_topology write below, too).
|
||||
*/
|
||||
jal hv_inquire_topology
|
||||
{
|
||||
v4int_l r5, zero, r1 /* r5 = width */
|
||||
shrui r4, r0, 32 /* r4 = y */
|
||||
}
|
||||
{
|
||||
v4int_l r6, zero, r0 /* r6 = x */
|
||||
mul_lu_lu r4, r4, r5
|
||||
}
|
||||
{
|
||||
add r4, r4, r6 /* r4 == cpu == y*width + x */
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
/*
|
||||
* Load up our per-cpu offset. When the first (master) tile
|
||||
* boots, this value is still zero, so we will load boot_pc
|
||||
* with start_kernel, and boot_sp with init_stack + THREAD_SIZE.
|
||||
* The master tile initializes the per-cpu offset array, so that
|
||||
* when subsequent (secondary) tiles boot, they will instead load
|
||||
* from their per-cpu versions of boot_sp and boot_pc.
|
||||
*/
|
||||
moveli r5, hw2_last(__per_cpu_offset)
|
||||
shl16insli r5, r5, hw1(__per_cpu_offset)
|
||||
shl16insli r5, r5, hw0(__per_cpu_offset)
|
||||
shl3add r5, r4, r5
|
||||
ld r5, r5
|
||||
bnez r5, 1f
|
||||
|
||||
/*
|
||||
* Save the width and height to the smp_topology variable
|
||||
* for later use.
|
||||
*/
|
||||
moveli r0, hw2_last(smp_topology + HV_TOPOLOGY_WIDTH_OFFSET)
|
||||
shl16insli r0, r0, hw1(smp_topology + HV_TOPOLOGY_WIDTH_OFFSET)
|
||||
shl16insli r0, r0, hw0(smp_topology + HV_TOPOLOGY_WIDTH_OFFSET)
|
||||
st r0, r1
|
||||
1:
|
||||
#else
|
||||
move r5, zero
|
||||
#endif
|
||||
|
||||
/* Load and go with the correct pc and sp. */
|
||||
{
|
||||
moveli r1, hw2_last(boot_sp)
|
||||
moveli r0, hw2_last(boot_pc)
|
||||
}
|
||||
{
|
||||
shl16insli r1, r1, hw1(boot_sp)
|
||||
shl16insli r0, r0, hw1(boot_pc)
|
||||
}
|
||||
{
|
||||
shl16insli r1, r1, hw0(boot_sp)
|
||||
shl16insli r0, r0, hw0(boot_pc)
|
||||
}
|
||||
{
|
||||
add r1, r1, r5
|
||||
add r0, r0, r5
|
||||
}
|
||||
ld r0, r0
|
||||
ld sp, r1
|
||||
or r4, sp, r4
|
||||
mtspr SPR_SYSTEM_SAVE_K_0, r4 /* save ksp0 + cpu */
|
||||
addi sp, sp, -STACK_TOP_DELTA
|
||||
{
|
||||
move lr, zero /* stop backtraces in the called function */
|
||||
jr r0
|
||||
}
|
||||
ENDPROC(_start)
|
||||
|
||||
__PAGE_ALIGNED_BSS
|
||||
.align PAGE_SIZE
|
||||
ENTRY(empty_zero_page)
|
||||
.fill PAGE_SIZE,1,0
|
||||
END(empty_zero_page)
|
||||
|
||||
.macro PTE cpa, bits1
|
||||
.quad HV_PTE_PAGE | HV_PTE_DIRTY | HV_PTE_PRESENT | HV_PTE_ACCESSED |\
|
||||
HV_PTE_GLOBAL | (HV_PTE_MODE_CACHE_NO_L3 << HV_PTE_INDEX_MODE) |\
|
||||
(\bits1) | (HV_CPA_TO_PFN(\cpa) << HV_PTE_INDEX_PFN)
|
||||
.endm
|
||||
|
||||
__PAGE_ALIGNED_DATA
|
||||
.align PAGE_SIZE
|
||||
ENTRY(swapper_pg_dir)
|
||||
.org swapper_pg_dir + HV_L0_INDEX(PAGE_OFFSET) * HV_PTE_SIZE
|
||||
.Lsv_data_pmd:
|
||||
.quad 0 /* PTE temp_data_pmd - PAGE_OFFSET, 0 */
|
||||
.org swapper_pg_dir + HV_L0_INDEX(MEM_SV_START) * HV_PTE_SIZE
|
||||
.Lsv_code_pmd:
|
||||
.quad 0 /* PTE temp_code_pmd - PAGE_OFFSET, 0 */
|
||||
.org swapper_pg_dir + HV_L0_SIZE
|
||||
END(swapper_pg_dir)
|
||||
|
||||
.align HV_PAGE_TABLE_ALIGN
|
||||
ENTRY(temp_data_pmd)
|
||||
/*
|
||||
* We fill the PAGE_OFFSET pmd with huge pages with
|
||||
* VA = PA + PAGE_OFFSET. We remap things with more precise access
|
||||
* permissions later.
|
||||
*/
|
||||
.set addr, 0
|
||||
.rept HV_L1_ENTRIES
|
||||
PTE addr, HV_PTE_READABLE | HV_PTE_WRITABLE
|
||||
.set addr, addr + HV_PAGE_SIZE_LARGE
|
||||
.endr
|
||||
.org temp_data_pmd + HV_L1_SIZE
|
||||
END(temp_data_pmd)
|
||||
|
||||
.align HV_PAGE_TABLE_ALIGN
|
||||
ENTRY(temp_code_pmd)
|
||||
/*
|
||||
* We fill the MEM_SV_START pmd with huge pages with
|
||||
* VA = PA + PAGE_OFFSET. We remap things with more precise access
|
||||
* permissions later.
|
||||
*/
|
||||
.set addr, 0
|
||||
.rept HV_L1_ENTRIES
|
||||
PTE addr, HV_PTE_READABLE | HV_PTE_EXECUTABLE
|
||||
.set addr, addr + HV_PAGE_SIZE_LARGE
|
||||
.endr
|
||||
.org temp_code_pmd + HV_L1_SIZE
|
||||
END(temp_code_pmd)
|
||||
|
||||
/*
|
||||
* Isolate swapper_pgprot to its own cache line, since each cpu
|
||||
* starting up will read it using VA-is-PA and local homing.
|
||||
* This would otherwise likely conflict with other data on the cache
|
||||
* line, once we have set its permanent home in the page tables.
|
||||
*/
|
||||
__INITDATA
|
||||
.align CHIP_L2_LINE_SIZE()
|
||||
ENTRY(swapper_pgprot)
|
||||
.quad HV_PTE_PRESENT | (HV_PTE_MODE_CACHE_NO_L3 << HV_PTE_INDEX_MODE)
|
||||
.align CHIP_L2_LINE_SIZE()
|
||||
END(swapper_pgprot)
|
@ -851,14 +851,27 @@ STD_ENTRY(interrupt_return)
|
||||
/* Check to see if there is any work to do before returning to user. */
|
||||
{
|
||||
addi r29, r32, THREAD_INFO_FLAGS_OFFSET
|
||||
moveli r28, lo16(_TIF_ALLWORK_MASK)
|
||||
moveli r1, lo16(_TIF_ALLWORK_MASK)
|
||||
}
|
||||
{
|
||||
lw r29, r29
|
||||
auli r28, r28, ha16(_TIF_ALLWORK_MASK)
|
||||
auli r1, r1, ha16(_TIF_ALLWORK_MASK)
|
||||
}
|
||||
and r28, r29, r28
|
||||
bnz r28, .Lwork_pending
|
||||
and r1, r29, r1
|
||||
bzt r1, .Lrestore_all
|
||||
|
||||
/*
|
||||
* Make sure we have all the registers saved for signal
|
||||
* handling or single-step. Call out to C code to figure out
|
||||
* exactly what we need to do for each flag bit, then if
|
||||
* necessary, reload the flags and recheck.
|
||||
*/
|
||||
push_extra_callee_saves r0
|
||||
{
|
||||
PTREGS_PTR(r0, PTREGS_OFFSET_BASE)
|
||||
jal do_work_pending
|
||||
}
|
||||
bnz r0, .Lresume_userspace
|
||||
|
||||
/*
|
||||
* In the NMI case we
|
||||
@ -1099,99 +1112,6 @@ STD_ENTRY(interrupt_return)
|
||||
pop_reg r50
|
||||
pop_reg r51, sp, PTREGS_OFFSET_REG(29) - PTREGS_OFFSET_REG(51)
|
||||
j .Lcontinue_restore_regs
|
||||
|
||||
.Lwork_pending:
|
||||
/* Mask the reschedule flag */
|
||||
andi r28, r29, _TIF_NEED_RESCHED
|
||||
|
||||
{
|
||||
/*
|
||||
* If the NEED_RESCHED flag is called, we call schedule(), which
|
||||
* may drop this context right here and go do something else.
|
||||
* On return, jump back to .Lresume_userspace and recheck.
|
||||
*/
|
||||
bz r28, .Lasync_tlb
|
||||
|
||||
/* Mask the async-tlb flag */
|
||||
andi r28, r29, _TIF_ASYNC_TLB
|
||||
}
|
||||
|
||||
jal schedule
|
||||
FEEDBACK_REENTER(interrupt_return)
|
||||
|
||||
/* Reload the flags and check again */
|
||||
j .Lresume_userspace
|
||||
|
||||
.Lasync_tlb:
|
||||
{
|
||||
bz r28, .Lneed_sigpending
|
||||
|
||||
/* Mask the sigpending flag */
|
||||
andi r28, r29, _TIF_SIGPENDING
|
||||
}
|
||||
|
||||
PTREGS_PTR(r0, PTREGS_OFFSET_BASE)
|
||||
jal do_async_page_fault
|
||||
FEEDBACK_REENTER(interrupt_return)
|
||||
|
||||
/*
|
||||
* Go restart the "resume userspace" process. We may have
|
||||
* fired a signal, and we need to disable interrupts again.
|
||||
*/
|
||||
j .Lresume_userspace
|
||||
|
||||
.Lneed_sigpending:
|
||||
/*
|
||||
* At this point we are either doing signal handling or single-step,
|
||||
* so either way make sure we have all the registers saved.
|
||||
*/
|
||||
push_extra_callee_saves r0
|
||||
|
||||
{
|
||||
/* If no signal pending, skip to singlestep check */
|
||||
bz r28, .Lneed_singlestep
|
||||
|
||||
/* Mask the singlestep flag */
|
||||
andi r28, r29, _TIF_SINGLESTEP
|
||||
}
|
||||
|
||||
jal do_signal
|
||||
FEEDBACK_REENTER(interrupt_return)
|
||||
|
||||
/* Reload the flags and check again */
|
||||
j .Lresume_userspace
|
||||
|
||||
.Lneed_singlestep:
|
||||
{
|
||||
/* Get a pointer to the EX1 field */
|
||||
PTREGS_PTR(r29, PTREGS_OFFSET_EX1)
|
||||
|
||||
/* If we get here, our bit must be set. */
|
||||
bz r28, .Lwork_confusion
|
||||
}
|
||||
/* If we are in priv mode, don't single step */
|
||||
lw r28, r29
|
||||
andi r28, r28, SPR_EX_CONTEXT_1_1__PL_MASK /* mask off ICS */
|
||||
bnz r28, .Lrestore_all
|
||||
|
||||
/* Allow interrupts within the single step code */
|
||||
TRACE_IRQS_ON /* Note: clobbers registers r0-r29 */
|
||||
IRQ_ENABLE(r20, r21)
|
||||
|
||||
/* try to single-step the current instruction */
|
||||
PTREGS_PTR(r0, PTREGS_OFFSET_BASE)
|
||||
jal single_step_once
|
||||
FEEDBACK_REENTER(interrupt_return)
|
||||
|
||||
/* Re-disable interrupts. TRACE_IRQS_OFF in .Lrestore_all. */
|
||||
IRQ_DISABLE(r20,r21)
|
||||
|
||||
j .Lrestore_all
|
||||
|
||||
.Lwork_confusion:
|
||||
move r0, r28
|
||||
panic "thread_info allwork flags unhandled on userspace resume: %#x"
|
||||
|
||||
STD_ENDPROC(interrupt_return)
|
||||
|
||||
/*
|
||||
@ -1550,7 +1470,10 @@ STD_ENTRY(_sys_clone)
|
||||
* We place it in the __HEAD section to ensure it is relatively
|
||||
* near to the intvec_SWINT_1 code (reachable by a conditional branch).
|
||||
*
|
||||
* Must match register usage in do_page_fault().
|
||||
* Our use of ATOMIC_LOCK_REG here must match do_page_fault_ics().
|
||||
*
|
||||
* As we do in lib/atomic_asm_32.S, we bypass a store if the value we
|
||||
* would store is the same as the value we just loaded.
|
||||
*/
|
||||
__HEAD
|
||||
.align 64
|
||||
@ -1611,17 +1534,7 @@ ENTRY(sys_cmpxchg)
|
||||
{
|
||||
shri r20, r25, 32 - ATOMIC_HASH_L1_SHIFT
|
||||
slt_u r23, r0, r23
|
||||
|
||||
/*
|
||||
* Ensure that the TLB is loaded before we take out the lock.
|
||||
* On TILEPro, this will start fetching the value all the way
|
||||
* into our L1 as well (and if it gets modified before we
|
||||
* grab the lock, it will be invalidated from our cache
|
||||
* before we reload it). On tile64, we'll start fetching it
|
||||
* into our L1 if we're the home, and if we're not, we'll
|
||||
* still at least start fetching it into the home's L2.
|
||||
*/
|
||||
lw r26, r0
|
||||
lw r26, r0 /* see comment in the "#else" for the "lw r26". */
|
||||
}
|
||||
{
|
||||
s2a r21, r20, r21
|
||||
@ -1637,18 +1550,9 @@ ENTRY(sys_cmpxchg)
|
||||
bbs r23, .Lcmpxchg64
|
||||
andi r23, r0, 7 /* Precompute alignment for cmpxchg64. */
|
||||
}
|
||||
|
||||
{
|
||||
/*
|
||||
* We very carefully align the code that actually runs with
|
||||
* the lock held (nine bundles) so that we know it is all in
|
||||
* the icache when we start. This instruction (the jump) is
|
||||
* at the start of the first cache line, address zero mod 64;
|
||||
* we jump to somewhere in the second cache line to issue the
|
||||
* tns, then jump back to finish up.
|
||||
*/
|
||||
s2a ATOMIC_LOCK_REG_NAME, r25, r21
|
||||
j .Lcmpxchg32_tns
|
||||
j .Lcmpxchg32_tns /* see comment in the #else for the jump. */
|
||||
}
|
||||
|
||||
#else /* ATOMIC_LOCKS_FOUND_VIA_TABLE() */
|
||||
@ -1713,24 +1617,25 @@ ENTRY(sys_cmpxchg)
|
||||
{
|
||||
/*
|
||||
* We very carefully align the code that actually runs with
|
||||
* the lock held (nine bundles) so that we know it is all in
|
||||
* the lock held (twelve bundles) so that we know it is all in
|
||||
* the icache when we start. This instruction (the jump) is
|
||||
* at the start of the first cache line, address zero mod 64;
|
||||
* we jump to somewhere in the second cache line to issue the
|
||||
* tns, then jump back to finish up.
|
||||
* we jump to the very end of the second cache line to get that
|
||||
* line loaded in the icache, then fall through to issue the tns
|
||||
* in the third cache line, at which point it's all cached.
|
||||
* Note that is for performance, not correctness.
|
||||
*/
|
||||
j .Lcmpxchg32_tns
|
||||
}
|
||||
|
||||
#endif /* ATOMIC_LOCKS_FOUND_VIA_TABLE() */
|
||||
|
||||
ENTRY(__sys_cmpxchg_grab_lock)
|
||||
/* Symbol for do_page_fault_ics() to use to compare against the PC. */
|
||||
.global __sys_cmpxchg_grab_lock
|
||||
__sys_cmpxchg_grab_lock:
|
||||
|
||||
/*
|
||||
* Perform the actual cmpxchg or atomic_update.
|
||||
* Note that the system <arch/atomic.h> header relies on
|
||||
* atomic_update() to always perform an "mf", so don't make
|
||||
* it optional or conditional without modifying that code.
|
||||
*/
|
||||
.Ldo_cmpxchg32:
|
||||
{
|
||||
@ -1748,10 +1653,13 @@ ENTRY(sys_cmpxchg)
|
||||
}
|
||||
{
|
||||
mvnz r24, r23, r25 /* Use atomic_update value if appropriate. */
|
||||
bbns r22, .Lcmpxchg32_mismatch
|
||||
bbns r22, .Lcmpxchg32_nostore
|
||||
}
|
||||
seq r22, r24, r21 /* Are we storing the value we loaded? */
|
||||
bbs r22, .Lcmpxchg32_nostore
|
||||
sw r0, r24
|
||||
|
||||
/* The following instruction is the start of the second cache line. */
|
||||
/* Do slow mtspr here so the following "mf" waits less. */
|
||||
{
|
||||
move sp, r27
|
||||
@ -1759,7 +1667,6 @@ ENTRY(sys_cmpxchg)
|
||||
}
|
||||
mf
|
||||
|
||||
/* The following instruction is the start of the second cache line. */
|
||||
{
|
||||
move r0, r21
|
||||
sw ATOMIC_LOCK_REG_NAME, zero
|
||||
@ -1767,7 +1674,7 @@ ENTRY(sys_cmpxchg)
|
||||
iret
|
||||
|
||||
/* Duplicated code here in the case where we don't overlap "mf" */
|
||||
.Lcmpxchg32_mismatch:
|
||||
.Lcmpxchg32_nostore:
|
||||
{
|
||||
move r0, r21
|
||||
sw ATOMIC_LOCK_REG_NAME, zero
|
||||
@ -1783,8 +1690,6 @@ ENTRY(sys_cmpxchg)
|
||||
* and for 64-bit cmpxchg. We provide it as a macro and put
|
||||
* it into both versions. We can't share the code literally
|
||||
* since it depends on having the right branch-back address.
|
||||
* Note that the first few instructions should share the cache
|
||||
* line with the second half of the actual locked code.
|
||||
*/
|
||||
.macro cmpxchg_lock, bitwidth
|
||||
|
||||
@ -1810,7 +1715,7 @@ ENTRY(sys_cmpxchg)
|
||||
}
|
||||
/*
|
||||
* The preceding instruction is the last thing that must be
|
||||
* on the second cache line.
|
||||
* hot in the icache before we do the "tns" above.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
@ -1841,6 +1746,12 @@ ENTRY(sys_cmpxchg)
|
||||
.endm
|
||||
|
||||
.Lcmpxchg32_tns:
|
||||
/*
|
||||
* This is the last instruction on the second cache line.
|
||||
* The nop here loads the second line, then we fall through
|
||||
* to the tns to load the third line before we take the lock.
|
||||
*/
|
||||
nop
|
||||
cmpxchg_lock 32
|
||||
|
||||
/*
|
||||
|
1231
arch/tile/kernel/intvec_64.S
Normal file
1231
arch/tile/kernel/intvec_64.S
Normal file
File diff suppressed because it is too large
Load Diff
@ -22,6 +22,7 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <asm/opcode-tile.h>
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/homecache.h>
|
||||
|
||||
#ifdef __tilegx__
|
||||
# define Elf_Rela Elf64_Rela
|
||||
@ -86,8 +87,13 @@ error:
|
||||
void module_free(struct module *mod, void *module_region)
|
||||
{
|
||||
vfree(module_region);
|
||||
|
||||
/* Globally flush the L1 icache. */
|
||||
flush_remote(0, HV_FLUSH_EVICT_L1I, cpu_online_mask,
|
||||
0, 0, 0, NULL, NULL, 0);
|
||||
|
||||
/*
|
||||
* FIXME: If module_region == mod->init_region, trim exception
|
||||
* FIXME: If module_region == mod->module_init, trim exception
|
||||
* table entries.
|
||||
*/
|
||||
}
|
||||
|
@ -244,7 +244,7 @@ EXPORT_SYMBOL(dma_sync_single_range_for_device);
|
||||
* dma_alloc_noncoherent() returns non-cacheable memory, so there's no
|
||||
* need to do any flushing here.
|
||||
*/
|
||||
void dma_cache_sync(void *vaddr, size_t size,
|
||||
void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
|
||||
enum dma_data_direction direction)
|
||||
{
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010 Tilera Corporation. All Rights Reserved.
|
||||
* Copyright 2011 Tilera Corporation. All Rights Reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@ -59,6 +59,7 @@ int __write_once tile_plx_gen1;
|
||||
|
||||
static struct pci_controller controllers[TILE_NUM_PCIE];
|
||||
static int num_controllers;
|
||||
static int pci_scan_flags[TILE_NUM_PCIE];
|
||||
|
||||
static struct pci_ops tile_cfg_ops;
|
||||
|
||||
@ -79,7 +80,7 @@ EXPORT_SYMBOL(pcibios_align_resource);
|
||||
* controller_id is the controller number, config type is 0 or 1 for
|
||||
* config0 or config1 operations.
|
||||
*/
|
||||
static int __init tile_pcie_open(int controller_id, int config_type)
|
||||
static int __devinit tile_pcie_open(int controller_id, int config_type)
|
||||
{
|
||||
char filename[32];
|
||||
int fd;
|
||||
@ -95,7 +96,7 @@ static int __init tile_pcie_open(int controller_id, int config_type)
|
||||
/*
|
||||
* Get the IRQ numbers from the HV and set up the handlers for them.
|
||||
*/
|
||||
static int __init tile_init_irqs(int controller_id,
|
||||
static int __devinit tile_init_irqs(int controller_id,
|
||||
struct pci_controller *controller)
|
||||
{
|
||||
char filename[32];
|
||||
@ -139,71 +140,74 @@ static int __init tile_init_irqs(int controller_id,
|
||||
*
|
||||
* Returns the number of controllers discovered.
|
||||
*/
|
||||
int __init tile_pci_init(void)
|
||||
int __devinit tile_pci_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
pr_info("PCI: Searching for controllers...\n");
|
||||
|
||||
/* Re-init number of PCIe controllers to support hot-plug feature. */
|
||||
num_controllers = 0;
|
||||
|
||||
/* Do any configuration we need before using the PCIe */
|
||||
|
||||
for (i = 0; i < TILE_NUM_PCIE; i++) {
|
||||
int hv_cfg_fd0 = -1;
|
||||
int hv_cfg_fd1 = -1;
|
||||
int hv_mem_fd = -1;
|
||||
char name[32];
|
||||
struct pci_controller *controller;
|
||||
|
||||
/*
|
||||
* Open the fd to the HV. If it fails then this
|
||||
* device doesn't exist.
|
||||
* To see whether we need a real config op based on
|
||||
* the results of pcibios_init(), to support PCIe hot-plug.
|
||||
*/
|
||||
hv_cfg_fd0 = tile_pcie_open(i, 0);
|
||||
if (hv_cfg_fd0 < 0)
|
||||
if (pci_scan_flags[i] == 0) {
|
||||
int hv_cfg_fd0 = -1;
|
||||
int hv_cfg_fd1 = -1;
|
||||
int hv_mem_fd = -1;
|
||||
char name[32];
|
||||
struct pci_controller *controller;
|
||||
|
||||
/*
|
||||
* Open the fd to the HV. If it fails then this
|
||||
* device doesn't exist.
|
||||
*/
|
||||
hv_cfg_fd0 = tile_pcie_open(i, 0);
|
||||
if (hv_cfg_fd0 < 0)
|
||||
continue;
|
||||
hv_cfg_fd1 = tile_pcie_open(i, 1);
|
||||
if (hv_cfg_fd1 < 0) {
|
||||
pr_err("PCI: Couldn't open config fd to HV "
|
||||
"for controller %d\n", i);
|
||||
goto err_cont;
|
||||
}
|
||||
|
||||
sprintf(name, "pcie/%d/mem", i);
|
||||
hv_mem_fd = hv_dev_open((HV_VirtAddr)name, 0);
|
||||
if (hv_mem_fd < 0) {
|
||||
pr_err("PCI: Could not open mem fd to HV!\n");
|
||||
goto err_cont;
|
||||
}
|
||||
|
||||
pr_info("PCI: Found PCI controller #%d\n", i);
|
||||
|
||||
controller = &controllers[i];
|
||||
|
||||
controller->index = i;
|
||||
controller->hv_cfg_fd[0] = hv_cfg_fd0;
|
||||
controller->hv_cfg_fd[1] = hv_cfg_fd1;
|
||||
controller->hv_mem_fd = hv_mem_fd;
|
||||
controller->first_busno = 0;
|
||||
controller->last_busno = 0xff;
|
||||
controller->ops = &tile_cfg_ops;
|
||||
|
||||
num_controllers++;
|
||||
continue;
|
||||
hv_cfg_fd1 = tile_pcie_open(i, 1);
|
||||
if (hv_cfg_fd1 < 0) {
|
||||
pr_err("PCI: Couldn't open config fd to HV "
|
||||
"for controller %d\n", i);
|
||||
goto err_cont;
|
||||
}
|
||||
|
||||
sprintf(name, "pcie/%d/mem", i);
|
||||
hv_mem_fd = hv_dev_open((HV_VirtAddr)name, 0);
|
||||
if (hv_mem_fd < 0) {
|
||||
pr_err("PCI: Could not open mem fd to HV!\n");
|
||||
goto err_cont;
|
||||
}
|
||||
|
||||
pr_info("PCI: Found PCI controller #%d\n", i);
|
||||
|
||||
controller = &controllers[num_controllers];
|
||||
|
||||
if (tile_init_irqs(i, controller)) {
|
||||
pr_err("PCI: Could not initialize "
|
||||
"IRQs, aborting.\n");
|
||||
goto err_cont;
|
||||
}
|
||||
|
||||
controller->index = num_controllers;
|
||||
controller->hv_cfg_fd[0] = hv_cfg_fd0;
|
||||
controller->hv_cfg_fd[1] = hv_cfg_fd1;
|
||||
controller->hv_mem_fd = hv_mem_fd;
|
||||
controller->first_busno = 0;
|
||||
controller->last_busno = 0xff;
|
||||
controller->ops = &tile_cfg_ops;
|
||||
|
||||
num_controllers++;
|
||||
continue;
|
||||
|
||||
err_cont:
|
||||
if (hv_cfg_fd0 >= 0)
|
||||
hv_dev_close(hv_cfg_fd0);
|
||||
if (hv_cfg_fd1 >= 0)
|
||||
hv_dev_close(hv_cfg_fd1);
|
||||
if (hv_mem_fd >= 0)
|
||||
hv_dev_close(hv_mem_fd);
|
||||
continue;
|
||||
if (hv_cfg_fd0 >= 0)
|
||||
hv_dev_close(hv_cfg_fd0);
|
||||
if (hv_cfg_fd1 >= 0)
|
||||
hv_dev_close(hv_cfg_fd1);
|
||||
if (hv_mem_fd >= 0)
|
||||
hv_dev_close(hv_mem_fd);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -232,7 +236,7 @@ static int tile_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
|
||||
}
|
||||
|
||||
|
||||
static void __init fixup_read_and_payload_sizes(void)
|
||||
static void __devinit fixup_read_and_payload_sizes(void)
|
||||
{
|
||||
struct pci_dev *dev = NULL;
|
||||
int smallest_max_payload = 0x1; /* Tile maxes out at 256 bytes. */
|
||||
@ -282,7 +286,7 @@ static void __init fixup_read_and_payload_sizes(void)
|
||||
* The controllers have been set up by the time we get here, by a call to
|
||||
* tile_pci_init.
|
||||
*/
|
||||
static int __init pcibios_init(void)
|
||||
int __devinit pcibios_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
@ -296,25 +300,36 @@ static int __init pcibios_init(void)
|
||||
mdelay(250);
|
||||
|
||||
/* Scan all of the recorded PCI controllers. */
|
||||
for (i = 0; i < num_controllers; i++) {
|
||||
struct pci_controller *controller = &controllers[i];
|
||||
struct pci_bus *bus;
|
||||
|
||||
pr_info("PCI: initializing controller #%d\n", i);
|
||||
|
||||
for (i = 0; i < TILE_NUM_PCIE; i++) {
|
||||
/*
|
||||
* This comes from the generic Linux PCI driver.
|
||||
*
|
||||
* It reads the PCI tree for this bus into the Linux
|
||||
* data structures.
|
||||
*
|
||||
* This is inlined in linux/pci.h and calls into
|
||||
* pci_scan_bus_parented() in probe.c.
|
||||
* Do real pcibios init ops if the controller is initialized
|
||||
* by tile_pci_init() successfully and not initialized by
|
||||
* pcibios_init() yet to support PCIe hot-plug.
|
||||
*/
|
||||
bus = pci_scan_bus(0, controller->ops, controller);
|
||||
controller->root_bus = bus;
|
||||
controller->last_busno = bus->subordinate;
|
||||
if (pci_scan_flags[i] == 0 && controllers[i].ops != NULL) {
|
||||
struct pci_controller *controller = &controllers[i];
|
||||
struct pci_bus *bus;
|
||||
|
||||
if (tile_init_irqs(i, controller)) {
|
||||
pr_err("PCI: Could not initialize IRQs\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
pr_info("PCI: initializing controller #%d\n", i);
|
||||
|
||||
/*
|
||||
* This comes from the generic Linux PCI driver.
|
||||
*
|
||||
* It reads the PCI tree for this bus into the Linux
|
||||
* data structures.
|
||||
*
|
||||
* This is inlined in linux/pci.h and calls into
|
||||
* pci_scan_bus_parented() in probe.c.
|
||||
*/
|
||||
bus = pci_scan_bus(0, controller->ops, controller);
|
||||
controller->root_bus = bus;
|
||||
controller->last_busno = bus->subordinate;
|
||||
}
|
||||
}
|
||||
|
||||
/* Do machine dependent PCI interrupt routing */
|
||||
@ -326,34 +341,45 @@ static int __init pcibios_init(void)
|
||||
* It allocates all of the resources (I/O memory, etc)
|
||||
* associated with the devices read in above.
|
||||
*/
|
||||
|
||||
pci_assign_unassigned_resources();
|
||||
|
||||
/* Configure the max_read_size and max_payload_size values. */
|
||||
fixup_read_and_payload_sizes();
|
||||
|
||||
/* Record the I/O resources in the PCI controller structure. */
|
||||
for (i = 0; i < num_controllers; i++) {
|
||||
struct pci_bus *root_bus = controllers[i].root_bus;
|
||||
struct pci_bus *next_bus;
|
||||
struct pci_dev *dev;
|
||||
for (i = 0; i < TILE_NUM_PCIE; i++) {
|
||||
/*
|
||||
* Do real pcibios init ops if the controller is initialized
|
||||
* by tile_pci_init() successfully and not initialized by
|
||||
* pcibios_init() yet to support PCIe hot-plug.
|
||||
*/
|
||||
if (pci_scan_flags[i] == 0 && controllers[i].ops != NULL) {
|
||||
struct pci_bus *root_bus = controllers[i].root_bus;
|
||||
struct pci_bus *next_bus;
|
||||
struct pci_dev *dev;
|
||||
|
||||
list_for_each_entry(dev, &root_bus->devices, bus_list) {
|
||||
/* Find the PCI host controller, ie. the 1st bridge. */
|
||||
if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI &&
|
||||
(PCI_SLOT(dev->devfn) == 0)) {
|
||||
next_bus = dev->subordinate;
|
||||
controllers[i].mem_resources[0] =
|
||||
*next_bus->resource[0];
|
||||
controllers[i].mem_resources[1] =
|
||||
*next_bus->resource[1];
|
||||
controllers[i].mem_resources[2] =
|
||||
*next_bus->resource[2];
|
||||
list_for_each_entry(dev, &root_bus->devices, bus_list) {
|
||||
/*
|
||||
* Find the PCI host controller, ie. the 1st
|
||||
* bridge.
|
||||
*/
|
||||
if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI &&
|
||||
(PCI_SLOT(dev->devfn) == 0)) {
|
||||
next_bus = dev->subordinate;
|
||||
controllers[i].mem_resources[0] =
|
||||
*next_bus->resource[0];
|
||||
controllers[i].mem_resources[1] =
|
||||
*next_bus->resource[1];
|
||||
controllers[i].mem_resources[2] =
|
||||
*next_bus->resource[2];
|
||||
|
||||
break;
|
||||
/* Setup flags. */
|
||||
pci_scan_flags[i] = 1;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -381,7 +407,7 @@ char __devinit *pcibios_setup(char *str)
|
||||
/*
|
||||
* This is called from the generic Linux layer.
|
||||
*/
|
||||
void __init pcibios_update_irq(struct pci_dev *dev, int irq)
|
||||
void __devinit pcibios_update_irq(struct pci_dev *dev, int irq)
|
||||
{
|
||||
pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
|
||||
}
|
||||
|
@ -25,10 +25,13 @@
|
||||
#include <linux/hardirq.h>
|
||||
#include <linux/syscalls.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/tracehook.h>
|
||||
#include <linux/signal.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/stack.h>
|
||||
#include <asm/homecache.h>
|
||||
#include <asm/syscalls.h>
|
||||
#include <asm/traps.h>
|
||||
#ifdef CONFIG_HARDWALL
|
||||
#include <asm/hardwall.h>
|
||||
#endif
|
||||
@ -546,6 +549,51 @@ struct task_struct *__sched _switch_to(struct task_struct *prev,
|
||||
return __switch_to(prev, next, next_current_ksp0(next));
|
||||
}
|
||||
|
||||
/*
|
||||
* This routine is called on return from interrupt if any of the
|
||||
* TIF_WORK_MASK flags are set in thread_info->flags. It is
|
||||
* entered with interrupts disabled so we don't miss an event
|
||||
* that modified the thread_info flags. If any flag is set, we
|
||||
* handle it and return, and the calling assembly code will
|
||||
* re-disable interrupts, reload the thread flags, and call back
|
||||
* if more flags need to be handled.
|
||||
*
|
||||
* We return whether we need to check the thread_info flags again
|
||||
* or not. Note that we don't clear TIF_SINGLESTEP here, so it's
|
||||
* important that it be tested last, and then claim that we don't
|
||||
* need to recheck the flags.
|
||||
*/
|
||||
int do_work_pending(struct pt_regs *regs, u32 thread_info_flags)
|
||||
{
|
||||
if (thread_info_flags & _TIF_NEED_RESCHED) {
|
||||
schedule();
|
||||
return 1;
|
||||
}
|
||||
#if CHIP_HAS_TILE_DMA() || CHIP_HAS_SN_PROC()
|
||||
if (thread_info_flags & _TIF_ASYNC_TLB) {
|
||||
do_async_page_fault(regs);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
if (thread_info_flags & _TIF_SIGPENDING) {
|
||||
do_signal(regs);
|
||||
return 1;
|
||||
}
|
||||
if (thread_info_flags & _TIF_NOTIFY_RESUME) {
|
||||
clear_thread_flag(TIF_NOTIFY_RESUME);
|
||||
tracehook_notify_resume(regs);
|
||||
if (current->replacement_session_keyring)
|
||||
key_replace_session_keyring();
|
||||
return 1;
|
||||
}
|
||||
if (thread_info_flags & _TIF_SINGLESTEP) {
|
||||
if ((regs->ex1 & SPR_EX_CONTEXT_1_1__PL_MASK) == 0)
|
||||
single_step_once(regs);
|
||||
return 0;
|
||||
}
|
||||
panic("work_pending: bad flags %#x\n", thread_info_flags);
|
||||
}
|
||||
|
||||
/* Note there is an implicit fifth argument if (clone_flags & CLONE_SETTLS). */
|
||||
SYSCALL_DEFINE5(clone, unsigned long, clone_flags, unsigned long, newsp,
|
||||
void __user *, parent_tidptr, void __user *, child_tidptr,
|
||||
@ -582,8 +630,8 @@ out:
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
long compat_sys_execve(const char __user *path,
|
||||
const compat_uptr_t __user *argv,
|
||||
const compat_uptr_t __user *envp,
|
||||
compat_uptr_t __user *argv,
|
||||
compat_uptr_t __user *envp,
|
||||
struct pt_regs *regs)
|
||||
{
|
||||
long error;
|
||||
|
145
arch/tile/kernel/regs_64.S
Normal file
145
arch/tile/kernel/regs_64.S
Normal file
@ -0,0 +1,145 @@
|
||||
/*
|
||||
* Copyright 2011 Tilera Corporation. All Rights Reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation, version 2.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
|
||||
* NON INFRINGEMENT. See the GNU General Public License for
|
||||
* more details.
|
||||
*/
|
||||
|
||||
#include <linux/linkage.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/ptrace.h>
|
||||
#include <asm/asm-offsets.h>
|
||||
#include <arch/spr_def.h>
|
||||
#include <asm/processor.h>
|
||||
|
||||
/*
|
||||
* See <asm/system.h>; called with prev and next task_struct pointers.
|
||||
* "prev" is returned in r0 for _switch_to and also for ret_from_fork.
|
||||
*
|
||||
* We want to save pc/sp in "prev", and get the new pc/sp from "next".
|
||||
* We also need to save all the callee-saved registers on the stack.
|
||||
*
|
||||
* Intel enables/disables access to the hardware cycle counter in
|
||||
* seccomp (secure computing) environments if necessary, based on
|
||||
* has_secure_computing(). We might want to do this at some point,
|
||||
* though it would require virtualizing the other SPRs under WORLD_ACCESS.
|
||||
*
|
||||
* Since we're saving to the stack, we omit sp from this list.
|
||||
* And for parallels with other architectures, we save lr separately,
|
||||
* in the thread_struct itself (as the "pc" field).
|
||||
*
|
||||
* This code also needs to be aligned with process.c copy_thread()
|
||||
*/
|
||||
|
||||
#if CALLEE_SAVED_REGS_COUNT != 24
|
||||
# error Mismatch between <asm/system.h> and kernel/entry.S
|
||||
#endif
|
||||
#define FRAME_SIZE ((2 + CALLEE_SAVED_REGS_COUNT) * 8)
|
||||
|
||||
#define SAVE_REG(r) { st r12, r; addi r12, r12, 8 }
|
||||
#define LOAD_REG(r) { ld r, r12; addi r12, r12, 8 }
|
||||
#define FOR_EACH_CALLEE_SAVED_REG(f) \
|
||||
f(r30); f(r31); \
|
||||
f(r32); f(r33); f(r34); f(r35); f(r36); f(r37); f(r38); f(r39); \
|
||||
f(r40); f(r41); f(r42); f(r43); f(r44); f(r45); f(r46); f(r47); \
|
||||
f(r48); f(r49); f(r50); f(r51); f(r52);
|
||||
|
||||
STD_ENTRY_SECTION(__switch_to, .sched.text)
|
||||
{
|
||||
move r10, sp
|
||||
st sp, lr
|
||||
}
|
||||
{
|
||||
addli r11, sp, -FRAME_SIZE + 8
|
||||
addli sp, sp, -FRAME_SIZE
|
||||
}
|
||||
{
|
||||
st r11, r10
|
||||
addli r4, r1, TASK_STRUCT_THREAD_KSP_OFFSET
|
||||
}
|
||||
{
|
||||
ld r13, r4 /* Load new sp to a temp register early. */
|
||||
addi r12, sp, 16
|
||||
}
|
||||
FOR_EACH_CALLEE_SAVED_REG(SAVE_REG)
|
||||
addli r3, r0, TASK_STRUCT_THREAD_KSP_OFFSET
|
||||
{
|
||||
st r3, sp
|
||||
addli r3, r0, TASK_STRUCT_THREAD_PC_OFFSET
|
||||
}
|
||||
{
|
||||
st r3, lr
|
||||
addli r4, r1, TASK_STRUCT_THREAD_PC_OFFSET
|
||||
}
|
||||
{
|
||||
ld lr, r4
|
||||
addi r12, r13, 16
|
||||
}
|
||||
{
|
||||
/* Update sp and ksp0 simultaneously to avoid backtracer warnings. */
|
||||
move sp, r13
|
||||
mtspr SPR_SYSTEM_SAVE_K_0, r2
|
||||
}
|
||||
FOR_EACH_CALLEE_SAVED_REG(LOAD_REG)
|
||||
.L__switch_to_pc:
|
||||
{
|
||||
addli sp, sp, FRAME_SIZE
|
||||
jrp lr /* r0 is still valid here, so return it */
|
||||
}
|
||||
STD_ENDPROC(__switch_to)
|
||||
|
||||
/* Return a suitable address for the backtracer for suspended threads */
|
||||
STD_ENTRY_SECTION(get_switch_to_pc, .sched.text)
|
||||
lnk r0
|
||||
{
|
||||
addli r0, r0, .L__switch_to_pc - .
|
||||
jrp lr
|
||||
}
|
||||
STD_ENDPROC(get_switch_to_pc)
|
||||
|
||||
STD_ENTRY(get_pt_regs)
|
||||
.irp reg, r0, r1, r2, r3, r4, r5, r6, r7, \
|
||||
r8, r9, r10, r11, r12, r13, r14, r15, \
|
||||
r16, r17, r18, r19, r20, r21, r22, r23, \
|
||||
r24, r25, r26, r27, r28, r29, r30, r31, \
|
||||
r32, r33, r34, r35, r36, r37, r38, r39, \
|
||||
r40, r41, r42, r43, r44, r45, r46, r47, \
|
||||
r48, r49, r50, r51, r52, tp, sp
|
||||
{
|
||||
st r0, \reg
|
||||
addi r0, r0, 8
|
||||
}
|
||||
.endr
|
||||
{
|
||||
st r0, lr
|
||||
addi r0, r0, PTREGS_OFFSET_PC - PTREGS_OFFSET_LR
|
||||
}
|
||||
lnk r1
|
||||
{
|
||||
st r0, r1
|
||||
addi r0, r0, PTREGS_OFFSET_EX1 - PTREGS_OFFSET_PC
|
||||
}
|
||||
mfspr r1, INTERRUPT_CRITICAL_SECTION
|
||||
shli r1, r1, SPR_EX_CONTEXT_1_1__ICS_SHIFT
|
||||
ori r1, r1, KERNEL_PL
|
||||
{
|
||||
st r0, r1
|
||||
addi r0, r0, PTREGS_OFFSET_FAULTNUM - PTREGS_OFFSET_EX1
|
||||
}
|
||||
{
|
||||
st r0, zero /* clear faultnum */
|
||||
addi r0, r0, PTREGS_OFFSET_ORIG_R0 - PTREGS_OFFSET_FAULTNUM
|
||||
}
|
||||
{
|
||||
st r0, zero /* clear orig_r0 */
|
||||
addli r0, r0, -PTREGS_OFFSET_ORIG_R0 /* restore r0 to base */
|
||||
}
|
||||
jrp lr
|
||||
STD_ENDPROC(get_pt_regs)
|
@ -912,6 +912,8 @@ void __cpuinit setup_cpu(int boot)
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CONFIG_BLK_DEV_INITRD
|
||||
|
||||
static int __initdata set_initramfs_file;
|
||||
static char __initdata initramfs_file[128] = "initramfs.cpio.gz";
|
||||
|
||||
@ -969,6 +971,10 @@ void __init free_initrd_mem(unsigned long begin, unsigned long end)
|
||||
free_bootmem(__pa(begin), end - begin);
|
||||
}
|
||||
|
||||
#else
|
||||
static inline void load_hv_initrd(void) {}
|
||||
#endif /* CONFIG_BLK_DEV_INITRD */
|
||||
|
||||
static void __init validate_hv(void)
|
||||
{
|
||||
/*
|
||||
|
@ -39,7 +39,6 @@
|
||||
|
||||
#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
|
||||
|
||||
|
||||
SYSCALL_DEFINE3(sigaltstack, const stack_t __user *, uss,
|
||||
stack_t __user *, uoss, struct pt_regs *, regs)
|
||||
{
|
||||
@ -78,6 +77,13 @@ int restore_sigcontext(struct pt_regs *regs,
|
||||
return err;
|
||||
}
|
||||
|
||||
void signal_fault(const char *type, struct pt_regs *regs,
|
||||
void __user *frame, int sig)
|
||||
{
|
||||
trace_unhandled_signal(type, regs, (unsigned long)frame, SIGSEGV);
|
||||
force_sigsegv(sig, current);
|
||||
}
|
||||
|
||||
/* The assembly shim for this function arranges to ignore the return value. */
|
||||
SYSCALL_DEFINE1(rt_sigreturn, struct pt_regs *, regs)
|
||||
{
|
||||
@ -105,7 +111,7 @@ SYSCALL_DEFINE1(rt_sigreturn, struct pt_regs *, regs)
|
||||
return 0;
|
||||
|
||||
badframe:
|
||||
force_sig(SIGSEGV, current);
|
||||
signal_fault("bad sigreturn frame", regs, frame, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -231,7 +237,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
|
||||
return 0;
|
||||
|
||||
give_sigsegv:
|
||||
force_sigsegv(sig, current);
|
||||
signal_fault("bad setup frame", regs, frame, sig);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
@ -245,7 +251,6 @@ static int handle_signal(unsigned long sig, siginfo_t *info,
|
||||
{
|
||||
int ret;
|
||||
|
||||
|
||||
/* Are we from a system call? */
|
||||
if (regs->faultnum == INT_SWINT_1) {
|
||||
/* If so, check system call restarting.. */
|
||||
@ -363,3 +368,118 @@ done:
|
||||
/* Avoid double syscall restart if there are nested signals. */
|
||||
regs->faultnum = INT_SWINT_1_SIGRETURN;
|
||||
}
|
||||
|
||||
int show_unhandled_signals = 1;
|
||||
|
||||
static int __init crashinfo(char *str)
|
||||
{
|
||||
unsigned long val;
|
||||
const char *word;
|
||||
|
||||
if (*str == '\0')
|
||||
val = 2;
|
||||
else if (*str != '=' || strict_strtoul(++str, 0, &val) != 0)
|
||||
return 0;
|
||||
show_unhandled_signals = val;
|
||||
switch (show_unhandled_signals) {
|
||||
case 0:
|
||||
word = "No";
|
||||
break;
|
||||
case 1:
|
||||
word = "One-line";
|
||||
break;
|
||||
default:
|
||||
word = "Detailed";
|
||||
break;
|
||||
}
|
||||
pr_info("%s crash reports will be generated on the console\n", word);
|
||||
return 1;
|
||||
}
|
||||
__setup("crashinfo", crashinfo);
|
||||
|
||||
static void dump_mem(void __user *address)
|
||||
{
|
||||
void __user *addr;
|
||||
enum { region_size = 256, bytes_per_line = 16 };
|
||||
int i, j, k;
|
||||
int found_readable_mem = 0;
|
||||
|
||||
pr_err("\n");
|
||||
if (!access_ok(VERIFY_READ, address, 1)) {
|
||||
pr_err("Not dumping at address 0x%lx (kernel address)\n",
|
||||
(unsigned long)address);
|
||||
return;
|
||||
}
|
||||
|
||||
addr = (void __user *)
|
||||
(((unsigned long)address & -bytes_per_line) - region_size/2);
|
||||
if (addr > address)
|
||||
addr = NULL;
|
||||
for (i = 0; i < region_size;
|
||||
addr += bytes_per_line, i += bytes_per_line) {
|
||||
unsigned char buf[bytes_per_line];
|
||||
char line[100];
|
||||
if (copy_from_user(buf, addr, bytes_per_line))
|
||||
continue;
|
||||
if (!found_readable_mem) {
|
||||
pr_err("Dumping memory around address 0x%lx:\n",
|
||||
(unsigned long)address);
|
||||
found_readable_mem = 1;
|
||||
}
|
||||
j = sprintf(line, REGFMT":", (unsigned long)addr);
|
||||
for (k = 0; k < bytes_per_line; ++k)
|
||||
j += sprintf(&line[j], " %02x", buf[k]);
|
||||
pr_err("%s\n", line);
|
||||
}
|
||||
if (!found_readable_mem)
|
||||
pr_err("No readable memory around address 0x%lx\n",
|
||||
(unsigned long)address);
|
||||
}
|
||||
|
||||
void trace_unhandled_signal(const char *type, struct pt_regs *regs,
|
||||
unsigned long address, int sig)
|
||||
{
|
||||
struct task_struct *tsk = current;
|
||||
|
||||
if (show_unhandled_signals == 0)
|
||||
return;
|
||||
|
||||
/* If the signal is handled, don't show it here. */
|
||||
if (!is_global_init(tsk)) {
|
||||
void __user *handler =
|
||||
tsk->sighand->action[sig-1].sa.sa_handler;
|
||||
if (handler != SIG_IGN && handler != SIG_DFL)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Rate-limit the one-line output, not the detailed output. */
|
||||
if (show_unhandled_signals <= 1 && !printk_ratelimit())
|
||||
return;
|
||||
|
||||
printk("%s%s[%d]: %s at %lx pc "REGFMT" signal %d",
|
||||
task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG,
|
||||
tsk->comm, task_pid_nr(tsk), type, address, regs->pc, sig);
|
||||
|
||||
print_vma_addr(KERN_CONT " in ", regs->pc);
|
||||
|
||||
printk(KERN_CONT "\n");
|
||||
|
||||
if (show_unhandled_signals > 1) {
|
||||
switch (sig) {
|
||||
case SIGILL:
|
||||
case SIGFPE:
|
||||
case SIGSEGV:
|
||||
case SIGBUS:
|
||||
pr_err("User crash: signal %d,"
|
||||
" trap %ld, address 0x%lx\n",
|
||||
sig, regs->faultnum, address);
|
||||
show_regs(regs);
|
||||
dump_mem((void __user *)address);
|
||||
break;
|
||||
default:
|
||||
pr_err("User crash: signal %d, trap %ld\n",
|
||||
sig, regs->faultnum);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -186,6 +186,8 @@ static tile_bundle_bits rewrite_load_store_unaligned(
|
||||
.si_code = SEGV_MAPERR,
|
||||
.si_addr = addr
|
||||
};
|
||||
trace_unhandled_signal("segfault", regs,
|
||||
(unsigned long)addr, SIGSEGV);
|
||||
force_sig_info(info.si_signo, &info, current);
|
||||
return (tile_bundle_bits) 0;
|
||||
}
|
||||
@ -196,6 +198,8 @@ static tile_bundle_bits rewrite_load_store_unaligned(
|
||||
.si_code = BUS_ADRALN,
|
||||
.si_addr = addr
|
||||
};
|
||||
trace_unhandled_signal("unaligned trap", regs,
|
||||
(unsigned long)addr, SIGBUS);
|
||||
force_sig_info(info.si_signo, &info, current);
|
||||
return (tile_bundle_bits) 0;
|
||||
}
|
||||
@ -318,6 +322,14 @@ void single_step_once(struct pt_regs *regs)
|
||||
" .popsection\n"
|
||||
);
|
||||
|
||||
/*
|
||||
* Enable interrupts here to allow touching userspace and the like.
|
||||
* The callers expect this: do_trap() already has interrupts
|
||||
* enabled, and do_work_pending() handles functions that enable
|
||||
* interrupts internally.
|
||||
*/
|
||||
local_irq_enable();
|
||||
|
||||
if (state == NULL) {
|
||||
/* allocate a page of writable, executable memory */
|
||||
state = kmalloc(sizeof(struct single_step_state), GFP_KERNEL);
|
||||
|
@ -36,7 +36,7 @@
|
||||
#define KBT_LOOP 3 /* Backtrace entered a loop */
|
||||
|
||||
/* Is address on the specified kernel stack? */
|
||||
static int in_kernel_stack(struct KBacktraceIterator *kbt, VirtualAddress sp)
|
||||
static int in_kernel_stack(struct KBacktraceIterator *kbt, unsigned long sp)
|
||||
{
|
||||
ulong kstack_base = (ulong) kbt->task->stack;
|
||||
if (kstack_base == 0) /* corrupt task pointer; just follow stack... */
|
||||
@ -45,7 +45,7 @@ static int in_kernel_stack(struct KBacktraceIterator *kbt, VirtualAddress sp)
|
||||
}
|
||||
|
||||
/* Is address valid for reading? */
|
||||
static int valid_address(struct KBacktraceIterator *kbt, VirtualAddress address)
|
||||
static int valid_address(struct KBacktraceIterator *kbt, unsigned long address)
|
||||
{
|
||||
HV_PTE *l1_pgtable = kbt->pgtable;
|
||||
HV_PTE *l2_pgtable;
|
||||
@ -97,7 +97,7 @@ static int valid_address(struct KBacktraceIterator *kbt, VirtualAddress address)
|
||||
}
|
||||
|
||||
/* Callback for backtracer; basically a glorified memcpy */
|
||||
static bool read_memory_func(void *result, VirtualAddress address,
|
||||
static bool read_memory_func(void *result, unsigned long address,
|
||||
unsigned int size, void *vkbt)
|
||||
{
|
||||
int retval;
|
||||
@ -124,7 +124,7 @@ static struct pt_regs *valid_fault_handler(struct KBacktraceIterator* kbt)
|
||||
{
|
||||
const char *fault = NULL; /* happy compiler */
|
||||
char fault_buf[64];
|
||||
VirtualAddress sp = kbt->it.sp;
|
||||
unsigned long sp = kbt->it.sp;
|
||||
struct pt_regs *p;
|
||||
|
||||
if (!in_kernel_stack(kbt, sp))
|
||||
@ -163,7 +163,7 @@ static struct pt_regs *valid_fault_handler(struct KBacktraceIterator* kbt)
|
||||
}
|
||||
|
||||
/* Is the pc pointing to a sigreturn trampoline? */
|
||||
static int is_sigreturn(VirtualAddress pc)
|
||||
static int is_sigreturn(unsigned long pc)
|
||||
{
|
||||
return (pc == VDSO_BASE);
|
||||
}
|
||||
@ -260,7 +260,7 @@ static void validate_stack(struct pt_regs *regs)
|
||||
void KBacktraceIterator_init(struct KBacktraceIterator *kbt,
|
||||
struct task_struct *t, struct pt_regs *regs)
|
||||
{
|
||||
VirtualAddress pc, lr, sp, r52;
|
||||
unsigned long pc, lr, sp, r52;
|
||||
int is_current;
|
||||
|
||||
/*
|
||||
@ -331,7 +331,7 @@ EXPORT_SYMBOL(KBacktraceIterator_end);
|
||||
|
||||
void KBacktraceIterator_next(struct KBacktraceIterator *kbt)
|
||||
{
|
||||
VirtualAddress old_pc = kbt->it.pc, old_sp = kbt->it.sp;
|
||||
unsigned long old_pc = kbt->it.pc, old_sp = kbt->it.sp;
|
||||
kbt->new_context = 0;
|
||||
if (!backtrace_next(&kbt->it) && !KBacktraceIterator_restart(kbt)) {
|
||||
kbt->end = KBT_DONE;
|
||||
|
@ -56,13 +56,6 @@ ssize_t sys32_readahead(int fd, u32 offset_lo, u32 offset_hi, u32 count)
|
||||
return sys_readahead(fd, ((loff_t)offset_hi << 32) | offset_lo, count);
|
||||
}
|
||||
|
||||
long sys32_fadvise64(int fd, u32 offset_lo, u32 offset_hi,
|
||||
u32 len, int advice)
|
||||
{
|
||||
return sys_fadvise64_64(fd, ((loff_t)offset_hi << 32) | offset_lo,
|
||||
len, advice);
|
||||
}
|
||||
|
||||
int sys32_fadvise64_64(int fd, u32 offset_lo, u32 offset_hi,
|
||||
u32 len_lo, u32 len_hi, int advice)
|
||||
{
|
||||
@ -103,10 +96,8 @@ SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len,
|
||||
|
||||
#ifndef __tilegx__
|
||||
/* See comments at the top of the file. */
|
||||
#define sys_fadvise64 sys32_fadvise64
|
||||
#define sys_fadvise64_64 sys32_fadvise64_64
|
||||
#define sys_readahead sys32_readahead
|
||||
#define sys_sync_file_range sys_sync_file_range2
|
||||
#endif
|
||||
|
||||
/* Call the trampolines to manage pt_regs where necessary. */
|
||||
|
@ -2413,12 +2413,13 @@ const struct tile_operand tile_operands[43] =
|
||||
|
||||
|
||||
|
||||
/* Given a set of bundle bits and the lookup FSM for a specific pipe,
|
||||
* returns which instruction the bundle contains in that pipe.
|
||||
/* Given a set of bundle bits and a specific pipe, returns which
|
||||
* instruction the bundle contains in that pipe.
|
||||
*/
|
||||
static const struct tile_opcode *
|
||||
find_opcode(tile_bundle_bits bits, const unsigned short *table)
|
||||
const struct tile_opcode *
|
||||
find_opcode(tile_bundle_bits bits, tile_pipeline pipe)
|
||||
{
|
||||
const unsigned short *table = tile_bundle_decoder_fsms[pipe];
|
||||
int index = 0;
|
||||
|
||||
while (1)
|
||||
@ -2465,7 +2466,7 @@ parse_insn_tile(tile_bundle_bits bits,
|
||||
int i;
|
||||
|
||||
d = &decoded[num_instructions++];
|
||||
opc = find_opcode (bits, tile_bundle_decoder_fsms[pipe]);
|
||||
opc = find_opcode (bits, (tile_pipeline)pipe);
|
||||
d->opcode = opc;
|
||||
|
||||
/* Decode each operand, sign extending, etc. as appropriate. */
|
||||
|
2200
arch/tile/kernel/tile-desc_64.c
Normal file
2200
arch/tile/kernel/tile-desc_64.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -22,6 +22,7 @@
|
||||
#include <linux/sched.h>
|
||||
#include <linux/smp.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/module.h>
|
||||
#include <asm/irq_regs.h>
|
||||
#include <asm/traps.h>
|
||||
#include <hv/hypervisor.h>
|
||||
@ -56,6 +57,7 @@ cycles_t get_cycles(void)
|
||||
|
||||
return (((cycles_t)high) << 32) | low;
|
||||
}
|
||||
EXPORT_SYMBOL(get_cycles);
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -34,13 +34,13 @@ void flush_tlb_mm(struct mm_struct *mm)
|
||||
{
|
||||
HV_Remote_ASID asids[NR_CPUS];
|
||||
int i = 0, cpu;
|
||||
for_each_cpu(cpu, &mm->cpu_vm_mask) {
|
||||
for_each_cpu(cpu, mm_cpumask(mm)) {
|
||||
HV_Remote_ASID *asid = &asids[i++];
|
||||
asid->y = cpu / smp_topology.width;
|
||||
asid->x = cpu % smp_topology.width;
|
||||
asid->asid = per_cpu(current_asid, cpu);
|
||||
}
|
||||
flush_remote(0, HV_FLUSH_EVICT_L1I, &mm->cpu_vm_mask,
|
||||
flush_remote(0, HV_FLUSH_EVICT_L1I, mm_cpumask(mm),
|
||||
0, 0, 0, NULL, asids, i);
|
||||
}
|
||||
|
||||
@ -54,8 +54,8 @@ void flush_tlb_page_mm(const struct vm_area_struct *vma, struct mm_struct *mm,
|
||||
{
|
||||
unsigned long size = hv_page_size(vma);
|
||||
int cache = (vma->vm_flags & VM_EXEC) ? HV_FLUSH_EVICT_L1I : 0;
|
||||
flush_remote(0, cache, &mm->cpu_vm_mask,
|
||||
va, size, size, &mm->cpu_vm_mask, NULL, 0);
|
||||
flush_remote(0, cache, mm_cpumask(mm),
|
||||
va, size, size, mm_cpumask(mm), NULL, 0);
|
||||
}
|
||||
|
||||
void flush_tlb_page(const struct vm_area_struct *vma, unsigned long va)
|
||||
@ -70,8 +70,8 @@ void flush_tlb_range(const struct vm_area_struct *vma,
|
||||
unsigned long size = hv_page_size(vma);
|
||||
struct mm_struct *mm = vma->vm_mm;
|
||||
int cache = (vma->vm_flags & VM_EXEC) ? HV_FLUSH_EVICT_L1I : 0;
|
||||
flush_remote(0, cache, &mm->cpu_vm_mask, start, end - start, size,
|
||||
&mm->cpu_vm_mask, NULL, 0);
|
||||
flush_remote(0, cache, mm_cpumask(mm), start, end - start, size,
|
||||
mm_cpumask(mm), NULL, 0);
|
||||
}
|
||||
|
||||
void flush_tlb_all(void)
|
||||
|
@ -308,6 +308,7 @@ void __kprobes do_trap(struct pt_regs *regs, int fault_num,
|
||||
info.si_addr = (void __user *)address;
|
||||
if (signo == SIGILL)
|
||||
info.si_trapno = fault_num;
|
||||
trace_unhandled_signal("trap", regs, address, signo);
|
||||
force_sig_info(signo, &info, current);
|
||||
}
|
||||
|
||||
|
@ -59,7 +59,7 @@
|
||||
* bad kernel addresses).
|
||||
*
|
||||
* Note that if the value we would store is the same as what we
|
||||
* loaded, we bypass the load. Other platforms with true atomics can
|
||||
* loaded, we bypass the store. Other platforms with true atomics can
|
||||
* make the guarantee that a non-atomic __clear_bit(), for example,
|
||||
* can safely race with an atomic test_and_set_bit(); this example is
|
||||
* from bit_spinlock.h in slub_lock() / slub_unlock(). We can't do
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include <asm/page.h>
|
||||
#include <asm/cacheflush.h>
|
||||
#include <arch/icache.h>
|
||||
#include <arch/spr_def.h>
|
||||
|
||||
|
||||
void __flush_icache_range(unsigned long start, unsigned long end)
|
||||
@ -39,6 +40,18 @@ void finv_buffer_remote(void *buffer, size_t size, int hfh)
|
||||
char *p, *base;
|
||||
size_t step_size, load_count;
|
||||
const unsigned long STRIPE_WIDTH = 8192;
|
||||
#ifdef __tilegx__
|
||||
/*
|
||||
* On TILE-Gx, we must disable the dstream prefetcher before doing
|
||||
* a cache flush; otherwise, we could end up with data in the cache
|
||||
* that we don't want there. Note that normally we'd do an mf
|
||||
* after the SPR write to disabling the prefetcher, but we do one
|
||||
* below, before any further loads, so there's no need to do it
|
||||
* here.
|
||||
*/
|
||||
uint_reg_t old_dstream_pf = __insn_mfspr(SPR_DSTREAM_PF);
|
||||
__insn_mtspr(SPR_DSTREAM_PF, 0);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Flush and invalidate the buffer out of the local L1/L2
|
||||
@ -122,4 +135,9 @@ void finv_buffer_remote(void *buffer, size_t size, int hfh)
|
||||
|
||||
/* Wait for the load+inv's (and thus finvs) to have completed. */
|
||||
__insn_mf();
|
||||
|
||||
#ifdef __tilegx__
|
||||
/* Reenable the prefetcher. */
|
||||
__insn_mtspr(SPR_DSTREAM_PF, old_dstream_pf);
|
||||
#endif
|
||||
}
|
||||
|
71
arch/tile/lib/memchr_64.c
Normal file
71
arch/tile/lib/memchr_64.c
Normal file
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright 2011 Tilera Corporation. All Rights Reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation, version 2.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
|
||||
* NON INFRINGEMENT. See the GNU General Public License for
|
||||
* more details.
|
||||
*/
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
void *memchr(const void *s, int c, size_t n)
|
||||
{
|
||||
const uint64_t *last_word_ptr;
|
||||
const uint64_t *p;
|
||||
const char *last_byte_ptr;
|
||||
uintptr_t s_int;
|
||||
uint64_t goal, before_mask, v, bits;
|
||||
char *ret;
|
||||
|
||||
if (__builtin_expect(n == 0, 0)) {
|
||||
/* Don't dereference any memory if the array is empty. */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Get an aligned pointer. */
|
||||
s_int = (uintptr_t) s;
|
||||
p = (const uint64_t *)(s_int & -8);
|
||||
|
||||
/* Create eight copies of the byte for which we are looking. */
|
||||
goal = 0x0101010101010101ULL * (uint8_t) c;
|
||||
|
||||
/* Read the first word, but munge it so that bytes before the array
|
||||
* will not match goal.
|
||||
*
|
||||
* Note that this shift count expression works because we know
|
||||
* shift counts are taken mod 64.
|
||||
*/
|
||||
before_mask = (1ULL << (s_int << 3)) - 1;
|
||||
v = (*p | before_mask) ^ (goal & before_mask);
|
||||
|
||||
/* Compute the address of the last byte. */
|
||||
last_byte_ptr = (const char *)s + n - 1;
|
||||
|
||||
/* Compute the address of the word containing the last byte. */
|
||||
last_word_ptr = (const uint64_t *)((uintptr_t) last_byte_ptr & -8);
|
||||
|
||||
while ((bits = __insn_v1cmpeq(v, goal)) == 0) {
|
||||
if (__builtin_expect(p == last_word_ptr, 0)) {
|
||||
/* We already read the last word in the array,
|
||||
* so give up.
|
||||
*/
|
||||
return NULL;
|
||||
}
|
||||
v = *++p;
|
||||
}
|
||||
|
||||
/* We found a match, but it might be in a byte past the end
|
||||
* of the array.
|
||||
*/
|
||||
ret = ((char *)p) + (__insn_ctz(bits) >> 3);
|
||||
return (ret <= last_byte_ptr) ? ret : NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(memchr);
|
220
arch/tile/lib/memcpy_64.c
Normal file
220
arch/tile/lib/memcpy_64.c
Normal file
@ -0,0 +1,220 @@
|
||||
/*
|
||||
* Copyright 2011 Tilera Corporation. All Rights Reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation, version 2.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
|
||||
* NON INFRINGEMENT. See the GNU General Public License for
|
||||
* more details.
|
||||
*/
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/module.h>
|
||||
#define __memcpy memcpy
|
||||
/* EXPORT_SYMBOL() is in arch/tile/lib/exports.c since this should be asm. */
|
||||
|
||||
/* Must be 8 bytes in size. */
|
||||
#define word_t uint64_t
|
||||
|
||||
#if CHIP_L2_LINE_SIZE() != 64 && CHIP_L2_LINE_SIZE() != 128
|
||||
#error "Assumes 64 or 128 byte line size"
|
||||
#endif
|
||||
|
||||
/* How many cache lines ahead should we prefetch? */
|
||||
#define PREFETCH_LINES_AHEAD 3
|
||||
|
||||
/*
|
||||
* Provide "base versions" of load and store for the normal code path.
|
||||
* The kernel provides other versions for userspace copies.
|
||||
*/
|
||||
#define ST(p, v) (*(p) = (v))
|
||||
#define LD(p) (*(p))
|
||||
|
||||
#ifndef USERCOPY_FUNC
|
||||
#define ST1 ST
|
||||
#define ST2 ST
|
||||
#define ST4 ST
|
||||
#define ST8 ST
|
||||
#define LD1 LD
|
||||
#define LD2 LD
|
||||
#define LD4 LD
|
||||
#define LD8 LD
|
||||
#define RETVAL dstv
|
||||
void *memcpy(void *__restrict dstv, const void *__restrict srcv, size_t n)
|
||||
#else
|
||||
/*
|
||||
* Special kernel version will provide implementation of the LDn/STn
|
||||
* macros to return a count of uncopied bytes due to mm fault.
|
||||
*/
|
||||
#define RETVAL 0
|
||||
int USERCOPY_FUNC(void *__restrict dstv, const void *__restrict srcv, size_t n)
|
||||
#endif
|
||||
{
|
||||
char *__restrict dst1 = (char *)dstv;
|
||||
const char *__restrict src1 = (const char *)srcv;
|
||||
const char *__restrict src1_end;
|
||||
const char *__restrict prefetch;
|
||||
word_t *__restrict dst8; /* 8-byte pointer to destination memory. */
|
||||
word_t final; /* Final bytes to write to trailing word, if any */
|
||||
long i;
|
||||
|
||||
if (n < 16) {
|
||||
for (; n; n--)
|
||||
ST1(dst1++, LD1(src1++));
|
||||
return RETVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Locate the end of source memory we will copy. Don't
|
||||
* prefetch past this.
|
||||
*/
|
||||
src1_end = src1 + n - 1;
|
||||
|
||||
/* Prefetch ahead a few cache lines, but not past the end. */
|
||||
prefetch = src1;
|
||||
for (i = 0; i < PREFETCH_LINES_AHEAD; i++) {
|
||||
__insn_prefetch(prefetch);
|
||||
prefetch += CHIP_L2_LINE_SIZE();
|
||||
prefetch = (prefetch > src1_end) ? prefetch : src1;
|
||||
}
|
||||
|
||||
/* Copy bytes until dst is word-aligned. */
|
||||
for (; (uintptr_t)dst1 & (sizeof(word_t) - 1); n--)
|
||||
ST1(dst1++, LD1(src1++));
|
||||
|
||||
/* 8-byte pointer to destination memory. */
|
||||
dst8 = (word_t *)dst1;
|
||||
|
||||
if (__builtin_expect((uintptr_t)src1 & (sizeof(word_t) - 1), 0)) {
|
||||
/*
|
||||
* Misaligned copy. Copy 8 bytes at a time, but don't
|
||||
* bother with other fanciness.
|
||||
*
|
||||
* TODO: Consider prefetching and using wh64 as well.
|
||||
*/
|
||||
|
||||
/* Create an aligned src8. */
|
||||
const word_t *__restrict src8 =
|
||||
(const word_t *)((uintptr_t)src1 & -sizeof(word_t));
|
||||
word_t b;
|
||||
|
||||
word_t a = LD8(src8++);
|
||||
for (; n >= sizeof(word_t); n -= sizeof(word_t)) {
|
||||
b = LD8(src8++);
|
||||
a = __insn_dblalign(a, b, src1);
|
||||
ST8(dst8++, a);
|
||||
a = b;
|
||||
}
|
||||
|
||||
if (n == 0)
|
||||
return RETVAL;
|
||||
|
||||
b = ((const char *)src8 <= src1_end) ? *src8 : 0;
|
||||
|
||||
/*
|
||||
* Final source bytes to write to trailing partial
|
||||
* word, if any.
|
||||
*/
|
||||
final = __insn_dblalign(a, b, src1);
|
||||
} else {
|
||||
/* Aligned copy. */
|
||||
|
||||
const word_t* __restrict src8 = (const word_t *)src1;
|
||||
|
||||
/* src8 and dst8 are both word-aligned. */
|
||||
if (n >= CHIP_L2_LINE_SIZE()) {
|
||||
/* Copy until 'dst' is cache-line-aligned. */
|
||||
for (; (uintptr_t)dst8 & (CHIP_L2_LINE_SIZE() - 1);
|
||||
n -= sizeof(word_t))
|
||||
ST8(dst8++, LD8(src8++));
|
||||
|
||||
for (; n >= CHIP_L2_LINE_SIZE(); ) {
|
||||
__insn_wh64(dst8);
|
||||
|
||||
/*
|
||||
* Prefetch and advance to next line
|
||||
* to prefetch, but don't go past the end
|
||||
*/
|
||||
__insn_prefetch(prefetch);
|
||||
prefetch += CHIP_L2_LINE_SIZE();
|
||||
prefetch = (prefetch > src1_end) ? prefetch :
|
||||
(const char *)src8;
|
||||
|
||||
/*
|
||||
* Copy an entire cache line. Manually
|
||||
* unrolled to avoid idiosyncracies of
|
||||
* compiler unrolling.
|
||||
*/
|
||||
#define COPY_WORD(offset) ({ ST8(dst8+offset, LD8(src8+offset)); n -= 8; })
|
||||
COPY_WORD(0);
|
||||
COPY_WORD(1);
|
||||
COPY_WORD(2);
|
||||
COPY_WORD(3);
|
||||
COPY_WORD(4);
|
||||
COPY_WORD(5);
|
||||
COPY_WORD(6);
|
||||
COPY_WORD(7);
|
||||
#if CHIP_L2_LINE_SIZE() == 128
|
||||
COPY_WORD(8);
|
||||
COPY_WORD(9);
|
||||
COPY_WORD(10);
|
||||
COPY_WORD(11);
|
||||
COPY_WORD(12);
|
||||
COPY_WORD(13);
|
||||
COPY_WORD(14);
|
||||
COPY_WORD(15);
|
||||
#elif CHIP_L2_LINE_SIZE() != 64
|
||||
# error Fix code that assumes particular L2 cache line sizes
|
||||
#endif
|
||||
|
||||
dst8 += CHIP_L2_LINE_SIZE() / sizeof(word_t);
|
||||
src8 += CHIP_L2_LINE_SIZE() / sizeof(word_t);
|
||||
}
|
||||
}
|
||||
|
||||
for (; n >= sizeof(word_t); n -= sizeof(word_t))
|
||||
ST8(dst8++, LD8(src8++));
|
||||
|
||||
if (__builtin_expect(n == 0, 1))
|
||||
return RETVAL;
|
||||
|
||||
final = LD8(src8);
|
||||
}
|
||||
|
||||
/* n != 0 if we get here. Write out any trailing bytes. */
|
||||
dst1 = (char *)dst8;
|
||||
if (n & 4) {
|
||||
ST4((uint32_t *)dst1, final);
|
||||
dst1 += 4;
|
||||
final >>= 32;
|
||||
n &= 3;
|
||||
}
|
||||
if (n & 2) {
|
||||
ST2((uint16_t *)dst1, final);
|
||||
dst1 += 2;
|
||||
final >>= 16;
|
||||
n &= 1;
|
||||
}
|
||||
if (n)
|
||||
ST1((uint8_t *)dst1, final);
|
||||
|
||||
return RETVAL;
|
||||
}
|
||||
|
||||
|
||||
#ifdef USERCOPY_FUNC
|
||||
#undef ST1
|
||||
#undef ST2
|
||||
#undef ST4
|
||||
#undef ST8
|
||||
#undef LD1
|
||||
#undef LD2
|
||||
#undef LD4
|
||||
#undef LD8
|
||||
#undef USERCOPY_FUNC
|
||||
#endif
|
86
arch/tile/lib/memcpy_user_64.c
Normal file
86
arch/tile/lib/memcpy_user_64.c
Normal file
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright 2011 Tilera Corporation. All Rights Reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation, version 2.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
|
||||
* NON INFRINGEMENT. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* Do memcpy(), but trap and return "n" when a load or store faults.
|
||||
*
|
||||
* Note: this idiom only works when memcpy() compiles to a leaf function.
|
||||
* If "sp" is updated during memcpy, the "jrp lr" will be incorrect.
|
||||
*
|
||||
* Also note that we are capturing "n" from the containing scope here.
|
||||
*/
|
||||
|
||||
#define _ST(p, inst, v) \
|
||||
({ \
|
||||
asm("1: " #inst " %0, %1;" \
|
||||
".pushsection .coldtext.memcpy,\"ax\";" \
|
||||
"2: { move r0, %2; jrp lr };" \
|
||||
".section __ex_table,\"a\";" \
|
||||
".quad 1b, 2b;" \
|
||||
".popsection" \
|
||||
: "=m" (*(p)) : "r" (v), "r" (n)); \
|
||||
})
|
||||
|
||||
#define _LD(p, inst) \
|
||||
({ \
|
||||
unsigned long __v; \
|
||||
asm("1: " #inst " %0, %1;" \
|
||||
".pushsection .coldtext.memcpy,\"ax\";" \
|
||||
"2: { move r0, %2; jrp lr };" \
|
||||
".section __ex_table,\"a\";" \
|
||||
".quad 1b, 2b;" \
|
||||
".popsection" \
|
||||
: "=r" (__v) : "m" (*(p)), "r" (n)); \
|
||||
__v; \
|
||||
})
|
||||
|
||||
#define USERCOPY_FUNC __copy_to_user_inatomic
|
||||
#define ST1(p, v) _ST((p), st1, (v))
|
||||
#define ST2(p, v) _ST((p), st2, (v))
|
||||
#define ST4(p, v) _ST((p), st4, (v))
|
||||
#define ST8(p, v) _ST((p), st, (v))
|
||||
#define LD1 LD
|
||||
#define LD2 LD
|
||||
#define LD4 LD
|
||||
#define LD8 LD
|
||||
#include "memcpy_64.c"
|
||||
|
||||
#define USERCOPY_FUNC __copy_from_user_inatomic
|
||||
#define ST1 ST
|
||||
#define ST2 ST
|
||||
#define ST4 ST
|
||||
#define ST8 ST
|
||||
#define LD1(p) _LD((p), ld1u)
|
||||
#define LD2(p) _LD((p), ld2u)
|
||||
#define LD4(p) _LD((p), ld4u)
|
||||
#define LD8(p) _LD((p), ld)
|
||||
#include "memcpy_64.c"
|
||||
|
||||
#define USERCOPY_FUNC __copy_in_user_inatomic
|
||||
#define ST1(p, v) _ST((p), st1, (v))
|
||||
#define ST2(p, v) _ST((p), st2, (v))
|
||||
#define ST4(p, v) _ST((p), st4, (v))
|
||||
#define ST8(p, v) _ST((p), st, (v))
|
||||
#define LD1(p) _LD((p), ld1u)
|
||||
#define LD2(p) _LD((p), ld2u)
|
||||
#define LD4(p) _LD((p), ld4u)
|
||||
#define LD8(p) _LD((p), ld)
|
||||
#include "memcpy_64.c"
|
||||
|
||||
unsigned long __copy_from_user_zeroing(void *to, const void __user *from,
|
||||
unsigned long n)
|
||||
{
|
||||
unsigned long rc = __copy_from_user_inatomic(to, from, n);
|
||||
if (unlikely(rc))
|
||||
memset(to + n - rc, 0, rc);
|
||||
return rc;
|
||||
}
|
145
arch/tile/lib/memset_64.c
Normal file
145
arch/tile/lib/memset_64.c
Normal file
@ -0,0 +1,145 @@
|
||||
/*
|
||||
* Copyright 2011 Tilera Corporation. All Rights Reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation, version 2.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
|
||||
* NON INFRINGEMENT. See the GNU General Public License for
|
||||
* more details.
|
||||
*/
|
||||
|
||||
#include <arch/chip.h>
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#undef memset
|
||||
|
||||
void *memset(void *s, int c, size_t n)
|
||||
{
|
||||
uint64_t *out64;
|
||||
int n64, to_align64;
|
||||
uint64_t v64;
|
||||
uint8_t *out8 = s;
|
||||
|
||||
/* Experimentation shows that a trivial tight loop is a win up until
|
||||
* around a size of 20, where writing a word at a time starts to win.
|
||||
*/
|
||||
#define BYTE_CUTOFF 20
|
||||
|
||||
#if BYTE_CUTOFF < 7
|
||||
/* This must be at least at least this big, or some code later
|
||||
* on doesn't work.
|
||||
*/
|
||||
#error "BYTE_CUTOFF is too small"
|
||||
#endif
|
||||
|
||||
if (n < BYTE_CUTOFF) {
|
||||
/* Strangely, this turns out to be the tightest way to
|
||||
* write this loop.
|
||||
*/
|
||||
if (n != 0) {
|
||||
do {
|
||||
/* Strangely, combining these into one line
|
||||
* performs worse.
|
||||
*/
|
||||
*out8 = c;
|
||||
out8++;
|
||||
} while (--n != 0);
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
/* Align 'out8'. We know n >= 7 so this won't write past the end. */
|
||||
while (((uintptr_t) out8 & 7) != 0) {
|
||||
*out8++ = c;
|
||||
--n;
|
||||
}
|
||||
|
||||
/* Align 'n'. */
|
||||
while (n & 7)
|
||||
out8[--n] = c;
|
||||
|
||||
out64 = (uint64_t *) out8;
|
||||
n64 = n >> 3;
|
||||
|
||||
/* Tile input byte out to 64 bits. */
|
||||
/* KLUDGE */
|
||||
v64 = 0x0101010101010101ULL * (uint8_t)c;
|
||||
|
||||
/* This must be at least 8 or the following loop doesn't work. */
|
||||
#define CACHE_LINE_SIZE_IN_DOUBLEWORDS (CHIP_L2_LINE_SIZE() / 8)
|
||||
|
||||
/* Determine how many words we need to emit before the 'out32'
|
||||
* pointer becomes aligned modulo the cache line size.
|
||||
*/
|
||||
to_align64 = (-((uintptr_t)out64 >> 3)) &
|
||||
(CACHE_LINE_SIZE_IN_DOUBLEWORDS - 1);
|
||||
|
||||
/* Only bother aligning and using wh64 if there is at least
|
||||
* one full cache line to process. This check also prevents
|
||||
* overrunning the end of the buffer with alignment words.
|
||||
*/
|
||||
if (to_align64 <= n64 - CACHE_LINE_SIZE_IN_DOUBLEWORDS) {
|
||||
int lines_left;
|
||||
|
||||
/* Align out64 mod the cache line size so we can use wh64. */
|
||||
n64 -= to_align64;
|
||||
for (; to_align64 != 0; to_align64--) {
|
||||
*out64 = v64;
|
||||
out64++;
|
||||
}
|
||||
|
||||
/* Use unsigned divide to turn this into a right shift. */
|
||||
lines_left = (unsigned)n64 / CACHE_LINE_SIZE_IN_DOUBLEWORDS;
|
||||
|
||||
do {
|
||||
/* Only wh64 a few lines at a time, so we don't
|
||||
* exceed the maximum number of victim lines.
|
||||
*/
|
||||
int x = ((lines_left < CHIP_MAX_OUTSTANDING_VICTIMS())
|
||||
? lines_left
|
||||
: CHIP_MAX_OUTSTANDING_VICTIMS());
|
||||
uint64_t *wh = out64;
|
||||
int i = x;
|
||||
int j;
|
||||
|
||||
lines_left -= x;
|
||||
|
||||
do {
|
||||
__insn_wh64(wh);
|
||||
wh += CACHE_LINE_SIZE_IN_DOUBLEWORDS;
|
||||
} while (--i);
|
||||
|
||||
for (j = x * (CACHE_LINE_SIZE_IN_DOUBLEWORDS / 4);
|
||||
j != 0; j--) {
|
||||
*out64++ = v64;
|
||||
*out64++ = v64;
|
||||
*out64++ = v64;
|
||||
*out64++ = v64;
|
||||
}
|
||||
} while (lines_left != 0);
|
||||
|
||||
/* We processed all full lines above, so only this many
|
||||
* words remain to be processed.
|
||||
*/
|
||||
n64 &= CACHE_LINE_SIZE_IN_DOUBLEWORDS - 1;
|
||||
}
|
||||
|
||||
/* Now handle any leftover values. */
|
||||
if (n64 != 0) {
|
||||
do {
|
||||
*out64 = v64;
|
||||
out64++;
|
||||
} while (--n64 != 0);
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
EXPORT_SYMBOL(memset);
|
104
arch/tile/lib/spinlock_64.c
Normal file
104
arch/tile/lib/spinlock_64.c
Normal file
@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright 2011 Tilera Corporation. All Rights Reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation, version 2.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
|
||||
* NON INFRINGEMENT. See the GNU General Public License for
|
||||
* more details.
|
||||
*/
|
||||
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/module.h>
|
||||
#include <asm/processor.h>
|
||||
|
||||
#include "spinlock_common.h"
|
||||
|
||||
/*
|
||||
* Read the spinlock value without allocating in our cache and without
|
||||
* causing an invalidation to another cpu with a copy of the cacheline.
|
||||
* This is important when we are spinning waiting for the lock.
|
||||
*/
|
||||
static inline u32 arch_spin_read_noalloc(void *lock)
|
||||
{
|
||||
return atomic_cmpxchg((atomic_t *)lock, -1, -1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait until the high bits (current) match my ticket.
|
||||
* If we notice the overflow bit set on entry, we clear it.
|
||||
*/
|
||||
void arch_spin_lock_slow(arch_spinlock_t *lock, u32 my_ticket)
|
||||
{
|
||||
if (unlikely(my_ticket & __ARCH_SPIN_NEXT_OVERFLOW)) {
|
||||
__insn_fetchand4(&lock->lock, ~__ARCH_SPIN_NEXT_OVERFLOW);
|
||||
my_ticket &= ~__ARCH_SPIN_NEXT_OVERFLOW;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
u32 val = arch_spin_read_noalloc(lock);
|
||||
u32 delta = my_ticket - arch_spin_current(val);
|
||||
if (delta == 0)
|
||||
return;
|
||||
relax((128 / CYCLES_PER_RELAX_LOOP) * delta);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(arch_spin_lock_slow);
|
||||
|
||||
/*
|
||||
* Check the lock to see if it is plausible, and try to get it with cmpxchg().
|
||||
*/
|
||||
int arch_spin_trylock(arch_spinlock_t *lock)
|
||||
{
|
||||
u32 val = arch_spin_read_noalloc(lock);
|
||||
if (unlikely(arch_spin_current(val) != arch_spin_next(val)))
|
||||
return 0;
|
||||
return cmpxchg(&lock->lock, val, (val + 1) & ~__ARCH_SPIN_NEXT_OVERFLOW)
|
||||
== val;
|
||||
}
|
||||
EXPORT_SYMBOL(arch_spin_trylock);
|
||||
|
||||
void arch_spin_unlock_wait(arch_spinlock_t *lock)
|
||||
{
|
||||
u32 iterations = 0;
|
||||
while (arch_spin_is_locked(lock))
|
||||
delay_backoff(iterations++);
|
||||
}
|
||||
EXPORT_SYMBOL(arch_spin_unlock_wait);
|
||||
|
||||
/*
|
||||
* If the read lock fails due to a writer, we retry periodically
|
||||
* until the value is positive and we write our incremented reader count.
|
||||
*/
|
||||
void __read_lock_failed(arch_rwlock_t *rw)
|
||||
{
|
||||
u32 val;
|
||||
int iterations = 0;
|
||||
do {
|
||||
delay_backoff(iterations++);
|
||||
val = __insn_fetchaddgez4(&rw->lock, 1);
|
||||
} while (unlikely(arch_write_val_locked(val)));
|
||||
}
|
||||
EXPORT_SYMBOL(__read_lock_failed);
|
||||
|
||||
/*
|
||||
* If we failed because there were readers, clear the "writer" bit
|
||||
* so we don't block additional readers. Otherwise, there was another
|
||||
* writer anyway, so our "fetchor" made no difference. Then wait,
|
||||
* issuing periodic fetchor instructions, till we get the lock.
|
||||
*/
|
||||
void __write_lock_failed(arch_rwlock_t *rw, u32 val)
|
||||
{
|
||||
int iterations = 0;
|
||||
do {
|
||||
if (!arch_write_val_locked(val))
|
||||
val = __insn_fetchand4(&rw->lock, ~__WRITE_LOCK_BIT);
|
||||
delay_backoff(iterations++);
|
||||
val = __insn_fetchor4(&rw->lock, __WRITE_LOCK_BIT);
|
||||
} while (val != 0);
|
||||
}
|
||||
EXPORT_SYMBOL(__write_lock_failed);
|
67
arch/tile/lib/strchr_64.c
Normal file
67
arch/tile/lib/strchr_64.c
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright 2011 Tilera Corporation. All Rights Reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation, version 2.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
|
||||
* NON INFRINGEMENT. See the GNU General Public License for
|
||||
* more details.
|
||||
*/
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#undef strchr
|
||||
|
||||
char *strchr(const char *s, int c)
|
||||
{
|
||||
int z, g;
|
||||
|
||||
/* Get an aligned pointer. */
|
||||
const uintptr_t s_int = (uintptr_t) s;
|
||||
const uint64_t *p = (const uint64_t *)(s_int & -8);
|
||||
|
||||
/* Create eight copies of the byte for which we are looking. */
|
||||
const uint64_t goal = 0x0101010101010101ULL * (uint8_t) c;
|
||||
|
||||
/* Read the first aligned word, but force bytes before the string to
|
||||
* match neither zero nor goal (we make sure the high bit of each
|
||||
* byte is 1, and the low 7 bits are all the opposite of the goal
|
||||
* byte).
|
||||
*
|
||||
* Note that this shift count expression works because we know shift
|
||||
* counts are taken mod 64.
|
||||
*/
|
||||
const uint64_t before_mask = (1ULL << (s_int << 3)) - 1;
|
||||
uint64_t v = (*p | before_mask) ^
|
||||
(goal & __insn_v1shrsi(before_mask, 1));
|
||||
|
||||
uint64_t zero_matches, goal_matches;
|
||||
while (1) {
|
||||
/* Look for a terminating '\0'. */
|
||||
zero_matches = __insn_v1cmpeqi(v, 0);
|
||||
|
||||
/* Look for the goal byte. */
|
||||
goal_matches = __insn_v1cmpeq(v, goal);
|
||||
|
||||
if (__builtin_expect((zero_matches | goal_matches) != 0, 0))
|
||||
break;
|
||||
|
||||
v = *++p;
|
||||
}
|
||||
|
||||
z = __insn_ctz(zero_matches);
|
||||
g = __insn_ctz(goal_matches);
|
||||
|
||||
/* If we found c before '\0' we got a match. Note that if c == '\0'
|
||||
* then g == z, and we correctly return the address of the '\0'
|
||||
* rather than NULL.
|
||||
*/
|
||||
return (g <= z) ? ((char *)p) + (g >> 3) : NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(strchr);
|
38
arch/tile/lib/strlen_64.c
Normal file
38
arch/tile/lib/strlen_64.c
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2011 Tilera Corporation. All Rights Reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation, version 2.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
|
||||
* NON INFRINGEMENT. See the GNU General Public License for
|
||||
* more details.
|
||||
*/
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#undef strlen
|
||||
|
||||
size_t strlen(const char *s)
|
||||
{
|
||||
/* Get an aligned pointer. */
|
||||
const uintptr_t s_int = (uintptr_t) s;
|
||||
const uint64_t *p = (const uint64_t *)(s_int & -8);
|
||||
|
||||
/* Read the first word, but force bytes before the string to be nonzero.
|
||||
* This expression works because we know shift counts are taken mod 64.
|
||||
*/
|
||||
uint64_t v = *p | ((1ULL << (s_int << 3)) - 1);
|
||||
|
||||
uint64_t bits;
|
||||
while ((bits = __insn_v1cmpeqi(v, 0)) == 0)
|
||||
v = *++p;
|
||||
|
||||
return ((const char *)p) + (__insn_ctz(bits) >> 3) - s;
|
||||
}
|
||||
EXPORT_SYMBOL(strlen);
|
196
arch/tile/lib/usercopy_64.S
Normal file
196
arch/tile/lib/usercopy_64.S
Normal file
@ -0,0 +1,196 @@
|
||||
/*
|
||||
* Copyright 2011 Tilera Corporation. All Rights Reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation, version 2.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
|
||||
* NON INFRINGEMENT. See the GNU General Public License for
|
||||
* more details.
|
||||
*/
|
||||
|
||||
#include <linux/linkage.h>
|
||||
#include <asm/errno.h>
|
||||
#include <asm/cache.h>
|
||||
#include <arch/chip.h>
|
||||
|
||||
/* Access user memory, but use MMU to avoid propagating kernel exceptions. */
|
||||
|
||||
.pushsection .fixup,"ax"
|
||||
|
||||
get_user_fault:
|
||||
{ movei r1, -EFAULT; move r0, zero }
|
||||
jrp lr
|
||||
ENDPROC(get_user_fault)
|
||||
|
||||
put_user_fault:
|
||||
{ movei r0, -EFAULT; jrp lr }
|
||||
ENDPROC(put_user_fault)
|
||||
|
||||
.popsection
|
||||
|
||||
/*
|
||||
* __get_user_N functions take a pointer in r0, and return 0 in r1
|
||||
* on success, with the value in r0; or else -EFAULT in r1.
|
||||
*/
|
||||
#define __get_user_N(bytes, LOAD) \
|
||||
STD_ENTRY(__get_user_##bytes); \
|
||||
1: { LOAD r0, r0; move r1, zero }; \
|
||||
jrp lr; \
|
||||
STD_ENDPROC(__get_user_##bytes); \
|
||||
.pushsection __ex_table,"a"; \
|
||||
.quad 1b, get_user_fault; \
|
||||
.popsection
|
||||
|
||||
__get_user_N(1, ld1u)
|
||||
__get_user_N(2, ld2u)
|
||||
__get_user_N(4, ld4u)
|
||||
__get_user_N(8, ld)
|
||||
|
||||
/*
|
||||
* __put_user_N functions take a value in r0 and a pointer in r1,
|
||||
* and return 0 in r0 on success or -EFAULT on failure.
|
||||
*/
|
||||
#define __put_user_N(bytes, STORE) \
|
||||
STD_ENTRY(__put_user_##bytes); \
|
||||
1: { STORE r1, r0; move r0, zero }; \
|
||||
jrp lr; \
|
||||
STD_ENDPROC(__put_user_##bytes); \
|
||||
.pushsection __ex_table,"a"; \
|
||||
.quad 1b, put_user_fault; \
|
||||
.popsection
|
||||
|
||||
__put_user_N(1, st1)
|
||||
__put_user_N(2, st2)
|
||||
__put_user_N(4, st4)
|
||||
__put_user_N(8, st)
|
||||
|
||||
/*
|
||||
* strnlen_user_asm takes the pointer in r0, and the length bound in r1.
|
||||
* It returns the length, including the terminating NUL, or zero on exception.
|
||||
* If length is greater than the bound, returns one plus the bound.
|
||||
*/
|
||||
STD_ENTRY(strnlen_user_asm)
|
||||
{ beqz r1, 2f; addi r3, r0, -1 } /* bias down to include NUL */
|
||||
1: { ld1u r4, r0; addi r1, r1, -1 }
|
||||
beqz r4, 2f
|
||||
{ bnezt r1, 1b; addi r0, r0, 1 }
|
||||
2: { sub r0, r0, r3; jrp lr }
|
||||
STD_ENDPROC(strnlen_user_asm)
|
||||
.pushsection .fixup,"ax"
|
||||
strnlen_user_fault:
|
||||
{ move r0, zero; jrp lr }
|
||||
ENDPROC(strnlen_user_fault)
|
||||
.section __ex_table,"a"
|
||||
.quad 1b, strnlen_user_fault
|
||||
.popsection
|
||||
|
||||
/*
|
||||
* strncpy_from_user_asm takes the kernel target pointer in r0,
|
||||
* the userspace source pointer in r1, and the length bound (including
|
||||
* the trailing NUL) in r2. On success, it returns the string length
|
||||
* (not including the trailing NUL), or -EFAULT on failure.
|
||||
*/
|
||||
STD_ENTRY(strncpy_from_user_asm)
|
||||
{ beqz r2, 2f; move r3, r0 }
|
||||
1: { ld1u r4, r1; addi r1, r1, 1; addi r2, r2, -1 }
|
||||
{ st1 r0, r4; addi r0, r0, 1 }
|
||||
beqz r2, 2f
|
||||
bnezt r4, 1b
|
||||
addi r0, r0, -1 /* don't count the trailing NUL */
|
||||
2: { sub r0, r0, r3; jrp lr }
|
||||
STD_ENDPROC(strncpy_from_user_asm)
|
||||
.pushsection .fixup,"ax"
|
||||
strncpy_from_user_fault:
|
||||
{ movei r0, -EFAULT; jrp lr }
|
||||
ENDPROC(strncpy_from_user_fault)
|
||||
.section __ex_table,"a"
|
||||
.quad 1b, strncpy_from_user_fault
|
||||
.popsection
|
||||
|
||||
/*
|
||||
* clear_user_asm takes the user target address in r0 and the
|
||||
* number of bytes to zero in r1.
|
||||
* It returns the number of uncopiable bytes (hopefully zero) in r0.
|
||||
* Note that we don't use a separate .fixup section here since we fall
|
||||
* through into the "fixup" code as the last straight-line bundle anyway.
|
||||
*/
|
||||
STD_ENTRY(clear_user_asm)
|
||||
{ beqz r1, 2f; or r2, r0, r1 }
|
||||
andi r2, r2, 7
|
||||
beqzt r2, .Lclear_aligned_user_asm
|
||||
1: { st1 r0, zero; addi r0, r0, 1; addi r1, r1, -1 }
|
||||
bnezt r1, 1b
|
||||
2: { move r0, r1; jrp lr }
|
||||
.pushsection __ex_table,"a"
|
||||
.quad 1b, 2b
|
||||
.popsection
|
||||
|
||||
.Lclear_aligned_user_asm:
|
||||
1: { st r0, zero; addi r0, r0, 8; addi r1, r1, -8 }
|
||||
bnezt r1, 1b
|
||||
2: { move r0, r1; jrp lr }
|
||||
STD_ENDPROC(clear_user_asm)
|
||||
.pushsection __ex_table,"a"
|
||||
.quad 1b, 2b
|
||||
.popsection
|
||||
|
||||
/*
|
||||
* flush_user_asm takes the user target address in r0 and the
|
||||
* number of bytes to flush in r1.
|
||||
* It returns the number of unflushable bytes (hopefully zero) in r0.
|
||||
*/
|
||||
STD_ENTRY(flush_user_asm)
|
||||
beqz r1, 2f
|
||||
{ movei r2, L2_CACHE_BYTES; add r1, r0, r1 }
|
||||
{ sub r2, zero, r2; addi r1, r1, L2_CACHE_BYTES-1 }
|
||||
{ and r0, r0, r2; and r1, r1, r2 }
|
||||
{ sub r1, r1, r0 }
|
||||
1: { flush r0; addi r1, r1, -CHIP_FLUSH_STRIDE() }
|
||||
{ addi r0, r0, CHIP_FLUSH_STRIDE(); bnezt r1, 1b }
|
||||
2: { move r0, r1; jrp lr }
|
||||
STD_ENDPROC(flush_user_asm)
|
||||
.pushsection __ex_table,"a"
|
||||
.quad 1b, 2b
|
||||
.popsection
|
||||
|
||||
/*
|
||||
* inv_user_asm takes the user target address in r0 and the
|
||||
* number of bytes to invalidate in r1.
|
||||
* It returns the number of not inv'able bytes (hopefully zero) in r0.
|
||||
*/
|
||||
STD_ENTRY(inv_user_asm)
|
||||
beqz r1, 2f
|
||||
{ movei r2, L2_CACHE_BYTES; add r1, r0, r1 }
|
||||
{ sub r2, zero, r2; addi r1, r1, L2_CACHE_BYTES-1 }
|
||||
{ and r0, r0, r2; and r1, r1, r2 }
|
||||
{ sub r1, r1, r0 }
|
||||
1: { inv r0; addi r1, r1, -CHIP_INV_STRIDE() }
|
||||
{ addi r0, r0, CHIP_INV_STRIDE(); bnezt r1, 1b }
|
||||
2: { move r0, r1; jrp lr }
|
||||
STD_ENDPROC(inv_user_asm)
|
||||
.pushsection __ex_table,"a"
|
||||
.quad 1b, 2b
|
||||
.popsection
|
||||
|
||||
/*
|
||||
* finv_user_asm takes the user target address in r0 and the
|
||||
* number of bytes to flush-invalidate in r1.
|
||||
* It returns the number of not finv'able bytes (hopefully zero) in r0.
|
||||
*/
|
||||
STD_ENTRY(finv_user_asm)
|
||||
beqz r1, 2f
|
||||
{ movei r2, L2_CACHE_BYTES; add r1, r0, r1 }
|
||||
{ sub r2, zero, r2; addi r1, r1, L2_CACHE_BYTES-1 }
|
||||
{ and r0, r0, r2; and r1, r1, r2 }
|
||||
{ sub r1, r1, r0 }
|
||||
1: { finv r0; addi r1, r1, -CHIP_FINV_STRIDE() }
|
||||
{ addi r0, r0, CHIP_FINV_STRIDE(); bnezt r1, 1b }
|
||||
2: { move r0, r1; jrp lr }
|
||||
STD_ENDPROC(finv_user_asm)
|
||||
.pushsection __ex_table,"a"
|
||||
.quad 1b, 2b
|
||||
.popsection
|
@ -43,8 +43,11 @@
|
||||
|
||||
#include <arch/interrupts.h>
|
||||
|
||||
static noinline void force_sig_info_fault(int si_signo, int si_code,
|
||||
unsigned long address, int fault_num, struct task_struct *tsk)
|
||||
static noinline void force_sig_info_fault(const char *type, int si_signo,
|
||||
int si_code, unsigned long address,
|
||||
int fault_num,
|
||||
struct task_struct *tsk,
|
||||
struct pt_regs *regs)
|
||||
{
|
||||
siginfo_t info;
|
||||
|
||||
@ -59,6 +62,7 @@ static noinline void force_sig_info_fault(int si_signo, int si_code,
|
||||
info.si_code = si_code;
|
||||
info.si_addr = (void __user *)address;
|
||||
info.si_trapno = fault_num;
|
||||
trace_unhandled_signal(type, regs, address, si_signo);
|
||||
force_sig_info(si_signo, &info, tsk);
|
||||
}
|
||||
|
||||
@ -71,11 +75,12 @@ SYSCALL_DEFINE2(cmpxchg_badaddr, unsigned long, address,
|
||||
struct pt_regs *, regs)
|
||||
{
|
||||
if (address >= PAGE_OFFSET)
|
||||
force_sig_info_fault(SIGSEGV, SEGV_MAPERR, address,
|
||||
INT_DTLB_MISS, current);
|
||||
force_sig_info_fault("atomic segfault", SIGSEGV, SEGV_MAPERR,
|
||||
address, INT_DTLB_MISS, current, regs);
|
||||
else
|
||||
force_sig_info_fault(SIGBUS, BUS_ADRALN, address,
|
||||
INT_UNALIGN_DATA, current);
|
||||
force_sig_info_fault("atomic alignment fault", SIGBUS,
|
||||
BUS_ADRALN, address,
|
||||
INT_UNALIGN_DATA, current, regs);
|
||||
|
||||
/*
|
||||
* Adjust pc to point at the actual instruction, which is unusual
|
||||
@ -471,8 +476,8 @@ bad_area_nosemaphore:
|
||||
*/
|
||||
local_irq_enable();
|
||||
|
||||
force_sig_info_fault(SIGSEGV, si_code, address,
|
||||
fault_num, tsk);
|
||||
force_sig_info_fault("segfault", SIGSEGV, si_code, address,
|
||||
fault_num, tsk, regs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -547,7 +552,8 @@ do_sigbus:
|
||||
if (is_kernel_mode)
|
||||
goto no_context;
|
||||
|
||||
force_sig_info_fault(SIGBUS, BUS_ADRERR, address, fault_num, tsk);
|
||||
force_sig_info_fault("bus error", SIGBUS, BUS_ADRERR, address,
|
||||
fault_num, tsk, regs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -732,6 +738,7 @@ void do_page_fault(struct pt_regs *regs, int fault_num,
|
||||
panic("Bad fault number %d in do_page_fault", fault_num);
|
||||
}
|
||||
|
||||
#if CHIP_HAS_TILE_DMA() || CHIP_HAS_SN_PROC()
|
||||
if (EX1_PL(regs->ex1) != USER_PL) {
|
||||
struct async_tlb *async;
|
||||
switch (fault_num) {
|
||||
@ -775,6 +782,7 @@ void do_page_fault(struct pt_regs *regs, int fault_num,
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
handle_page_fault(regs, fault_num, is_page_fault, address, write);
|
||||
}
|
||||
@ -801,8 +809,6 @@ static void handle_async_page_fault(struct pt_regs *regs,
|
||||
async->address, async->is_write);
|
||||
}
|
||||
}
|
||||
#endif /* CHIP_HAS_TILE_DMA() || CHIP_HAS_SN_PROC() */
|
||||
|
||||
|
||||
/*
|
||||
* This routine effectively re-issues asynchronous page faults
|
||||
@ -824,6 +830,8 @@ void do_async_page_fault(struct pt_regs *regs)
|
||||
handle_async_page_fault(regs, ¤t->thread.sn_async_tlb);
|
||||
#endif
|
||||
}
|
||||
#endif /* CHIP_HAS_TILE_DMA() || CHIP_HAS_SN_PROC() */
|
||||
|
||||
|
||||
void vmalloc_sync_all(void)
|
||||
{
|
||||
|
187
arch/tile/mm/migrate_64.S
Normal file
187
arch/tile/mm/migrate_64.S
Normal file
@ -0,0 +1,187 @@
|
||||
/*
|
||||
* Copyright 2011 Tilera Corporation. All Rights Reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation, version 2.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
|
||||
* NON INFRINGEMENT. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* This routine is a helper for migrating the home of a set of pages to
|
||||
* a new cpu. See the documentation in homecache.c for more information.
|
||||
*/
|
||||
|
||||
#include <linux/linkage.h>
|
||||
#include <linux/threads.h>
|
||||
#include <asm/page.h>
|
||||
#include <asm/thread_info.h>
|
||||
#include <asm/types.h>
|
||||
#include <asm/asm-offsets.h>
|
||||
#include <hv/hypervisor.h>
|
||||
|
||||
.text
|
||||
|
||||
/*
|
||||
* First, some definitions that apply to all the code in the file.
|
||||
*/
|
||||
|
||||
/* Locals (caller-save) */
|
||||
#define r_tmp r10
|
||||
#define r_save_sp r11
|
||||
|
||||
/* What we save where in the stack frame; must include all callee-saves. */
|
||||
#define FRAME_SP 8
|
||||
#define FRAME_R30 16
|
||||
#define FRAME_R31 24
|
||||
#define FRAME_R32 32
|
||||
#define FRAME_R33 40
|
||||
#define FRAME_SIZE 48
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* On entry:
|
||||
*
|
||||
* r0 the new context PA to install (moved to r_context)
|
||||
* r1 PTE to use for context access (moved to r_access)
|
||||
* r2 ASID to use for new context (moved to r_asid)
|
||||
* r3 pointer to cpumask with just this cpu set in it (r_my_cpumask)
|
||||
*/
|
||||
|
||||
/* Arguments (caller-save) */
|
||||
#define r_context_in r0
|
||||
#define r_access_in r1
|
||||
#define r_asid_in r2
|
||||
#define r_my_cpumask r3
|
||||
|
||||
/* Locals (callee-save); must not be more than FRAME_xxx above. */
|
||||
#define r_save_ics r30
|
||||
#define r_context r31
|
||||
#define r_access r32
|
||||
#define r_asid r33
|
||||
|
||||
/*
|
||||
* Caller-save locals and frame constants are the same as
|
||||
* for homecache_migrate_stack_and_flush.
|
||||
*/
|
||||
|
||||
STD_ENTRY(flush_and_install_context)
|
||||
/*
|
||||
* Create a stack frame; we can't touch it once we flush the
|
||||
* cache until we install the new page table and flush the TLB.
|
||||
*/
|
||||
{
|
||||
move r_save_sp, sp
|
||||
st sp, lr
|
||||
addi sp, sp, -FRAME_SIZE
|
||||
}
|
||||
addi r_tmp, sp, FRAME_SP
|
||||
{
|
||||
st r_tmp, r_save_sp
|
||||
addi r_tmp, sp, FRAME_R30
|
||||
}
|
||||
{
|
||||
st r_tmp, r30
|
||||
addi r_tmp, sp, FRAME_R31
|
||||
}
|
||||
{
|
||||
st r_tmp, r31
|
||||
addi r_tmp, sp, FRAME_R32
|
||||
}
|
||||
{
|
||||
st r_tmp, r32
|
||||
addi r_tmp, sp, FRAME_R33
|
||||
}
|
||||
st r_tmp, r33
|
||||
|
||||
/* Move some arguments to callee-save registers. */
|
||||
{
|
||||
move r_context, r_context_in
|
||||
move r_access, r_access_in
|
||||
}
|
||||
move r_asid, r_asid_in
|
||||
|
||||
/* Disable interrupts, since we can't use our stack. */
|
||||
{
|
||||
mfspr r_save_ics, INTERRUPT_CRITICAL_SECTION
|
||||
movei r_tmp, 1
|
||||
}
|
||||
mtspr INTERRUPT_CRITICAL_SECTION, r_tmp
|
||||
|
||||
/* First, flush our L2 cache. */
|
||||
{
|
||||
move r0, zero /* cache_pa */
|
||||
moveli r1, hw2_last(HV_FLUSH_EVICT_L2) /* cache_control */
|
||||
}
|
||||
{
|
||||
shl16insli r1, r1, hw1(HV_FLUSH_EVICT_L2)
|
||||
move r2, r_my_cpumask /* cache_cpumask */
|
||||
}
|
||||
{
|
||||
shl16insli r1, r1, hw0(HV_FLUSH_EVICT_L2)
|
||||
move r3, zero /* tlb_va */
|
||||
}
|
||||
{
|
||||
move r4, zero /* tlb_length */
|
||||
move r5, zero /* tlb_pgsize */
|
||||
}
|
||||
{
|
||||
move r6, zero /* tlb_cpumask */
|
||||
move r7, zero /* asids */
|
||||
}
|
||||
{
|
||||
move r8, zero /* asidcount */
|
||||
jal hv_flush_remote
|
||||
}
|
||||
bnez r0, 1f
|
||||
|
||||
/* Now install the new page table. */
|
||||
{
|
||||
move r0, r_context
|
||||
move r1, r_access
|
||||
}
|
||||
{
|
||||
move r2, r_asid
|
||||
movei r3, HV_CTX_DIRECTIO
|
||||
}
|
||||
jal hv_install_context
|
||||
bnez r0, 1f
|
||||
|
||||
/* Finally, flush the TLB. */
|
||||
{
|
||||
movei r0, 0 /* preserve_global */
|
||||
jal hv_flush_all
|
||||
}
|
||||
|
||||
1: /* Reset interrupts back how they were before. */
|
||||
mtspr INTERRUPT_CRITICAL_SECTION, r_save_ics
|
||||
|
||||
/* Restore the callee-saved registers and return. */
|
||||
addli lr, sp, FRAME_SIZE
|
||||
{
|
||||
ld lr, lr
|
||||
addli r_tmp, sp, FRAME_R30
|
||||
}
|
||||
{
|
||||
ld r30, r_tmp
|
||||
addli r_tmp, sp, FRAME_R31
|
||||
}
|
||||
{
|
||||
ld r31, r_tmp
|
||||
addli r_tmp, sp, FRAME_R32
|
||||
}
|
||||
{
|
||||
ld r32, r_tmp
|
||||
addli r_tmp, sp, FRAME_R33
|
||||
}
|
||||
{
|
||||
ld r33, r_tmp
|
||||
addi sp, sp, FRAME_SIZE
|
||||
}
|
||||
jrp lr
|
||||
STD_ENDPROC(flush_and_install_context)
|
@ -19,7 +19,7 @@
|
||||
|
||||
/* Note to the author of this code: did it ever occur to
|
||||
you why the ifdefs are needed? Think about it again. -AK */
|
||||
#ifdef CONFIG_X86_64
|
||||
#if defined(CONFIG_X86_64) || defined(CONFIG_TILE)
|
||||
# define INPUT_COMPAT_TEST is_compat_task()
|
||||
#elif defined(CONFIG_S390)
|
||||
# define INPUT_COMPAT_TEST test_thread_flag(TIF_31BIT)
|
||||
|
@ -1658,11 +1658,9 @@ static int tile_net_stop(struct net_device *dev)
|
||||
while (tile_net_lepp_free_comps(dev, true))
|
||||
/* loop */;
|
||||
|
||||
/* Wipe the EPP queue. */
|
||||
/* Wipe the EPP queue, and wait till the stores hit the EPP. */
|
||||
memset(priv->eq, 0, sizeof(lepp_queue_t));
|
||||
|
||||
/* Evict the EPP queue. */
|
||||
finv_buffer(priv->eq, EQ_SIZE);
|
||||
mb();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -2398,7 +2396,7 @@ static void tile_net_cleanup(void)
|
||||
struct net_device *dev = tile_net_devs[i];
|
||||
struct tile_net_priv *priv = netdev_priv(dev);
|
||||
unregister_netdev(dev);
|
||||
finv_buffer(priv->eq, EQ_SIZE);
|
||||
finv_buffer_remote(priv->eq, EQ_SIZE, 0);
|
||||
__free_pages(priv->eq_pages, EQ_ORDER);
|
||||
free_netdev(dev);
|
||||
}
|
||||
|
@ -992,4 +992,11 @@ config RTC_DRV_TEGRA
|
||||
This drive can also be built as a module. If so, the module
|
||||
will be called rtc-tegra.
|
||||
|
||||
config RTC_DRV_TILE
|
||||
tristate "Tilera hypervisor RTC support"
|
||||
depends on TILE
|
||||
help
|
||||
Enable support for the Linux driver side of the Tilera
|
||||
hypervisor's real-time clock interface.
|
||||
|
||||
endif # RTC_CLASS
|
||||
|
@ -93,6 +93,7 @@ obj-$(CONFIG_RTC_DRV_STMP) += rtc-stmp3xxx.o
|
||||
obj-$(CONFIG_RTC_DRV_SUN4V) += rtc-sun4v.o
|
||||
obj-$(CONFIG_RTC_DRV_TEGRA) += rtc-tegra.o
|
||||
obj-$(CONFIG_RTC_DRV_TEST) += rtc-test.o
|
||||
obj-$(CONFIG_RTC_DRV_TILE) += rtc-tile.o
|
||||
obj-$(CONFIG_RTC_DRV_TWL4030) += rtc-twl.o
|
||||
obj-$(CONFIG_RTC_DRV_TX4939) += rtc-tx4939.o
|
||||
obj-$(CONFIG_RTC_DRV_V3020) += rtc-v3020.o
|
||||
|
162
drivers/rtc/rtc-tile.c
Normal file
162
drivers/rtc/rtc-tile.c
Normal file
@ -0,0 +1,162 @@
|
||||
/*
|
||||
* Copyright 2011 Tilera Corporation. All Rights Reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation, version 2.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
|
||||
* NON INFRINGEMENT. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* Tilera-specific RTC driver.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/rtc.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
/* Platform device pointer. */
|
||||
static struct platform_device *tile_rtc_platform_device;
|
||||
|
||||
/*
|
||||
* RTC read routine. Gets time info from RTC chip via hypervisor syscall.
|
||||
*/
|
||||
static int read_rtc_time(struct device *dev, struct rtc_time *tm)
|
||||
{
|
||||
HV_RTCTime hvtm = hv_get_rtc();
|
||||
|
||||
tm->tm_sec = hvtm.tm_sec;
|
||||
tm->tm_min = hvtm.tm_min;
|
||||
tm->tm_hour = hvtm.tm_hour;
|
||||
tm->tm_mday = hvtm.tm_mday;
|
||||
tm->tm_mon = hvtm.tm_mon;
|
||||
tm->tm_year = hvtm.tm_year;
|
||||
tm->tm_wday = 0;
|
||||
tm->tm_yday = 0;
|
||||
tm->tm_isdst = 0;
|
||||
|
||||
if (rtc_valid_tm(tm) < 0)
|
||||
dev_warn(dev, "Read invalid date/time from RTC\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* RTC write routine. Sends time info to hypervisor via syscall, to be
|
||||
* written to RTC chip.
|
||||
*/
|
||||
static int set_rtc_time(struct device *dev, struct rtc_time *tm)
|
||||
{
|
||||
HV_RTCTime hvtm;
|
||||
|
||||
hvtm.tm_sec = tm->tm_sec;
|
||||
hvtm.tm_min = tm->tm_min;
|
||||
hvtm.tm_hour = tm->tm_hour;
|
||||
hvtm.tm_mday = tm->tm_mday;
|
||||
hvtm.tm_mon = tm->tm_mon;
|
||||
hvtm.tm_year = tm->tm_year;
|
||||
|
||||
hv_set_rtc(hvtm);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* RTC read/write ops.
|
||||
*/
|
||||
static const struct rtc_class_ops tile_rtc_ops = {
|
||||
.read_time = read_rtc_time,
|
||||
.set_time = set_rtc_time,
|
||||
};
|
||||
|
||||
/*
|
||||
* Device probe routine.
|
||||
*/
|
||||
static int __devinit tile_rtc_probe(struct platform_device *dev)
|
||||
{
|
||||
struct rtc_device *rtc;
|
||||
|
||||
rtc = rtc_device_register("tile",
|
||||
&dev->dev, &tile_rtc_ops, THIS_MODULE);
|
||||
|
||||
if (IS_ERR(rtc))
|
||||
return PTR_ERR(rtc);
|
||||
|
||||
platform_set_drvdata(dev, rtc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Device cleanup routine.
|
||||
*/
|
||||
static int __devexit tile_rtc_remove(struct platform_device *dev)
|
||||
{
|
||||
struct rtc_device *rtc = platform_get_drvdata(dev);
|
||||
|
||||
if (rtc)
|
||||
rtc_device_unregister(rtc);
|
||||
|
||||
platform_set_drvdata(dev, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver tile_rtc_platform_driver = {
|
||||
.driver = {
|
||||
.name = "rtc-tile",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.probe = tile_rtc_probe,
|
||||
.remove = __devexit_p(tile_rtc_remove),
|
||||
};
|
||||
|
||||
/*
|
||||
* Driver init routine.
|
||||
*/
|
||||
static int __init tile_rtc_driver_init(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = platform_driver_register(&tile_rtc_platform_driver);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
tile_rtc_platform_device = platform_device_alloc("rtc-tile", 0);
|
||||
if (tile_rtc_platform_device == NULL) {
|
||||
err = -ENOMEM;
|
||||
goto exit_driver_unregister;
|
||||
}
|
||||
|
||||
err = platform_device_add(tile_rtc_platform_device);
|
||||
if (err)
|
||||
goto exit_device_put;
|
||||
|
||||
return 0;
|
||||
|
||||
exit_device_put:
|
||||
platform_device_put(tile_rtc_platform_device);
|
||||
|
||||
exit_driver_unregister:
|
||||
platform_driver_unregister(&tile_rtc_platform_driver);
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* Driver cleanup routine.
|
||||
*/
|
||||
static void __exit tile_rtc_driver_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&tile_rtc_platform_driver);
|
||||
}
|
||||
|
||||
module_init(tile_rtc_driver_init);
|
||||
module_exit(tile_rtc_driver_exit);
|
||||
|
||||
MODULE_DESCRIPTION("Tilera-specific Real Time Clock Driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("platform:rtc-tile");
|
@ -1,4 +1,6 @@
|
||||
#ifdef __NR_chmod
|
||||
__NR_chmod,
|
||||
#endif
|
||||
__NR_fchmod,
|
||||
#ifdef __NR_chown
|
||||
__NR_chown,
|
||||
@ -20,7 +22,9 @@ __NR_chown32,
|
||||
__NR_fchown32,
|
||||
__NR_lchown32,
|
||||
#endif
|
||||
#ifdef __NR_link
|
||||
__NR_link,
|
||||
#endif
|
||||
#ifdef __NR_linkat
|
||||
__NR_linkat,
|
||||
#endif
|
||||
|
@ -1,13 +1,27 @@
|
||||
#ifdef __NR_rename
|
||||
__NR_rename,
|
||||
#endif
|
||||
#ifdef __NR_mkdir
|
||||
__NR_mkdir,
|
||||
#endif
|
||||
#ifdef __NR_rmdir
|
||||
__NR_rmdir,
|
||||
#endif
|
||||
#ifdef __NR_creat
|
||||
__NR_creat,
|
||||
#endif
|
||||
#ifdef __NR_link
|
||||
__NR_link,
|
||||
#endif
|
||||
#ifdef __NR_unlink
|
||||
__NR_unlink,
|
||||
#endif
|
||||
#ifdef __NR_symlink
|
||||
__NR_symlink,
|
||||
#endif
|
||||
#ifdef __NR_mknod
|
||||
__NR_mknod,
|
||||
#endif
|
||||
#ifdef __NR_mkdirat
|
||||
__NR_mkdirat,
|
||||
__NR_mknodat,
|
||||
|
@ -1,4 +1,6 @@
|
||||
#ifdef __NR_readlink
|
||||
__NR_readlink,
|
||||
#endif
|
||||
__NR_quotactl,
|
||||
__NR_listxattr,
|
||||
__NR_llistxattr,
|
||||
@ -6,3 +8,6 @@ __NR_flistxattr,
|
||||
__NR_getxattr,
|
||||
__NR_lgetxattr,
|
||||
__NR_fgetxattr,
|
||||
#ifdef __NR_readlinkat
|
||||
__NR_readlinkat,
|
||||
#endif
|
||||
|
@ -4,7 +4,9 @@ __NR_acct,
|
||||
__NR_swapon,
|
||||
#endif
|
||||
__NR_quotactl,
|
||||
#ifdef __NR_truncate
|
||||
__NR_truncate,
|
||||
#endif
|
||||
#ifdef __NR_truncate64
|
||||
__NR_truncate64,
|
||||
#endif
|
||||
|
@ -24,16 +24,24 @@
|
||||
#define __SC_3264(_nr, _32, _64) __SYSCALL(_nr, _64)
|
||||
#endif
|
||||
|
||||
#ifdef __SYSCALL_COMPAT
|
||||
#define __SC_COMP(_nr, _sys, _comp) __SYSCALL(_nr, _comp)
|
||||
#define __SC_COMP_3264(_nr, _32, _64, _comp) __SYSCALL(_nr, _comp)
|
||||
#else
|
||||
#define __SC_COMP(_nr, _sys, _comp) __SYSCALL(_nr, _sys)
|
||||
#define __SC_COMP_3264(_nr, _32, _64, _comp) __SC_3264(_nr, _32, _64)
|
||||
#endif
|
||||
|
||||
#define __NR_io_setup 0
|
||||
__SYSCALL(__NR_io_setup, sys_io_setup)
|
||||
__SC_COMP(__NR_io_setup, sys_io_setup, compat_sys_io_setup)
|
||||
#define __NR_io_destroy 1
|
||||
__SYSCALL(__NR_io_destroy, sys_io_destroy)
|
||||
#define __NR_io_submit 2
|
||||
__SYSCALL(__NR_io_submit, sys_io_submit)
|
||||
__SC_COMP(__NR_io_submit, sys_io_submit, compat_sys_io_submit)
|
||||
#define __NR_io_cancel 3
|
||||
__SYSCALL(__NR_io_cancel, sys_io_cancel)
|
||||
#define __NR_io_getevents 4
|
||||
__SYSCALL(__NR_io_getevents, sys_io_getevents)
|
||||
__SC_COMP(__NR_io_getevents, sys_io_getevents, compat_sys_io_getevents)
|
||||
|
||||
/* fs/xattr.c */
|
||||
#define __NR_setxattr 5
|
||||
@ -67,7 +75,7 @@ __SYSCALL(__NR_getcwd, sys_getcwd)
|
||||
|
||||
/* fs/cookies.c */
|
||||
#define __NR_lookup_dcookie 18
|
||||
__SYSCALL(__NR_lookup_dcookie, sys_lookup_dcookie)
|
||||
__SC_COMP(__NR_lookup_dcookie, sys_lookup_dcookie, compat_sys_lookup_dcookie)
|
||||
|
||||
/* fs/eventfd.c */
|
||||
#define __NR_eventfd2 19
|
||||
@ -79,7 +87,7 @@ __SYSCALL(__NR_epoll_create1, sys_epoll_create1)
|
||||
#define __NR_epoll_ctl 21
|
||||
__SYSCALL(__NR_epoll_ctl, sys_epoll_ctl)
|
||||
#define __NR_epoll_pwait 22
|
||||
__SYSCALL(__NR_epoll_pwait, sys_epoll_pwait)
|
||||
__SC_COMP(__NR_epoll_pwait, sys_epoll_pwait, compat_sys_epoll_pwait)
|
||||
|
||||
/* fs/fcntl.c */
|
||||
#define __NR_dup 23
|
||||
@ -87,7 +95,7 @@ __SYSCALL(__NR_dup, sys_dup)
|
||||
#define __NR_dup3 24
|
||||
__SYSCALL(__NR_dup3, sys_dup3)
|
||||
#define __NR3264_fcntl 25
|
||||
__SC_3264(__NR3264_fcntl, sys_fcntl64, sys_fcntl)
|
||||
__SC_COMP_3264(__NR3264_fcntl, sys_fcntl64, sys_fcntl, compat_sys_fcntl64)
|
||||
|
||||
/* fs/inotify_user.c */
|
||||
#define __NR_inotify_init1 26
|
||||
@ -99,7 +107,7 @@ __SYSCALL(__NR_inotify_rm_watch, sys_inotify_rm_watch)
|
||||
|
||||
/* fs/ioctl.c */
|
||||
#define __NR_ioctl 29
|
||||
__SYSCALL(__NR_ioctl, sys_ioctl)
|
||||
__SC_COMP(__NR_ioctl, sys_ioctl, compat_sys_ioctl)
|
||||
|
||||
/* fs/ioprio.c */
|
||||
#define __NR_ioprio_set 30
|
||||
@ -129,26 +137,30 @@ __SYSCALL(__NR_renameat, sys_renameat)
|
||||
#define __NR_umount2 39
|
||||
__SYSCALL(__NR_umount2, sys_umount)
|
||||
#define __NR_mount 40
|
||||
__SYSCALL(__NR_mount, sys_mount)
|
||||
__SC_COMP(__NR_mount, sys_mount, compat_sys_mount)
|
||||
#define __NR_pivot_root 41
|
||||
__SYSCALL(__NR_pivot_root, sys_pivot_root)
|
||||
|
||||
/* fs/nfsctl.c */
|
||||
#define __NR_nfsservctl 42
|
||||
__SYSCALL(__NR_nfsservctl, sys_nfsservctl)
|
||||
__SC_COMP(__NR_nfsservctl, sys_nfsservctl, compat_sys_nfsservctl)
|
||||
|
||||
/* fs/open.c */
|
||||
#define __NR3264_statfs 43
|
||||
__SC_3264(__NR3264_statfs, sys_statfs64, sys_statfs)
|
||||
__SC_COMP_3264(__NR3264_statfs, sys_statfs64, sys_statfs, \
|
||||
compat_sys_statfs64)
|
||||
#define __NR3264_fstatfs 44
|
||||
__SC_3264(__NR3264_fstatfs, sys_fstatfs64, sys_fstatfs)
|
||||
__SC_COMP_3264(__NR3264_fstatfs, sys_fstatfs64, sys_fstatfs, \
|
||||
compat_sys_fstatfs64)
|
||||
#define __NR3264_truncate 45
|
||||
__SC_3264(__NR3264_truncate, sys_truncate64, sys_truncate)
|
||||
__SC_COMP_3264(__NR3264_truncate, sys_truncate64, sys_truncate, \
|
||||
compat_sys_truncate64)
|
||||
#define __NR3264_ftruncate 46
|
||||
__SC_3264(__NR3264_ftruncate, sys_ftruncate64, sys_ftruncate)
|
||||
__SC_COMP_3264(__NR3264_ftruncate, sys_ftruncate64, sys_ftruncate, \
|
||||
compat_sys_ftruncate64)
|
||||
|
||||
#define __NR_fallocate 47
|
||||
__SYSCALL(__NR_fallocate, sys_fallocate)
|
||||
__SC_COMP(__NR_fallocate, sys_fallocate, compat_sys_fallocate)
|
||||
#define __NR_faccessat 48
|
||||
__SYSCALL(__NR_faccessat, sys_faccessat)
|
||||
#define __NR_chdir 49
|
||||
@ -166,7 +178,7 @@ __SYSCALL(__NR_fchownat, sys_fchownat)
|
||||
#define __NR_fchown 55
|
||||
__SYSCALL(__NR_fchown, sys_fchown)
|
||||
#define __NR_openat 56
|
||||
__SYSCALL(__NR_openat, sys_openat)
|
||||
__SC_COMP(__NR_openat, sys_openat, compat_sys_openat)
|
||||
#define __NR_close 57
|
||||
__SYSCALL(__NR_close, sys_close)
|
||||
#define __NR_vhangup 58
|
||||
@ -182,7 +194,7 @@ __SYSCALL(__NR_quotactl, sys_quotactl)
|
||||
|
||||
/* fs/readdir.c */
|
||||
#define __NR_getdents64 61
|
||||
__SYSCALL(__NR_getdents64, sys_getdents64)
|
||||
__SC_COMP(__NR_getdents64, sys_getdents64, compat_sys_getdents64)
|
||||
|
||||
/* fs/read_write.c */
|
||||
#define __NR3264_lseek 62
|
||||
@ -192,17 +204,17 @@ __SYSCALL(__NR_read, sys_read)
|
||||
#define __NR_write 64
|
||||
__SYSCALL(__NR_write, sys_write)
|
||||
#define __NR_readv 65
|
||||
__SYSCALL(__NR_readv, sys_readv)
|
||||
__SC_COMP(__NR_readv, sys_readv, compat_sys_readv)
|
||||
#define __NR_writev 66
|
||||
__SYSCALL(__NR_writev, sys_writev)
|
||||
__SC_COMP(__NR_writev, sys_writev, compat_sys_writev)
|
||||
#define __NR_pread64 67
|
||||
__SYSCALL(__NR_pread64, sys_pread64)
|
||||
__SC_COMP(__NR_pread64, sys_pread64, compat_sys_pread64)
|
||||
#define __NR_pwrite64 68
|
||||
__SYSCALL(__NR_pwrite64, sys_pwrite64)
|
||||
__SC_COMP(__NR_pwrite64, sys_pwrite64, compat_sys_pwrite64)
|
||||
#define __NR_preadv 69
|
||||
__SYSCALL(__NR_preadv, sys_preadv)
|
||||
__SC_COMP(__NR_preadv, sys_preadv, compat_sys_preadv)
|
||||
#define __NR_pwritev 70
|
||||
__SYSCALL(__NR_pwritev, sys_pwritev)
|
||||
__SC_COMP(__NR_pwritev, sys_pwritev, compat_sys_pwritev)
|
||||
|
||||
/* fs/sendfile.c */
|
||||
#define __NR3264_sendfile 71
|
||||
@ -210,17 +222,17 @@ __SC_3264(__NR3264_sendfile, sys_sendfile64, sys_sendfile)
|
||||
|
||||
/* fs/select.c */
|
||||
#define __NR_pselect6 72
|
||||
__SYSCALL(__NR_pselect6, sys_pselect6)
|
||||
__SC_COMP(__NR_pselect6, sys_pselect6, compat_sys_pselect6)
|
||||
#define __NR_ppoll 73
|
||||
__SYSCALL(__NR_ppoll, sys_ppoll)
|
||||
__SC_COMP(__NR_ppoll, sys_ppoll, compat_sys_ppoll)
|
||||
|
||||
/* fs/signalfd.c */
|
||||
#define __NR_signalfd4 74
|
||||
__SYSCALL(__NR_signalfd4, sys_signalfd4)
|
||||
__SC_COMP(__NR_signalfd4, sys_signalfd4, compat_sys_signalfd4)
|
||||
|
||||
/* fs/splice.c */
|
||||
#define __NR_vmsplice 75
|
||||
__SYSCALL(__NR_vmsplice, sys_vmsplice)
|
||||
__SC_COMP(__NR_vmsplice, sys_vmsplice, compat_sys_vmsplice)
|
||||
#define __NR_splice 76
|
||||
__SYSCALL(__NR_splice, sys_splice)
|
||||
#define __NR_tee 77
|
||||
@ -243,23 +255,27 @@ __SYSCALL(__NR_fsync, sys_fsync)
|
||||
__SYSCALL(__NR_fdatasync, sys_fdatasync)
|
||||
#ifdef __ARCH_WANT_SYNC_FILE_RANGE2
|
||||
#define __NR_sync_file_range2 84
|
||||
__SYSCALL(__NR_sync_file_range2, sys_sync_file_range2)
|
||||
__SC_COMP(__NR_sync_file_range2, sys_sync_file_range2, \
|
||||
compat_sys_sync_file_range2)
|
||||
#else
|
||||
#define __NR_sync_file_range 84
|
||||
__SYSCALL(__NR_sync_file_range, sys_sync_file_range)
|
||||
__SC_COMP(__NR_sync_file_range, sys_sync_file_range, \
|
||||
compat_sys_sync_file_range)
|
||||
#endif
|
||||
|
||||
/* fs/timerfd.c */
|
||||
#define __NR_timerfd_create 85
|
||||
__SYSCALL(__NR_timerfd_create, sys_timerfd_create)
|
||||
#define __NR_timerfd_settime 86
|
||||
__SYSCALL(__NR_timerfd_settime, sys_timerfd_settime)
|
||||
__SC_COMP(__NR_timerfd_settime, sys_timerfd_settime, \
|
||||
compat_sys_timerfd_settime)
|
||||
#define __NR_timerfd_gettime 87
|
||||
__SYSCALL(__NR_timerfd_gettime, sys_timerfd_gettime)
|
||||
__SC_COMP(__NR_timerfd_gettime, sys_timerfd_gettime, \
|
||||
compat_sys_timerfd_gettime)
|
||||
|
||||
/* fs/utimes.c */
|
||||
#define __NR_utimensat 88
|
||||
__SYSCALL(__NR_utimensat, sys_utimensat)
|
||||
__SC_COMP(__NR_utimensat, sys_utimensat, compat_sys_utimensat)
|
||||
|
||||
/* kernel/acct.c */
|
||||
#define __NR_acct 89
|
||||
@ -281,7 +297,7 @@ __SYSCALL(__NR_exit, sys_exit)
|
||||
#define __NR_exit_group 94
|
||||
__SYSCALL(__NR_exit_group, sys_exit_group)
|
||||
#define __NR_waitid 95
|
||||
__SYSCALL(__NR_waitid, sys_waitid)
|
||||
__SC_COMP(__NR_waitid, sys_waitid, compat_sys_waitid)
|
||||
|
||||
/* kernel/fork.c */
|
||||
#define __NR_set_tid_address 96
|
||||
@ -291,25 +307,27 @@ __SYSCALL(__NR_unshare, sys_unshare)
|
||||
|
||||
/* kernel/futex.c */
|
||||
#define __NR_futex 98
|
||||
__SYSCALL(__NR_futex, sys_futex)
|
||||
__SC_COMP(__NR_futex, sys_futex, compat_sys_futex)
|
||||
#define __NR_set_robust_list 99
|
||||
__SYSCALL(__NR_set_robust_list, sys_set_robust_list)
|
||||
__SC_COMP(__NR_set_robust_list, sys_set_robust_list, \
|
||||
compat_sys_set_robust_list)
|
||||
#define __NR_get_robust_list 100
|
||||
__SYSCALL(__NR_get_robust_list, sys_get_robust_list)
|
||||
__SC_COMP(__NR_get_robust_list, sys_get_robust_list, \
|
||||
compat_sys_get_robust_list)
|
||||
|
||||
/* kernel/hrtimer.c */
|
||||
#define __NR_nanosleep 101
|
||||
__SYSCALL(__NR_nanosleep, sys_nanosleep)
|
||||
__SC_COMP(__NR_nanosleep, sys_nanosleep, compat_sys_nanosleep)
|
||||
|
||||
/* kernel/itimer.c */
|
||||
#define __NR_getitimer 102
|
||||
__SYSCALL(__NR_getitimer, sys_getitimer)
|
||||
__SC_COMP(__NR_getitimer, sys_getitimer, compat_sys_getitimer)
|
||||
#define __NR_setitimer 103
|
||||
__SYSCALL(__NR_setitimer, sys_setitimer)
|
||||
__SC_COMP(__NR_setitimer, sys_setitimer, compat_sys_setitimer)
|
||||
|
||||
/* kernel/kexec.c */
|
||||
#define __NR_kexec_load 104
|
||||
__SYSCALL(__NR_kexec_load, sys_kexec_load)
|
||||
__SC_COMP(__NR_kexec_load, sys_kexec_load, compat_sys_kexec_load)
|
||||
|
||||
/* kernel/module.c */
|
||||
#define __NR_init_module 105
|
||||
@ -319,23 +337,24 @@ __SYSCALL(__NR_delete_module, sys_delete_module)
|
||||
|
||||
/* kernel/posix-timers.c */
|
||||
#define __NR_timer_create 107
|
||||
__SYSCALL(__NR_timer_create, sys_timer_create)
|
||||
__SC_COMP(__NR_timer_create, sys_timer_create, compat_sys_timer_create)
|
||||
#define __NR_timer_gettime 108
|
||||
__SYSCALL(__NR_timer_gettime, sys_timer_gettime)
|
||||
__SC_COMP(__NR_timer_gettime, sys_timer_gettime, compat_sys_timer_gettime)
|
||||
#define __NR_timer_getoverrun 109
|
||||
__SYSCALL(__NR_timer_getoverrun, sys_timer_getoverrun)
|
||||
#define __NR_timer_settime 110
|
||||
__SYSCALL(__NR_timer_settime, sys_timer_settime)
|
||||
__SC_COMP(__NR_timer_settime, sys_timer_settime, compat_sys_timer_settime)
|
||||
#define __NR_timer_delete 111
|
||||
__SYSCALL(__NR_timer_delete, sys_timer_delete)
|
||||
#define __NR_clock_settime 112
|
||||
__SYSCALL(__NR_clock_settime, sys_clock_settime)
|
||||
__SC_COMP(__NR_clock_settime, sys_clock_settime, compat_sys_clock_settime)
|
||||
#define __NR_clock_gettime 113
|
||||
__SYSCALL(__NR_clock_gettime, sys_clock_gettime)
|
||||
__SC_COMP(__NR_clock_gettime, sys_clock_gettime, compat_sys_clock_gettime)
|
||||
#define __NR_clock_getres 114
|
||||
__SYSCALL(__NR_clock_getres, sys_clock_getres)
|
||||
__SC_COMP(__NR_clock_getres, sys_clock_getres, compat_sys_clock_getres)
|
||||
#define __NR_clock_nanosleep 115
|
||||
__SYSCALL(__NR_clock_nanosleep, sys_clock_nanosleep)
|
||||
__SC_COMP(__NR_clock_nanosleep, sys_clock_nanosleep, \
|
||||
compat_sys_clock_nanosleep)
|
||||
|
||||
/* kernel/printk.c */
|
||||
#define __NR_syslog 116
|
||||
@ -355,9 +374,11 @@ __SYSCALL(__NR_sched_getscheduler, sys_sched_getscheduler)
|
||||
#define __NR_sched_getparam 121
|
||||
__SYSCALL(__NR_sched_getparam, sys_sched_getparam)
|
||||
#define __NR_sched_setaffinity 122
|
||||
__SYSCALL(__NR_sched_setaffinity, sys_sched_setaffinity)
|
||||
__SC_COMP(__NR_sched_setaffinity, sys_sched_setaffinity, \
|
||||
compat_sys_sched_setaffinity)
|
||||
#define __NR_sched_getaffinity 123
|
||||
__SYSCALL(__NR_sched_getaffinity, sys_sched_getaffinity)
|
||||
__SC_COMP(__NR_sched_getaffinity, sys_sched_getaffinity, \
|
||||
compat_sys_sched_getaffinity)
|
||||
#define __NR_sched_yield 124
|
||||
__SYSCALL(__NR_sched_yield, sys_sched_yield)
|
||||
#define __NR_sched_get_priority_max 125
|
||||
@ -365,7 +386,8 @@ __SYSCALL(__NR_sched_get_priority_max, sys_sched_get_priority_max)
|
||||
#define __NR_sched_get_priority_min 126
|
||||
__SYSCALL(__NR_sched_get_priority_min, sys_sched_get_priority_min)
|
||||
#define __NR_sched_rr_get_interval 127
|
||||
__SYSCALL(__NR_sched_rr_get_interval, sys_sched_rr_get_interval)
|
||||
__SC_COMP(__NR_sched_rr_get_interval, sys_sched_rr_get_interval, \
|
||||
compat_sys_sched_rr_get_interval)
|
||||
|
||||
/* kernel/signal.c */
|
||||
#define __NR_restart_syscall 128
|
||||
@ -377,21 +399,23 @@ __SYSCALL(__NR_tkill, sys_tkill)
|
||||
#define __NR_tgkill 131
|
||||
__SYSCALL(__NR_tgkill, sys_tgkill)
|
||||
#define __NR_sigaltstack 132
|
||||
__SYSCALL(__NR_sigaltstack, sys_sigaltstack)
|
||||
__SC_COMP(__NR_sigaltstack, sys_sigaltstack, compat_sys_sigaltstack)
|
||||
#define __NR_rt_sigsuspend 133
|
||||
__SYSCALL(__NR_rt_sigsuspend, sys_rt_sigsuspend) /* __ARCH_WANT_SYS_RT_SIGSUSPEND */
|
||||
__SC_COMP(__NR_rt_sigsuspend, sys_rt_sigsuspend, compat_sys_rt_sigsuspend)
|
||||
#define __NR_rt_sigaction 134
|
||||
__SYSCALL(__NR_rt_sigaction, sys_rt_sigaction) /* __ARCH_WANT_SYS_RT_SIGACTION */
|
||||
__SC_COMP(__NR_rt_sigaction, sys_rt_sigaction, compat_sys_rt_sigaction)
|
||||
#define __NR_rt_sigprocmask 135
|
||||
__SYSCALL(__NR_rt_sigprocmask, sys_rt_sigprocmask)
|
||||
#define __NR_rt_sigpending 136
|
||||
__SYSCALL(__NR_rt_sigpending, sys_rt_sigpending)
|
||||
#define __NR_rt_sigtimedwait 137
|
||||
__SYSCALL(__NR_rt_sigtimedwait, sys_rt_sigtimedwait)
|
||||
__SC_COMP(__NR_rt_sigtimedwait, sys_rt_sigtimedwait, \
|
||||
compat_sys_rt_sigtimedwait)
|
||||
#define __NR_rt_sigqueueinfo 138
|
||||
__SYSCALL(__NR_rt_sigqueueinfo, sys_rt_sigqueueinfo)
|
||||
__SC_COMP(__NR_rt_sigqueueinfo, sys_rt_sigqueueinfo, \
|
||||
compat_sys_rt_sigqueueinfo)
|
||||
#define __NR_rt_sigreturn 139
|
||||
__SYSCALL(__NR_rt_sigreturn, sys_rt_sigreturn) /* sys_rt_sigreturn_wrapper, */
|
||||
__SC_COMP(__NR_rt_sigreturn, sys_rt_sigreturn, compat_sys_rt_sigreturn)
|
||||
|
||||
/* kernel/sys.c */
|
||||
#define __NR_setpriority 140
|
||||
@ -421,7 +445,7 @@ __SYSCALL(__NR_setfsuid, sys_setfsuid)
|
||||
#define __NR_setfsgid 152
|
||||
__SYSCALL(__NR_setfsgid, sys_setfsgid)
|
||||
#define __NR_times 153
|
||||
__SYSCALL(__NR_times, sys_times)
|
||||
__SC_COMP(__NR_times, sys_times, compat_sys_times)
|
||||
#define __NR_setpgid 154
|
||||
__SYSCALL(__NR_setpgid, sys_setpgid)
|
||||
#define __NR_getpgid 155
|
||||
@ -441,11 +465,11 @@ __SYSCALL(__NR_sethostname, sys_sethostname)
|
||||
#define __NR_setdomainname 162
|
||||
__SYSCALL(__NR_setdomainname, sys_setdomainname)
|
||||
#define __NR_getrlimit 163
|
||||
__SYSCALL(__NR_getrlimit, sys_getrlimit)
|
||||
__SC_COMP(__NR_getrlimit, sys_getrlimit, compat_sys_getrlimit)
|
||||
#define __NR_setrlimit 164
|
||||
__SYSCALL(__NR_setrlimit, sys_setrlimit)
|
||||
__SC_COMP(__NR_setrlimit, sys_setrlimit, compat_sys_setrlimit)
|
||||
#define __NR_getrusage 165
|
||||
__SYSCALL(__NR_getrusage, sys_getrusage)
|
||||
__SC_COMP(__NR_getrusage, sys_getrusage, compat_sys_getrusage)
|
||||
#define __NR_umask 166
|
||||
__SYSCALL(__NR_umask, sys_umask)
|
||||
#define __NR_prctl 167
|
||||
@ -455,11 +479,11 @@ __SYSCALL(__NR_getcpu, sys_getcpu)
|
||||
|
||||
/* kernel/time.c */
|
||||
#define __NR_gettimeofday 169
|
||||
__SYSCALL(__NR_gettimeofday, sys_gettimeofday)
|
||||
__SC_COMP(__NR_gettimeofday, sys_gettimeofday, compat_sys_gettimeofday)
|
||||
#define __NR_settimeofday 170
|
||||
__SYSCALL(__NR_settimeofday, sys_settimeofday)
|
||||
__SC_COMP(__NR_settimeofday, sys_settimeofday, compat_sys_settimeofday)
|
||||
#define __NR_adjtimex 171
|
||||
__SYSCALL(__NR_adjtimex, sys_adjtimex)
|
||||
__SC_COMP(__NR_adjtimex, sys_adjtimex, compat_sys_adjtimex)
|
||||
|
||||
/* kernel/timer.c */
|
||||
#define __NR_getpid 172
|
||||
@ -477,39 +501,40 @@ __SYSCALL(__NR_getegid, sys_getegid)
|
||||
#define __NR_gettid 178
|
||||
__SYSCALL(__NR_gettid, sys_gettid)
|
||||
#define __NR_sysinfo 179
|
||||
__SYSCALL(__NR_sysinfo, sys_sysinfo)
|
||||
__SC_COMP(__NR_sysinfo, sys_sysinfo, compat_sys_sysinfo)
|
||||
|
||||
/* ipc/mqueue.c */
|
||||
#define __NR_mq_open 180
|
||||
__SYSCALL(__NR_mq_open, sys_mq_open)
|
||||
__SC_COMP(__NR_mq_open, sys_mq_open, compat_sys_mq_open)
|
||||
#define __NR_mq_unlink 181
|
||||
__SYSCALL(__NR_mq_unlink, sys_mq_unlink)
|
||||
#define __NR_mq_timedsend 182
|
||||
__SYSCALL(__NR_mq_timedsend, sys_mq_timedsend)
|
||||
__SC_COMP(__NR_mq_timedsend, sys_mq_timedsend, compat_sys_mq_timedsend)
|
||||
#define __NR_mq_timedreceive 183
|
||||
__SYSCALL(__NR_mq_timedreceive, sys_mq_timedreceive)
|
||||
__SC_COMP(__NR_mq_timedreceive, sys_mq_timedreceive, \
|
||||
compat_sys_mq_timedreceive)
|
||||
#define __NR_mq_notify 184
|
||||
__SYSCALL(__NR_mq_notify, sys_mq_notify)
|
||||
__SC_COMP(__NR_mq_notify, sys_mq_notify, compat_sys_mq_notify)
|
||||
#define __NR_mq_getsetattr 185
|
||||
__SYSCALL(__NR_mq_getsetattr, sys_mq_getsetattr)
|
||||
__SC_COMP(__NR_mq_getsetattr, sys_mq_getsetattr, compat_sys_mq_getsetattr)
|
||||
|
||||
/* ipc/msg.c */
|
||||
#define __NR_msgget 186
|
||||
__SYSCALL(__NR_msgget, sys_msgget)
|
||||
#define __NR_msgctl 187
|
||||
__SYSCALL(__NR_msgctl, sys_msgctl)
|
||||
__SC_COMP(__NR_msgctl, sys_msgctl, compat_sys_msgctl)
|
||||
#define __NR_msgrcv 188
|
||||
__SYSCALL(__NR_msgrcv, sys_msgrcv)
|
||||
__SC_COMP(__NR_msgrcv, sys_msgrcv, compat_sys_msgrcv)
|
||||
#define __NR_msgsnd 189
|
||||
__SYSCALL(__NR_msgsnd, sys_msgsnd)
|
||||
__SC_COMP(__NR_msgsnd, sys_msgsnd, compat_sys_msgsnd)
|
||||
|
||||
/* ipc/sem.c */
|
||||
#define __NR_semget 190
|
||||
__SYSCALL(__NR_semget, sys_semget)
|
||||
#define __NR_semctl 191
|
||||
__SYSCALL(__NR_semctl, sys_semctl)
|
||||
__SC_COMP(__NR_semctl, sys_semctl, compat_sys_semctl)
|
||||
#define __NR_semtimedop 192
|
||||
__SYSCALL(__NR_semtimedop, sys_semtimedop)
|
||||
__SC_COMP(__NR_semtimedop, sys_semtimedop, compat_sys_semtimedop)
|
||||
#define __NR_semop 193
|
||||
__SYSCALL(__NR_semop, sys_semop)
|
||||
|
||||
@ -517,9 +542,9 @@ __SYSCALL(__NR_semop, sys_semop)
|
||||
#define __NR_shmget 194
|
||||
__SYSCALL(__NR_shmget, sys_shmget)
|
||||
#define __NR_shmctl 195
|
||||
__SYSCALL(__NR_shmctl, sys_shmctl)
|
||||
__SC_COMP(__NR_shmctl, sys_shmctl, compat_sys_shmctl)
|
||||
#define __NR_shmat 196
|
||||
__SYSCALL(__NR_shmat, sys_shmat)
|
||||
__SC_COMP(__NR_shmat, sys_shmat, compat_sys_shmat)
|
||||
#define __NR_shmdt 197
|
||||
__SYSCALL(__NR_shmdt, sys_shmdt)
|
||||
|
||||
@ -543,21 +568,21 @@ __SYSCALL(__NR_getpeername, sys_getpeername)
|
||||
#define __NR_sendto 206
|
||||
__SYSCALL(__NR_sendto, sys_sendto)
|
||||
#define __NR_recvfrom 207
|
||||
__SYSCALL(__NR_recvfrom, sys_recvfrom)
|
||||
__SC_COMP(__NR_recvfrom, sys_recvfrom, compat_sys_recvfrom)
|
||||
#define __NR_setsockopt 208
|
||||
__SYSCALL(__NR_setsockopt, sys_setsockopt)
|
||||
__SC_COMP(__NR_setsockopt, sys_setsockopt, compat_sys_setsockopt)
|
||||
#define __NR_getsockopt 209
|
||||
__SYSCALL(__NR_getsockopt, sys_getsockopt)
|
||||
__SC_COMP(__NR_getsockopt, sys_getsockopt, compat_sys_getsockopt)
|
||||
#define __NR_shutdown 210
|
||||
__SYSCALL(__NR_shutdown, sys_shutdown)
|
||||
#define __NR_sendmsg 211
|
||||
__SYSCALL(__NR_sendmsg, sys_sendmsg)
|
||||
__SC_COMP(__NR_sendmsg, sys_sendmsg, compat_sys_sendmsg)
|
||||
#define __NR_recvmsg 212
|
||||
__SYSCALL(__NR_recvmsg, sys_recvmsg)
|
||||
__SC_COMP(__NR_recvmsg, sys_recvmsg, compat_sys_recvmsg)
|
||||
|
||||
/* mm/filemap.c */
|
||||
#define __NR_readahead 213
|
||||
__SYSCALL(__NR_readahead, sys_readahead)
|
||||
__SC_COMP(__NR_readahead, sys_readahead, compat_sys_readahead)
|
||||
|
||||
/* mm/nommu.c, also with MMU */
|
||||
#define __NR_brk 214
|
||||
@ -573,19 +598,19 @@ __SYSCALL(__NR_add_key, sys_add_key)
|
||||
#define __NR_request_key 218
|
||||
__SYSCALL(__NR_request_key, sys_request_key)
|
||||
#define __NR_keyctl 219
|
||||
__SYSCALL(__NR_keyctl, sys_keyctl)
|
||||
__SC_COMP(__NR_keyctl, sys_keyctl, compat_sys_keyctl)
|
||||
|
||||
/* arch/example/kernel/sys_example.c */
|
||||
#define __NR_clone 220
|
||||
__SYSCALL(__NR_clone, sys_clone) /* .long sys_clone_wrapper */
|
||||
__SYSCALL(__NR_clone, sys_clone)
|
||||
#define __NR_execve 221
|
||||
__SYSCALL(__NR_execve, sys_execve) /* .long sys_execve_wrapper */
|
||||
__SC_COMP(__NR_execve, sys_execve, compat_sys_execve)
|
||||
|
||||
#define __NR3264_mmap 222
|
||||
__SC_3264(__NR3264_mmap, sys_mmap2, sys_mmap)
|
||||
/* mm/fadvise.c */
|
||||
#define __NR3264_fadvise64 223
|
||||
__SYSCALL(__NR3264_fadvise64, sys_fadvise64_64)
|
||||
__SC_COMP(__NR3264_fadvise64, sys_fadvise64_64, compat_sys_fadvise64_64)
|
||||
|
||||
/* mm/, CONFIG_MMU only */
|
||||
#ifndef __ARCH_NOMMU
|
||||
@ -612,25 +637,26 @@ __SYSCALL(__NR_madvise, sys_madvise)
|
||||
#define __NR_remap_file_pages 234
|
||||
__SYSCALL(__NR_remap_file_pages, sys_remap_file_pages)
|
||||
#define __NR_mbind 235
|
||||
__SYSCALL(__NR_mbind, sys_mbind)
|
||||
__SC_COMP(__NR_mbind, sys_mbind, compat_sys_mbind)
|
||||
#define __NR_get_mempolicy 236
|
||||
__SYSCALL(__NR_get_mempolicy, sys_get_mempolicy)
|
||||
__SC_COMP(__NR_get_mempolicy, sys_get_mempolicy, compat_sys_get_mempolicy)
|
||||
#define __NR_set_mempolicy 237
|
||||
__SYSCALL(__NR_set_mempolicy, sys_set_mempolicy)
|
||||
__SC_COMP(__NR_set_mempolicy, sys_set_mempolicy, compat_sys_set_mempolicy)
|
||||
#define __NR_migrate_pages 238
|
||||
__SYSCALL(__NR_migrate_pages, sys_migrate_pages)
|
||||
__SC_COMP(__NR_migrate_pages, sys_migrate_pages, compat_sys_migrate_pages)
|
||||
#define __NR_move_pages 239
|
||||
__SYSCALL(__NR_move_pages, sys_move_pages)
|
||||
__SC_COMP(__NR_move_pages, sys_move_pages, compat_sys_move_pages)
|
||||
#endif
|
||||
|
||||
#define __NR_rt_tgsigqueueinfo 240
|
||||
__SYSCALL(__NR_rt_tgsigqueueinfo, sys_rt_tgsigqueueinfo)
|
||||
__SC_COMP(__NR_rt_tgsigqueueinfo, sys_rt_tgsigqueueinfo, \
|
||||
compat_sys_rt_tgsigqueueinfo)
|
||||
#define __NR_perf_event_open 241
|
||||
__SYSCALL(__NR_perf_event_open, sys_perf_event_open)
|
||||
#define __NR_accept4 242
|
||||
__SYSCALL(__NR_accept4, sys_accept4)
|
||||
#define __NR_recvmmsg 243
|
||||
__SYSCALL(__NR_recvmmsg, sys_recvmmsg)
|
||||
__SC_COMP(__NR_recvmmsg, sys_recvmmsg, compat_sys_recvmmsg)
|
||||
|
||||
/*
|
||||
* Architectures may provide up to 16 syscalls of their own
|
||||
@ -639,19 +665,20 @@ __SYSCALL(__NR_recvmmsg, sys_recvmmsg)
|
||||
#define __NR_arch_specific_syscall 244
|
||||
|
||||
#define __NR_wait4 260
|
||||
__SYSCALL(__NR_wait4, sys_wait4)
|
||||
__SC_COMP(__NR_wait4, sys_wait4, compat_sys_wait4)
|
||||
#define __NR_prlimit64 261
|
||||
__SYSCALL(__NR_prlimit64, sys_prlimit64)
|
||||
#define __NR_fanotify_init 262
|
||||
__SYSCALL(__NR_fanotify_init, sys_fanotify_init)
|
||||
#define __NR_fanotify_mark 263
|
||||
__SYSCALL(__NR_fanotify_mark, sys_fanotify_mark)
|
||||
#define __NR_name_to_handle_at 264
|
||||
#define __NR_name_to_handle_at 264
|
||||
__SYSCALL(__NR_name_to_handle_at, sys_name_to_handle_at)
|
||||
#define __NR_open_by_handle_at 265
|
||||
__SYSCALL(__NR_open_by_handle_at, sys_open_by_handle_at)
|
||||
#define __NR_open_by_handle_at 265
|
||||
__SC_COMP(__NR_open_by_handle_at, sys_open_by_handle_at, \
|
||||
compat_sys_open_by_handle_at)
|
||||
#define __NR_clock_adjtime 266
|
||||
__SYSCALL(__NR_clock_adjtime, sys_clock_adjtime)
|
||||
__SC_COMP(__NR_clock_adjtime, sys_clock_adjtime, compat_sys_clock_adjtime)
|
||||
#define __NR_syncfs 267
|
||||
__SYSCALL(__NR_syncfs, sys_syncfs)
|
||||
|
||||
|
@ -12,6 +12,8 @@
|
||||
#include <linux/sem.h>
|
||||
#include <linux/socket.h>
|
||||
#include <linux/if.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/aio_abi.h> /* for aio_context_t */
|
||||
|
||||
#include <asm/compat.h>
|
||||
#include <asm/siginfo.h>
|
||||
@ -26,7 +28,7 @@ typedef __compat_gid32_t compat_gid_t;
|
||||
struct compat_sel_arg_struct;
|
||||
struct rusage;
|
||||
|
||||
struct compat_itimerspec {
|
||||
struct compat_itimerspec {
|
||||
struct compat_timespec it_interval;
|
||||
struct compat_timespec it_value;
|
||||
};
|
||||
@ -70,9 +72,9 @@ struct compat_timex {
|
||||
compat_long_t stbcnt;
|
||||
compat_int_t tai;
|
||||
|
||||
compat_int_t :32; compat_int_t :32; compat_int_t :32; compat_int_t :32;
|
||||
compat_int_t :32; compat_int_t :32; compat_int_t :32; compat_int_t :32;
|
||||
compat_int_t :32; compat_int_t :32; compat_int_t :32;
|
||||
compat_int_t:32; compat_int_t:32; compat_int_t:32; compat_int_t:32;
|
||||
compat_int_t:32; compat_int_t:32; compat_int_t:32; compat_int_t:32;
|
||||
compat_int_t:32; compat_int_t:32; compat_int_t:32;
|
||||
};
|
||||
|
||||
#define _COMPAT_NSIG_WORDS (_COMPAT_NSIG / _COMPAT_NSIG_BPW)
|
||||
@ -81,8 +83,10 @@ typedef struct {
|
||||
compat_sigset_word sig[_COMPAT_NSIG_WORDS];
|
||||
} compat_sigset_t;
|
||||
|
||||
extern int get_compat_timespec(struct timespec *, const struct compat_timespec __user *);
|
||||
extern int put_compat_timespec(const struct timespec *, struct compat_timespec __user *);
|
||||
extern int get_compat_timespec(struct timespec *,
|
||||
const struct compat_timespec __user *);
|
||||
extern int put_compat_timespec(const struct timespec *,
|
||||
struct compat_timespec __user *);
|
||||
|
||||
struct compat_iovec {
|
||||
compat_uptr_t iov_base;
|
||||
@ -113,7 +117,8 @@ struct compat_rusage {
|
||||
compat_long_t ru_nivcsw;
|
||||
};
|
||||
|
||||
extern int put_compat_rusage(const struct rusage *, struct compat_rusage __user *);
|
||||
extern int put_compat_rusage(const struct rusage *,
|
||||
struct compat_rusage __user *);
|
||||
|
||||
struct compat_siginfo;
|
||||
|
||||
@ -166,8 +171,7 @@ struct compat_ifmap {
|
||||
unsigned char port;
|
||||
};
|
||||
|
||||
struct compat_if_settings
|
||||
{
|
||||
struct compat_if_settings {
|
||||
unsigned int type; /* Type of physical device or protocol */
|
||||
unsigned int size; /* Size of the data allocated by the caller */
|
||||
compat_uptr_t ifs_ifsu; /* union of pointers */
|
||||
@ -195,8 +199,8 @@ struct compat_ifreq {
|
||||
};
|
||||
|
||||
struct compat_ifconf {
|
||||
compat_int_t ifc_len; /* size of buffer */
|
||||
compat_caddr_t ifcbuf;
|
||||
compat_int_t ifc_len; /* size of buffer */
|
||||
compat_caddr_t ifcbuf;
|
||||
};
|
||||
|
||||
struct compat_robust_list {
|
||||
@ -209,6 +213,18 @@ struct compat_robust_list_head {
|
||||
compat_uptr_t list_op_pending;
|
||||
};
|
||||
|
||||
struct compat_statfs;
|
||||
struct compat_statfs64;
|
||||
struct compat_old_linux_dirent;
|
||||
struct compat_linux_dirent;
|
||||
struct linux_dirent64;
|
||||
struct compat_msghdr;
|
||||
struct compat_mmsghdr;
|
||||
struct compat_sysinfo;
|
||||
struct compat_sysctl_args;
|
||||
struct compat_kexec_segment;
|
||||
struct compat_mq_attr;
|
||||
|
||||
extern void compat_exit_robust_list(struct task_struct *curr);
|
||||
|
||||
asmlinkage long
|
||||
@ -243,8 +259,8 @@ asmlinkage ssize_t compat_sys_pwritev(unsigned long fd,
|
||||
const struct compat_iovec __user *vec,
|
||||
unsigned long vlen, u32 pos_low, u32 pos_high);
|
||||
|
||||
int compat_do_execve(char * filename, compat_uptr_t __user *argv,
|
||||
compat_uptr_t __user *envp, struct pt_regs * regs);
|
||||
int compat_do_execve(char *filename, compat_uptr_t __user *argv,
|
||||
compat_uptr_t __user *envp, struct pt_regs *regs);
|
||||
|
||||
asmlinkage long compat_sys_select(int n, compat_ulong_t __user *inp,
|
||||
compat_ulong_t __user *outp, compat_ulong_t __user *exp,
|
||||
@ -331,12 +347,18 @@ asmlinkage long compat_sys_epoll_pwait(int epfd,
|
||||
const compat_sigset_t __user *sigmask,
|
||||
compat_size_t sigsetsize);
|
||||
|
||||
asmlinkage long compat_sys_utimensat(unsigned int dfd, const char __user *filename,
|
||||
struct compat_timespec __user *t, int flags);
|
||||
asmlinkage long compat_sys_utime(const char __user *filename,
|
||||
struct compat_utimbuf __user *t);
|
||||
asmlinkage long compat_sys_utimensat(unsigned int dfd,
|
||||
const char __user *filename,
|
||||
struct compat_timespec __user *t,
|
||||
int flags);
|
||||
|
||||
asmlinkage long compat_sys_time(compat_time_t __user *tloc);
|
||||
asmlinkage long compat_sys_stime(compat_time_t __user *tptr);
|
||||
asmlinkage long compat_sys_signalfd(int ufd,
|
||||
const compat_sigset_t __user *sigmask,
|
||||
compat_size_t sigsetsize);
|
||||
const compat_sigset_t __user *sigmask,
|
||||
compat_size_t sigsetsize);
|
||||
asmlinkage long compat_sys_timerfd_settime(int ufd, int flags,
|
||||
const struct compat_itimerspec __user *utmr,
|
||||
struct compat_itimerspec __user *otmr);
|
||||
@ -348,16 +370,190 @@ asmlinkage long compat_sys_move_pages(pid_t pid, unsigned long nr_page,
|
||||
const int __user *nodes,
|
||||
int __user *status,
|
||||
int flags);
|
||||
asmlinkage long compat_sys_futimesat(unsigned int dfd, const char __user *filename,
|
||||
asmlinkage long compat_sys_futimesat(unsigned int dfd,
|
||||
const char __user *filename,
|
||||
struct compat_timeval __user *t);
|
||||
asmlinkage long compat_sys_newfstatat(unsigned int dfd, const char __user * filename,
|
||||
asmlinkage long compat_sys_utimes(const char __user *filename,
|
||||
struct compat_timeval __user *t);
|
||||
asmlinkage long compat_sys_newstat(const char __user *filename,
|
||||
struct compat_stat __user *statbuf);
|
||||
asmlinkage long compat_sys_newlstat(const char __user *filename,
|
||||
struct compat_stat __user *statbuf);
|
||||
asmlinkage long compat_sys_newfstatat(unsigned int dfd,
|
||||
const char __user *filename,
|
||||
struct compat_stat __user *statbuf,
|
||||
int flag);
|
||||
asmlinkage long compat_sys_newfstat(unsigned int fd,
|
||||
struct compat_stat __user *statbuf);
|
||||
asmlinkage long compat_sys_statfs(const char __user *pathname,
|
||||
struct compat_statfs __user *buf);
|
||||
asmlinkage long compat_sys_fstatfs(unsigned int fd,
|
||||
struct compat_statfs __user *buf);
|
||||
asmlinkage long compat_sys_statfs64(const char __user *pathname,
|
||||
compat_size_t sz,
|
||||
struct compat_statfs64 __user *buf);
|
||||
asmlinkage long compat_sys_fstatfs64(unsigned int fd, compat_size_t sz,
|
||||
struct compat_statfs64 __user *buf);
|
||||
asmlinkage long compat_sys_fcntl64(unsigned int fd, unsigned int cmd,
|
||||
unsigned long arg);
|
||||
asmlinkage long compat_sys_fcntl(unsigned int fd, unsigned int cmd,
|
||||
unsigned long arg);
|
||||
asmlinkage long compat_sys_io_setup(unsigned nr_reqs, u32 __user *ctx32p);
|
||||
asmlinkage long compat_sys_io_getevents(aio_context_t ctx_id,
|
||||
unsigned long min_nr,
|
||||
unsigned long nr,
|
||||
struct io_event __user *events,
|
||||
struct compat_timespec __user *timeout);
|
||||
asmlinkage long compat_sys_io_submit(aio_context_t ctx_id, int nr,
|
||||
u32 __user *iocb);
|
||||
asmlinkage long compat_sys_mount(const char __user *dev_name,
|
||||
const char __user *dir_name,
|
||||
const char __user *type, unsigned long flags,
|
||||
const void __user *data);
|
||||
asmlinkage long compat_sys_old_readdir(unsigned int fd,
|
||||
struct compat_old_linux_dirent __user *,
|
||||
unsigned int count);
|
||||
asmlinkage long compat_sys_getdents(unsigned int fd,
|
||||
struct compat_linux_dirent __user *dirent,
|
||||
unsigned int count);
|
||||
asmlinkage long compat_sys_getdents64(unsigned int fd,
|
||||
struct linux_dirent64 __user *dirent,
|
||||
unsigned int count);
|
||||
asmlinkage long compat_sys_vmsplice(int fd, const struct compat_iovec __user *,
|
||||
unsigned int nr_segs, unsigned int flags);
|
||||
asmlinkage long compat_sys_open(const char __user *filename, int flags,
|
||||
int mode);
|
||||
asmlinkage long compat_sys_openat(unsigned int dfd, const char __user *filename,
|
||||
int flags, int mode);
|
||||
asmlinkage long compat_sys_open_by_handle_at(int mountdirfd,
|
||||
struct file_handle __user *handle,
|
||||
int flags);
|
||||
asmlinkage long compat_sys_pselect6(int n, compat_ulong_t __user *inp,
|
||||
compat_ulong_t __user *outp,
|
||||
compat_ulong_t __user *exp,
|
||||
struct compat_timespec __user *tsp,
|
||||
void __user *sig);
|
||||
asmlinkage long compat_sys_ppoll(struct pollfd __user *ufds,
|
||||
unsigned int nfds,
|
||||
struct compat_timespec __user *tsp,
|
||||
const compat_sigset_t __user *sigmask,
|
||||
compat_size_t sigsetsize);
|
||||
#if (defined(CONFIG_NFSD) || defined(CONFIG_NFSD_MODULE)) && \
|
||||
!defined(CONFIG_NFSD_DEPRECATED)
|
||||
union compat_nfsctl_res;
|
||||
struct compat_nfsctl_arg;
|
||||
asmlinkage long compat_sys_nfsservctl(int cmd,
|
||||
struct compat_nfsctl_arg __user *arg,
|
||||
union compat_nfsctl_res __user *res);
|
||||
#else
|
||||
asmlinkage long compat_sys_nfsservctl(int cmd, void *notused, void *notused2);
|
||||
#endif
|
||||
asmlinkage long compat_sys_signalfd4(int ufd,
|
||||
const compat_sigset_t __user *sigmask,
|
||||
compat_size_t sigsetsize, int flags);
|
||||
asmlinkage long compat_sys_get_mempolicy(int __user *policy,
|
||||
compat_ulong_t __user *nmask,
|
||||
compat_ulong_t maxnode,
|
||||
compat_ulong_t addr,
|
||||
compat_ulong_t flags);
|
||||
asmlinkage long compat_sys_set_mempolicy(int mode, compat_ulong_t __user *nmask,
|
||||
compat_ulong_t maxnode);
|
||||
asmlinkage long compat_sys_mbind(compat_ulong_t start, compat_ulong_t len,
|
||||
compat_ulong_t mode,
|
||||
compat_ulong_t __user *nmask,
|
||||
compat_ulong_t maxnode, compat_ulong_t flags);
|
||||
|
||||
asmlinkage long compat_sys_setsockopt(int fd, int level, int optname,
|
||||
char __user *optval, unsigned int optlen);
|
||||
asmlinkage long compat_sys_sendmsg(int fd, struct compat_msghdr __user *msg,
|
||||
unsigned flags);
|
||||
asmlinkage long compat_sys_recvmsg(int fd, struct compat_msghdr __user *msg,
|
||||
unsigned int flags);
|
||||
asmlinkage long compat_sys_recv(int fd, void __user *buf, size_t len,
|
||||
unsigned flags);
|
||||
asmlinkage long compat_sys_recvfrom(int fd, void __user *buf, size_t len,
|
||||
unsigned flags, struct sockaddr __user *addr,
|
||||
int __user *addrlen);
|
||||
asmlinkage long compat_sys_recvmmsg(int fd, struct compat_mmsghdr __user *mmsg,
|
||||
unsigned vlen, unsigned int flags,
|
||||
struct compat_timespec __user *timeout);
|
||||
asmlinkage long compat_sys_nanosleep(struct compat_timespec __user *rqtp,
|
||||
struct compat_timespec __user *rmtp);
|
||||
asmlinkage long compat_sys_getitimer(int which,
|
||||
struct compat_itimerval __user *it);
|
||||
asmlinkage long compat_sys_setitimer(int which,
|
||||
struct compat_itimerval __user *in,
|
||||
struct compat_itimerval __user *out);
|
||||
asmlinkage long compat_sys_times(struct compat_tms __user *tbuf);
|
||||
asmlinkage long compat_sys_setrlimit(unsigned int resource,
|
||||
struct compat_rlimit __user *rlim);
|
||||
asmlinkage long compat_sys_getrlimit(unsigned int resource,
|
||||
struct compat_rlimit __user *rlim);
|
||||
asmlinkage long compat_sys_getrusage(int who, struct compat_rusage __user *ru);
|
||||
asmlinkage long compat_sys_sched_setaffinity(compat_pid_t pid,
|
||||
unsigned int len,
|
||||
compat_ulong_t __user *user_mask_ptr);
|
||||
asmlinkage long compat_sys_sched_getaffinity(compat_pid_t pid,
|
||||
unsigned int len,
|
||||
compat_ulong_t __user *user_mask_ptr);
|
||||
asmlinkage long compat_sys_timer_create(clockid_t which_clock,
|
||||
struct compat_sigevent __user *timer_event_spec,
|
||||
timer_t __user *created_timer_id);
|
||||
asmlinkage long compat_sys_timer_settime(timer_t timer_id, int flags,
|
||||
struct compat_itimerspec __user *new,
|
||||
struct compat_itimerspec __user *old);
|
||||
asmlinkage long compat_sys_timer_gettime(timer_t timer_id,
|
||||
struct compat_itimerspec __user *setting);
|
||||
asmlinkage long compat_sys_clock_settime(clockid_t which_clock,
|
||||
struct compat_timespec __user *tp);
|
||||
asmlinkage long compat_sys_clock_gettime(clockid_t which_clock,
|
||||
struct compat_timespec __user *tp);
|
||||
asmlinkage long compat_sys_clock_adjtime(clockid_t which_clock,
|
||||
struct compat_timex __user *tp);
|
||||
asmlinkage long compat_sys_clock_getres(clockid_t which_clock,
|
||||
struct compat_timespec __user *tp);
|
||||
asmlinkage long compat_sys_clock_nanosleep(clockid_t which_clock, int flags,
|
||||
struct compat_timespec __user *rqtp,
|
||||
struct compat_timespec __user *rmtp);
|
||||
asmlinkage long compat_sys_rt_sigtimedwait(compat_sigset_t __user *uthese,
|
||||
struct compat_siginfo __user *uinfo,
|
||||
struct compat_timespec __user *uts, compat_size_t sigsetsize);
|
||||
asmlinkage long compat_sys_rt_sigsuspend(compat_sigset_t __user *unewset,
|
||||
compat_size_t sigsetsize);
|
||||
asmlinkage long compat_sys_sysinfo(struct compat_sysinfo __user *info);
|
||||
asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd,
|
||||
unsigned long arg);
|
||||
asmlinkage long compat_sys_futex(u32 __user *uaddr, int op, u32 val,
|
||||
struct compat_timespec __user *utime, u32 __user *uaddr2,
|
||||
u32 val3);
|
||||
asmlinkage long compat_sys_getsockopt(int fd, int level, int optname,
|
||||
char __user *optval, int __user *optlen);
|
||||
asmlinkage long compat_sys_kexec_load(unsigned long entry,
|
||||
unsigned long nr_segments,
|
||||
struct compat_kexec_segment __user *,
|
||||
unsigned long flags);
|
||||
asmlinkage long compat_sys_mq_getsetattr(mqd_t mqdes,
|
||||
const struct compat_mq_attr __user *u_mqstat,
|
||||
struct compat_mq_attr __user *u_omqstat);
|
||||
asmlinkage long compat_sys_mq_notify(mqd_t mqdes,
|
||||
const struct compat_sigevent __user *u_notification);
|
||||
asmlinkage long compat_sys_mq_open(const char __user *u_name,
|
||||
int oflag, compat_mode_t mode,
|
||||
struct compat_mq_attr __user *u_attr);
|
||||
asmlinkage long compat_sys_mq_timedsend(mqd_t mqdes,
|
||||
const char __user *u_msg_ptr,
|
||||
size_t msg_len, unsigned int msg_prio,
|
||||
const struct compat_timespec __user *u_abs_timeout);
|
||||
asmlinkage ssize_t compat_sys_mq_timedreceive(mqd_t mqdes,
|
||||
char __user *u_msg_ptr,
|
||||
size_t msg_len, unsigned int __user *u_msg_prio,
|
||||
const struct compat_timespec __user *u_abs_timeout);
|
||||
asmlinkage long compat_sys_socketcall(int call, u32 __user *args);
|
||||
asmlinkage long compat_sys_sysctl(struct compat_sysctl_args __user *args);
|
||||
|
||||
extern ssize_t compat_rw_copy_check_uvector(int type,
|
||||
const struct compat_iovec __user *uvector, unsigned long nr_segs,
|
||||
const struct compat_iovec __user *uvector,
|
||||
unsigned long nr_segs,
|
||||
unsigned long fast_segs, struct iovec *fast_pointer,
|
||||
struct iovec **ret_pointer);
|
||||
|
||||
|
@ -293,6 +293,8 @@ asmlinkage long compat_sys_times(struct compat_tms __user *tbuf)
|
||||
return compat_jiffies_to_clock_t(jiffies);
|
||||
}
|
||||
|
||||
#ifdef __ARCH_WANT_SYS_SIGPENDING
|
||||
|
||||
/*
|
||||
* Assumption: old_sigset_t and compat_old_sigset_t are both
|
||||
* types that can be passed to put_user()/get_user().
|
||||
@ -312,6 +314,10 @@ asmlinkage long compat_sys_sigpending(compat_old_sigset_t __user *set)
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __ARCH_WANT_SYS_SIGPROCMASK
|
||||
|
||||
asmlinkage long compat_sys_sigprocmask(int how, compat_old_sigset_t __user *set,
|
||||
compat_old_sigset_t __user *oset)
|
||||
{
|
||||
@ -333,6 +339,8 @@ asmlinkage long compat_sys_sigprocmask(int how, compat_old_sigset_t __user *set,
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
asmlinkage long compat_sys_setrlimit(unsigned int resource,
|
||||
struct compat_rlimit __user *rlim)
|
||||
{
|
||||
|
@ -1506,7 +1506,7 @@ static struct ctl_table fs_table[] = {
|
||||
|
||||
static struct ctl_table debug_table[] = {
|
||||
#if defined(CONFIG_X86) || defined(CONFIG_PPC) || defined(CONFIG_SPARC) || \
|
||||
defined(CONFIG_S390)
|
||||
defined(CONFIG_S390) || defined(CONFIG_TILE)
|
||||
{
|
||||
.procname = "exception-trace",
|
||||
.data = &show_unhandled_signals,
|
||||
|
@ -36,8 +36,10 @@ int audit_classify_arch(int arch)
|
||||
int audit_classify_syscall(int abi, unsigned syscall)
|
||||
{
|
||||
switch(syscall) {
|
||||
#ifdef __NR_open
|
||||
case __NR_open:
|
||||
return 2;
|
||||
#endif
|
||||
#ifdef __NR_openat
|
||||
case __NR_openat:
|
||||
return 3;
|
||||
|
Loading…
Reference in New Issue
Block a user