Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net

Several cases of bug fixes in 'net' overlapping other changes in
'net-next-.

Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
David S. Miller 2016-11-15 10:54:36 -05:00
commit bb598c1b8c
580 changed files with 7322 additions and 4039 deletions

View File

@ -1,4 +1,4 @@
What: state What: /sys/devices/system/ibm_rtl/state
Date: Sep 2010 Date: Sep 2010
KernelVersion: 2.6.37 KernelVersion: 2.6.37
Contact: Vernon Mauery <vernux@us.ibm.com> Contact: Vernon Mauery <vernux@us.ibm.com>
@ -10,7 +10,7 @@ Description: The state file allows a means by which to change in and
Users: The ibm-prtm userspace daemon uses this interface. Users: The ibm-prtm userspace daemon uses this interface.
What: version What: /sys/devices/system/ibm_rtl/version
Date: Sep 2010 Date: Sep 2010
KernelVersion: 2.6.37 KernelVersion: 2.6.37
Contact: Vernon Mauery <vernux@us.ibm.com> Contact: Vernon Mauery <vernux@us.ibm.com>

View File

@ -43,6 +43,9 @@ Optional properties:
reset signal present internally in some host controller IC designs. reset signal present internally in some host controller IC designs.
See Documentation/devicetree/bindings/reset/reset.txt for details. See Documentation/devicetree/bindings/reset/reset.txt for details.
* reset-names: request name for using "resets" property. Must be "reset".
(It will be used together with "resets" property.)
* clocks: from common clock binding: handle to biu and ciu clocks for the * clocks: from common clock binding: handle to biu and ciu clocks for the
bus interface unit clock and the card interface unit clock. bus interface unit clock and the card interface unit clock.
@ -103,6 +106,8 @@ board specific portions as listed below.
interrupts = <0 75 0>; interrupts = <0 75 0>;
#address-cells = <1>; #address-cells = <1>;
#size-cells = <0>; #size-cells = <0>;
resets = <&rst 20>;
reset-names = "reset";
}; };
[board specific internal DMA resources] [board specific internal DMA resources]

View File

@ -26,13 +26,16 @@ Required properties:
- "sys" - "sys"
- "legacy" - "legacy"
- "client" - "client"
- resets: Must contain five entries for each entry in reset-names. - resets: Must contain seven entries for each entry in reset-names.
See ../reset/reset.txt for details. See ../reset/reset.txt for details.
- reset-names: Must include the following names - reset-names: Must include the following names
- "core" - "core"
- "mgmt" - "mgmt"
- "mgmt-sticky" - "mgmt-sticky"
- "pipe" - "pipe"
- "pm"
- "aclk"
- "pclk"
- pinctrl-names : The pin control state names - pinctrl-names : The pin control state names
- pinctrl-0: The "default" pinctrl state - pinctrl-0: The "default" pinctrl state
- #interrupt-cells: specifies the number of cells needed to encode an - #interrupt-cells: specifies the number of cells needed to encode an
@ -86,8 +89,10 @@ pcie0: pcie@f8000000 {
reg = <0x0 0xf8000000 0x0 0x2000000>, <0x0 0xfd000000 0x0 0x1000000>; reg = <0x0 0xf8000000 0x0 0x2000000>, <0x0 0xfd000000 0x0 0x1000000>;
reg-names = "axi-base", "apb-base"; reg-names = "axi-base", "apb-base";
resets = <&cru SRST_PCIE_CORE>, <&cru SRST_PCIE_MGMT>, resets = <&cru SRST_PCIE_CORE>, <&cru SRST_PCIE_MGMT>,
<&cru SRST_PCIE_MGMT_STICKY>, <&cru SRST_PCIE_PIPE>; <&cru SRST_PCIE_MGMT_STICKY>, <&cru SRST_PCIE_PIPE> ,
reset-names = "core", "mgmt", "mgmt-sticky", "pipe"; <&cru SRST_PCIE_PM>, <&cru SRST_P_PCIE>, <&cru SRST_A_PCIE>;
reset-names = "core", "mgmt", "mgmt-sticky", "pipe",
"pm", "pclk", "aclk";
phys = <&pcie_phy>; phys = <&pcie_phy>;
phy-names = "pcie-phy"; phy-names = "pcie-phy";
pinctrl-names = "default"; pinctrl-names = "default";

View File

@ -14,11 +14,6 @@ Required properies:
- #size-cells : The value of this property must be 1 - #size-cells : The value of this property must be 1
- ranges : defines mapping between pin controller node (parent) to - ranges : defines mapping between pin controller node (parent) to
gpio-bank node (children). gpio-bank node (children).
- interrupt-parent: phandle of the interrupt parent to which the external
GPIO interrupts are forwarded to.
- st,syscfg: Should be phandle/offset pair. The phandle to the syscon node
which includes IRQ mux selection register, and the offset of the IRQ mux
selection register.
- pins-are-numbered: Specify the subnodes are using numbered pinmux to - pins-are-numbered: Specify the subnodes are using numbered pinmux to
specify pins. specify pins.
@ -37,6 +32,11 @@ Required properties:
Optional properties: Optional properties:
- reset: : Reference to the reset controller - reset: : Reference to the reset controller
- interrupt-parent: phandle of the interrupt parent to which the external
GPIO interrupts are forwarded to.
- st,syscfg: Should be phandle/offset pair. The phandle to the syscon node
which includes IRQ mux selection register, and the offset of the IRQ mux
selection register.
Example: Example:
#include <dt-bindings/pinctrl/stm32f429-pinfunc.h> #include <dt-bindings/pinctrl/stm32f429-pinfunc.h>

View File

@ -447,7 +447,6 @@ prototypes:
int (*flush) (struct file *); int (*flush) (struct file *);
int (*release) (struct inode *, struct file *); int (*release) (struct inode *, struct file *);
int (*fsync) (struct file *, loff_t start, loff_t end, int datasync); int (*fsync) (struct file *, loff_t start, loff_t end, int datasync);
int (*aio_fsync) (struct kiocb *, int datasync);
int (*fasync) (int, struct file *, int); int (*fasync) (int, struct file *, int);
int (*lock) (struct file *, int, struct file_lock *); int (*lock) (struct file *, int, struct file_lock *);
ssize_t (*readv) (struct file *, const struct iovec *, unsigned long, ssize_t (*readv) (struct file *, const struct iovec *, unsigned long,

View File

@ -828,7 +828,6 @@ struct file_operations {
int (*flush) (struct file *, fl_owner_t id); int (*flush) (struct file *, fl_owner_t id);
int (*release) (struct inode *, struct file *); int (*release) (struct inode *, struct file *);
int (*fsync) (struct file *, loff_t, loff_t, int datasync); int (*fsync) (struct file *, loff_t, loff_t, int datasync);
int (*aio_fsync) (struct kiocb *, int datasync);
int (*fasync) (int, struct file *, int); int (*fasync) (int, struct file *, int);
int (*lock) (struct file *, int, struct file_lock *); int (*lock) (struct file *, int, struct file_lock *);
ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int); ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);

View File

@ -67,13 +67,14 @@ Note that DSA does not currently create network interfaces for the "cpu" and
Switch tagging protocols Switch tagging protocols
------------------------ ------------------------
DSA currently supports 4 different tagging protocols, and a tag-less mode as DSA currently supports 5 different tagging protocols, and a tag-less mode as
well. The different protocols are implemented in: well. The different protocols are implemented in:
net/dsa/tag_trailer.c: Marvell's 4 trailer tag mode (legacy) net/dsa/tag_trailer.c: Marvell's 4 trailer tag mode (legacy)
net/dsa/tag_dsa.c: Marvell's original DSA tag net/dsa/tag_dsa.c: Marvell's original DSA tag
net/dsa/tag_edsa.c: Marvell's enhanced DSA tag net/dsa/tag_edsa.c: Marvell's enhanced DSA tag
net/dsa/tag_brcm.c: Broadcom's 4 bytes tag net/dsa/tag_brcm.c: Broadcom's 4 bytes tag
net/dsa/tag_qca.c: Qualcomm's 2 bytes tag
The exact format of the tag protocol is vendor specific, but in general, they The exact format of the tag protocol is vendor specific, but in general, they
all contain something which: all contain something which:

View File

@ -4,7 +4,17 @@ KVM Lock Overview
1. Acquisition Orders 1. Acquisition Orders
--------------------- ---------------------
(to be written) The acquisition orders for mutexes are as follows:
- kvm->lock is taken outside vcpu->mutex
- kvm->lock is taken outside kvm->slots_lock and kvm->irq_lock
- kvm->slots_lock is taken outside kvm->irq_lock, though acquiring
them together is quite rare.
For spinlocks, kvm_lock is taken outside kvm->mmu_lock. Everything
else is a leaf: no other lock is taken inside the critical sections.
2: Exception 2: Exception
------------ ------------

View File

@ -7927,6 +7927,10 @@ F: mm/
MEMORY TECHNOLOGY DEVICES (MTD) MEMORY TECHNOLOGY DEVICES (MTD)
M: David Woodhouse <dwmw2@infradead.org> M: David Woodhouse <dwmw2@infradead.org>
M: Brian Norris <computersforpeace@gmail.com> M: Brian Norris <computersforpeace@gmail.com>
M: Boris Brezillon <boris.brezillon@free-electrons.com>
M: Marek Vasut <marek.vasut@gmail.com>
M: Richard Weinberger <richard@nod.at>
M: Cyrille Pitchen <cyrille.pitchen@atmel.com>
L: linux-mtd@lists.infradead.org L: linux-mtd@lists.infradead.org
W: http://www.linux-mtd.infradead.org/ W: http://www.linux-mtd.infradead.org/
Q: http://patchwork.ozlabs.org/project/linux-mtd/list/ Q: http://patchwork.ozlabs.org/project/linux-mtd/list/
@ -8055,6 +8059,7 @@ F: drivers/infiniband/hw/mlx4/
F: include/linux/mlx4/ F: include/linux/mlx4/
MELLANOX MLX5 core VPI driver MELLANOX MLX5 core VPI driver
M: Saeed Mahameed <saeedm@mellanox.com>
M: Matan Barak <matanb@mellanox.com> M: Matan Barak <matanb@mellanox.com>
M: Leon Romanovsky <leonro@mellanox.com> M: Leon Romanovsky <leonro@mellanox.com>
L: netdev@vger.kernel.org L: netdev@vger.kernel.org
@ -9332,7 +9337,7 @@ PCI DRIVER FOR INTEL VOLUME MANAGEMENT DEVICE (VMD)
M: Keith Busch <keith.busch@intel.com> M: Keith Busch <keith.busch@intel.com>
L: linux-pci@vger.kernel.org L: linux-pci@vger.kernel.org
S: Supported S: Supported
F: arch/x86/pci/vmd.c F: drivers/pci/host/vmd.c
PCIE DRIVER FOR ST SPEAR13XX PCIE DRIVER FOR ST SPEAR13XX
M: Pratyush Anand <pratyush.anand@gmail.com> M: Pratyush Anand <pratyush.anand@gmail.com>
@ -11405,6 +11410,17 @@ W: http://www.st.com/spear
S: Maintained S: Maintained
F: drivers/clk/spear/ F: drivers/clk/spear/
SPI NOR SUBSYSTEM
M: Cyrille Pitchen <cyrille.pitchen@atmel.com>
M: Marek Vasut <marek.vasut@gmail.com>
L: linux-mtd@lists.infradead.org
W: http://www.linux-mtd.infradead.org/
Q: http://patchwork.ozlabs.org/project/linux-mtd/list/
T: git git://github.com/spi-nor/linux.git
S: Maintained
F: drivers/mtd/spi-nor/
F: include/linux/mtd/spi-nor.h
SPI SUBSYSTEM SPI SUBSYSTEM
M: Mark Brown <broonie@kernel.org> M: Mark Brown <broonie@kernel.org>
L: linux-spi@vger.kernel.org L: linux-spi@vger.kernel.org
@ -12784,6 +12800,7 @@ F: include/uapi/linux/virtio_console.h
VIRTIO CORE, NET AND BLOCK DRIVERS VIRTIO CORE, NET AND BLOCK DRIVERS
M: "Michael S. Tsirkin" <mst@redhat.com> M: "Michael S. Tsirkin" <mst@redhat.com>
M: Jason Wang <jasowang@redhat.com>
L: virtualization@lists.linux-foundation.org L: virtualization@lists.linux-foundation.org
S: Maintained S: Maintained
F: Documentation/devicetree/bindings/virtio/ F: Documentation/devicetree/bindings/virtio/
@ -12814,6 +12831,7 @@ F: include/uapi/linux/virtio_gpu.h
VIRTIO HOST (VHOST) VIRTIO HOST (VHOST)
M: "Michael S. Tsirkin" <mst@redhat.com> M: "Michael S. Tsirkin" <mst@redhat.com>
M: Jason Wang <jasowang@redhat.com>
L: kvm@vger.kernel.org L: kvm@vger.kernel.org
L: virtualization@lists.linux-foundation.org L: virtualization@lists.linux-foundation.org
L: netdev@vger.kernel.org L: netdev@vger.kernel.org

View File

@ -1,7 +1,7 @@
VERSION = 4 VERSION = 4
PATCHLEVEL = 9 PATCHLEVEL = 9
SUBLEVEL = 0 SUBLEVEL = 0
EXTRAVERSION = -rc3 EXTRAVERSION = -rc5
NAME = Psychotic Stoned Sheep NAME = Psychotic Stoned Sheep
# *DOCUMENTATION* # *DOCUMENTATION*
@ -370,7 +370,7 @@ LDFLAGS_MODULE =
CFLAGS_KERNEL = CFLAGS_KERNEL =
AFLAGS_KERNEL = AFLAGS_KERNEL =
LDFLAGS_vmlinux = LDFLAGS_vmlinux =
CFLAGS_GCOV = -fprofile-arcs -ftest-coverage -fno-tree-loop-im CFLAGS_GCOV = -fprofile-arcs -ftest-coverage -fno-tree-loop-im -Wno-maybe-uninitialized
CFLAGS_KCOV := $(call cc-option,-fsanitize-coverage=trace-pc,) CFLAGS_KCOV := $(call cc-option,-fsanitize-coverage=trace-pc,)
@ -620,7 +620,6 @@ ARCH_CFLAGS :=
include arch/$(SRCARCH)/Makefile include arch/$(SRCARCH)/Makefile
KBUILD_CFLAGS += $(call cc-option,-fno-delete-null-pointer-checks,) KBUILD_CFLAGS += $(call cc-option,-fno-delete-null-pointer-checks,)
KBUILD_CFLAGS += $(call cc-disable-warning,maybe-uninitialized,)
KBUILD_CFLAGS += $(call cc-disable-warning,frame-address,) KBUILD_CFLAGS += $(call cc-disable-warning,frame-address,)
ifdef CONFIG_LD_DEAD_CODE_DATA_ELIMINATION ifdef CONFIG_LD_DEAD_CODE_DATA_ELIMINATION
@ -629,15 +628,18 @@ KBUILD_CFLAGS += $(call cc-option,-fdata-sections,)
endif endif
ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE
KBUILD_CFLAGS += -Os KBUILD_CFLAGS += -Os $(call cc-disable-warning,maybe-uninitialized,)
else else
ifdef CONFIG_PROFILE_ALL_BRANCHES ifdef CONFIG_PROFILE_ALL_BRANCHES
KBUILD_CFLAGS += -O2 KBUILD_CFLAGS += -O2 $(call cc-disable-warning,maybe-uninitialized,)
else else
KBUILD_CFLAGS += -O2 KBUILD_CFLAGS += -O2
endif endif
endif endif
KBUILD_CFLAGS += $(call cc-ifversion, -lt, 0409, \
$(call cc-disable-warning,maybe-uninitialized,))
# Tell gcc to never replace conditional load with a non-conditional one # Tell gcc to never replace conditional load with a non-conditional one
KBUILD_CFLAGS += $(call cc-option,--param=allow-store-data-races=0) KBUILD_CFLAGS += $(call cc-option,--param=allow-store-data-races=0)

View File

@ -50,6 +50,9 @@ atleast_gcc44 := $(call cc-ifversion, -ge, 0404, y)
cflags-$(atleast_gcc44) += -fsection-anchors cflags-$(atleast_gcc44) += -fsection-anchors
cflags-$(CONFIG_ARC_HAS_LLSC) += -mlock
cflags-$(CONFIG_ARC_HAS_SWAPE) += -mswape
ifdef CONFIG_ISA_ARCV2 ifdef CONFIG_ISA_ARCV2
ifndef CONFIG_ARC_HAS_LL64 ifndef CONFIG_ARC_HAS_LL64
@ -68,7 +71,9 @@ cflags-$(CONFIG_ARC_DW2_UNWIND) += -fasynchronous-unwind-tables $(cfi)
ifndef CONFIG_CC_OPTIMIZE_FOR_SIZE ifndef CONFIG_CC_OPTIMIZE_FOR_SIZE
# Generic build system uses -O2, we want -O3 # Generic build system uses -O2, we want -O3
# Note: No need to add to cflags-y as that happens anyways # Note: No need to add to cflags-y as that happens anyways
ARCH_CFLAGS += -O3 #
# Disable the false maybe-uninitialized warings gcc spits out at -O3
ARCH_CFLAGS += -O3 $(call cc-disable-warning,maybe-uninitialized,)
endif endif
# small data is default for elf32 tool-chain. If not usable, disable it # small data is default for elf32 tool-chain. If not usable, disable it

View File

@ -71,7 +71,7 @@
reg-io-width = <4>; reg-io-width = <4>;
}; };
arcpmu0: pmu { arcpct0: pct {
compatible = "snps,arc700-pct"; compatible = "snps,arc700-pct";
}; };
}; };

View File

@ -69,7 +69,7 @@
}; };
}; };
arcpmu0: pmu { arcpct0: pct {
compatible = "snps,arc700-pct"; compatible = "snps,arc700-pct";
}; };
}; };

View File

@ -83,5 +83,9 @@
reg = <0xf0003000 0x44>; reg = <0xf0003000 0x44>;
interrupts = <7>; interrupts = <7>;
}; };
arcpct0: pct {
compatible = "snps,arc700-pct";
};
}; };
}; };

View File

@ -14,6 +14,7 @@ CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE="../arc_initramfs/" CONFIG_INITRAMFS_SOURCE="../arc_initramfs/"
CONFIG_KALLSYMS_ALL=y CONFIG_KALLSYMS_ALL=y
CONFIG_EMBEDDED=y CONFIG_EMBEDDED=y
CONFIG_PERF_EVENTS=y
# CONFIG_SLUB_DEBUG is not set # CONFIG_SLUB_DEBUG is not set
# CONFIG_COMPAT_BRK is not set # CONFIG_COMPAT_BRK is not set
CONFIG_KPROBES=y CONFIG_KPROBES=y

View File

@ -14,6 +14,7 @@ CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE="../../arc_initramfs_hs/" CONFIG_INITRAMFS_SOURCE="../../arc_initramfs_hs/"
CONFIG_KALLSYMS_ALL=y CONFIG_KALLSYMS_ALL=y
CONFIG_EMBEDDED=y CONFIG_EMBEDDED=y
CONFIG_PERF_EVENTS=y
# CONFIG_SLUB_DEBUG is not set # CONFIG_SLUB_DEBUG is not set
# CONFIG_COMPAT_BRK is not set # CONFIG_COMPAT_BRK is not set
CONFIG_KPROBES=y CONFIG_KPROBES=y

View File

@ -12,6 +12,7 @@ CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE="../arc_initramfs_hs/" CONFIG_INITRAMFS_SOURCE="../arc_initramfs_hs/"
CONFIG_KALLSYMS_ALL=y CONFIG_KALLSYMS_ALL=y
CONFIG_EMBEDDED=y CONFIG_EMBEDDED=y
CONFIG_PERF_EVENTS=y
# CONFIG_SLUB_DEBUG is not set # CONFIG_SLUB_DEBUG is not set
# CONFIG_COMPAT_BRK is not set # CONFIG_COMPAT_BRK is not set
CONFIG_KPROBES=y CONFIG_KPROBES=y

View File

@ -14,6 +14,7 @@ CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE="../arc_initramfs/" CONFIG_INITRAMFS_SOURCE="../arc_initramfs/"
CONFIG_KALLSYMS_ALL=y CONFIG_KALLSYMS_ALL=y
CONFIG_EMBEDDED=y CONFIG_EMBEDDED=y
CONFIG_PERF_EVENTS=y
# CONFIG_SLUB_DEBUG is not set # CONFIG_SLUB_DEBUG is not set
# CONFIG_COMPAT_BRK is not set # CONFIG_COMPAT_BRK is not set
CONFIG_KPROBES=y CONFIG_KPROBES=y

View File

@ -14,6 +14,7 @@ CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE="../arc_initramfs_hs/" CONFIG_INITRAMFS_SOURCE="../arc_initramfs_hs/"
CONFIG_KALLSYMS_ALL=y CONFIG_KALLSYMS_ALL=y
CONFIG_EMBEDDED=y CONFIG_EMBEDDED=y
CONFIG_PERF_EVENTS=y
# CONFIG_SLUB_DEBUG is not set # CONFIG_SLUB_DEBUG is not set
# CONFIG_COMPAT_BRK is not set # CONFIG_COMPAT_BRK is not set
CONFIG_KPROBES=y CONFIG_KPROBES=y

View File

@ -10,6 +10,7 @@ CONFIG_IKCONFIG_PROC=y
# CONFIG_PID_NS is not set # CONFIG_PID_NS is not set
CONFIG_BLK_DEV_INITRD=y CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE="../arc_initramfs_hs/" CONFIG_INITRAMFS_SOURCE="../arc_initramfs_hs/"
CONFIG_PERF_EVENTS=y
# CONFIG_COMPAT_BRK is not set # CONFIG_COMPAT_BRK is not set
CONFIG_KPROBES=y CONFIG_KPROBES=y
CONFIG_MODULES=y CONFIG_MODULES=y
@ -34,7 +35,6 @@ CONFIG_INET=y
# CONFIG_INET_XFRM_MODE_TRANSPORT is not set # CONFIG_INET_XFRM_MODE_TRANSPORT is not set
# CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_TUNNEL is not set
# CONFIG_INET_XFRM_MODE_BEET is not set # CONFIG_INET_XFRM_MODE_BEET is not set
# CONFIG_INET_LRO is not set
# CONFIG_IPV6 is not set # CONFIG_IPV6 is not set
# CONFIG_WIRELESS is not set # CONFIG_WIRELESS is not set
CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS=y
@ -72,7 +72,6 @@ CONFIG_SERIAL_OF_PLATFORM=y
# CONFIG_HWMON is not set # CONFIG_HWMON is not set
CONFIG_DRM=y CONFIG_DRM=y
CONFIG_DRM_ARCPGU=y CONFIG_DRM_ARCPGU=y
CONFIG_FRAMEBUFFER_CONSOLE=y
CONFIG_LOGO=y CONFIG_LOGO=y
# CONFIG_HID is not set # CONFIG_HID is not set
# CONFIG_USB_SUPPORT is not set # CONFIG_USB_SUPPORT is not set

View File

@ -43,12 +43,14 @@
#define STATUS_AE_BIT 5 /* Exception active */ #define STATUS_AE_BIT 5 /* Exception active */
#define STATUS_DE_BIT 6 /* PC is in delay slot */ #define STATUS_DE_BIT 6 /* PC is in delay slot */
#define STATUS_U_BIT 7 /* User/Kernel mode */ #define STATUS_U_BIT 7 /* User/Kernel mode */
#define STATUS_Z_BIT 11
#define STATUS_L_BIT 12 /* Loop inhibit */ #define STATUS_L_BIT 12 /* Loop inhibit */
/* These masks correspond to the status word(STATUS_32) bits */ /* These masks correspond to the status word(STATUS_32) bits */
#define STATUS_AE_MASK (1<<STATUS_AE_BIT) #define STATUS_AE_MASK (1<<STATUS_AE_BIT)
#define STATUS_DE_MASK (1<<STATUS_DE_BIT) #define STATUS_DE_MASK (1<<STATUS_DE_BIT)
#define STATUS_U_MASK (1<<STATUS_U_BIT) #define STATUS_U_MASK (1<<STATUS_U_BIT)
#define STATUS_Z_MASK (1<<STATUS_Z_BIT)
#define STATUS_L_MASK (1<<STATUS_L_BIT) #define STATUS_L_MASK (1<<STATUS_L_BIT)
/* /*

View File

@ -37,9 +37,9 @@ extern const char *arc_platform_smp_cpuinfo(void);
* API expected BY platform smp code (FROM arch smp code) * API expected BY platform smp code (FROM arch smp code)
* *
* smp_ipi_irq_setup: * smp_ipi_irq_setup:
* Takes @cpu and @irq to which the arch-common ISR is hooked up * Takes @cpu and @hwirq to which the arch-common ISR is hooked up
*/ */
extern int smp_ipi_irq_setup(int cpu, int irq); extern int smp_ipi_irq_setup(int cpu, irq_hw_number_t hwirq);
/* /*
* struct plat_smp_ops - SMP callbacks provided by platform to ARC SMP * struct plat_smp_ops - SMP callbacks provided by platform to ARC SMP

View File

@ -31,6 +31,8 @@ static void __init arc_set_early_base_baud(unsigned long dt_root)
arc_base_baud = 166666666; /* Fixed 166.6MHz clk (TB10x) */ arc_base_baud = 166666666; /* Fixed 166.6MHz clk (TB10x) */
else if (of_flat_dt_is_compatible(dt_root, "snps,arc-sdp")) else if (of_flat_dt_is_compatible(dt_root, "snps,arc-sdp"))
arc_base_baud = 33333333; /* Fixed 33MHz clk (AXS10x) */ arc_base_baud = 33333333; /* Fixed 33MHz clk (AXS10x) */
else if (of_flat_dt_is_compatible(dt_root, "ezchip,arc-nps"))
arc_base_baud = 800000000; /* Fixed 800MHz clk (NPS) */
else else
arc_base_baud = 50000000; /* Fixed default 50MHz */ arc_base_baud = 50000000; /* Fixed default 50MHz */
} }

View File

@ -181,6 +181,8 @@ idu_irq_set_affinity(struct irq_data *data, const struct cpumask *cpumask,
{ {
unsigned long flags; unsigned long flags;
cpumask_t online; cpumask_t online;
unsigned int destination_bits;
unsigned int distribution_mode;
/* errout if no online cpu per @cpumask */ /* errout if no online cpu per @cpumask */
if (!cpumask_and(&online, cpumask, cpu_online_mask)) if (!cpumask_and(&online, cpumask, cpu_online_mask))
@ -188,8 +190,15 @@ idu_irq_set_affinity(struct irq_data *data, const struct cpumask *cpumask,
raw_spin_lock_irqsave(&mcip_lock, flags); raw_spin_lock_irqsave(&mcip_lock, flags);
idu_set_dest(data->hwirq, cpumask_bits(&online)[0]); destination_bits = cpumask_bits(&online)[0];
idu_set_mode(data->hwirq, IDU_M_TRIG_LEVEL, IDU_M_DISTRI_RR); idu_set_dest(data->hwirq, destination_bits);
if (ffs(destination_bits) == fls(destination_bits))
distribution_mode = IDU_M_DISTRI_DEST;
else
distribution_mode = IDU_M_DISTRI_RR;
idu_set_mode(data->hwirq, IDU_M_TRIG_LEVEL, distribution_mode);
raw_spin_unlock_irqrestore(&mcip_lock, flags); raw_spin_unlock_irqrestore(&mcip_lock, flags);
@ -207,16 +216,15 @@ static struct irq_chip idu_irq_chip = {
}; };
static int idu_first_irq; static irq_hw_number_t idu_first_hwirq;
static void idu_cascade_isr(struct irq_desc *desc) static void idu_cascade_isr(struct irq_desc *desc)
{ {
struct irq_domain *domain = irq_desc_get_handler_data(desc); struct irq_domain *idu_domain = irq_desc_get_handler_data(desc);
unsigned int core_irq = irq_desc_get_irq(desc); irq_hw_number_t core_hwirq = irqd_to_hwirq(irq_desc_get_irq_data(desc));
unsigned int idu_irq; irq_hw_number_t idu_hwirq = core_hwirq - idu_first_hwirq;
idu_irq = core_irq - idu_first_irq; generic_handle_irq(irq_find_mapping(idu_domain, idu_hwirq));
generic_handle_irq(irq_find_mapping(domain, idu_irq));
} }
static int idu_irq_map(struct irq_domain *d, unsigned int virq, irq_hw_number_t hwirq) static int idu_irq_map(struct irq_domain *d, unsigned int virq, irq_hw_number_t hwirq)
@ -282,7 +290,7 @@ idu_of_init(struct device_node *intc, struct device_node *parent)
struct irq_domain *domain; struct irq_domain *domain;
/* Read IDU BCR to confirm nr_irqs */ /* Read IDU BCR to confirm nr_irqs */
int nr_irqs = of_irq_count(intc); int nr_irqs = of_irq_count(intc);
int i, irq; int i, virq;
struct mcip_bcr mp; struct mcip_bcr mp;
READ_BCR(ARC_REG_MCIP_BCR, mp); READ_BCR(ARC_REG_MCIP_BCR, mp);
@ -303,11 +311,11 @@ idu_of_init(struct device_node *intc, struct device_node *parent)
* however we need it to get the parent virq and set IDU handler * however we need it to get the parent virq and set IDU handler
* as first level isr * as first level isr
*/ */
irq = irq_of_parse_and_map(intc, i); virq = irq_of_parse_and_map(intc, i);
if (!i) if (!i)
idu_first_irq = irq; idu_first_hwirq = irqd_to_hwirq(irq_get_irq_data(virq));
irq_set_chained_handler_and_data(irq, idu_cascade_isr, domain); irq_set_chained_handler_and_data(virq, idu_cascade_isr, domain);
} }
__mcip_cmd(CMD_IDU_ENABLE, 0); __mcip_cmd(CMD_IDU_ENABLE, 0);

View File

@ -43,8 +43,8 @@ SYSCALL_DEFINE0(arc_gettls)
SYSCALL_DEFINE3(arc_usr_cmpxchg, int *, uaddr, int, expected, int, new) SYSCALL_DEFINE3(arc_usr_cmpxchg, int *, uaddr, int, expected, int, new)
{ {
int uval; struct pt_regs *regs = current_pt_regs();
int ret; int uval = -EFAULT;
/* /*
* This is only for old cores lacking LLOCK/SCOND, which by defintion * This is only for old cores lacking LLOCK/SCOND, which by defintion
@ -54,24 +54,26 @@ SYSCALL_DEFINE3(arc_usr_cmpxchg, int *, uaddr, int, expected, int, new)
*/ */
WARN_ON_ONCE(IS_ENABLED(CONFIG_SMP)); WARN_ON_ONCE(IS_ENABLED(CONFIG_SMP));
/* Z indicates to userspace if operation succeded */
regs->status32 &= ~STATUS_Z_MASK;
if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int))) if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
return -EFAULT; return -EFAULT;
preempt_disable(); preempt_disable();
ret = __get_user(uval, uaddr); if (__get_user(uval, uaddr))
if (ret)
goto done; goto done;
if (uval != expected) if (uval == expected) {
ret = -EAGAIN; if (!__put_user(new, uaddr))
else regs->status32 |= STATUS_Z_MASK;
ret = __put_user(new, uaddr); }
done: done:
preempt_enable(); preempt_enable();
return ret; return uval;
} }
void arch_cpu_idle(void) void arch_cpu_idle(void)

View File

@ -22,6 +22,7 @@
#include <linux/atomic.h> #include <linux/atomic.h>
#include <linux/cpumask.h> #include <linux/cpumask.h>
#include <linux/reboot.h> #include <linux/reboot.h>
#include <linux/irqdomain.h>
#include <asm/processor.h> #include <asm/processor.h>
#include <asm/setup.h> #include <asm/setup.h>
#include <asm/mach_desc.h> #include <asm/mach_desc.h>
@ -67,11 +68,13 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
int i; int i;
/* /*
* Initialise the present map, which describes the set of CPUs * if platform didn't set the present map already, do it now
* actually populated at the present time. * boot cpu is set to present already by init/main.c
*/ */
for (i = 0; i < max_cpus; i++) if (num_present_cpus() <= 1) {
set_cpu_present(i, true); for (i = 0; i < max_cpus; i++)
set_cpu_present(i, true);
}
} }
void __init smp_cpus_done(unsigned int max_cpus) void __init smp_cpus_done(unsigned int max_cpus)
@ -351,20 +354,24 @@ irqreturn_t do_IPI(int irq, void *dev_id)
*/ */
static DEFINE_PER_CPU(int, ipi_dev); static DEFINE_PER_CPU(int, ipi_dev);
int smp_ipi_irq_setup(int cpu, int irq) int smp_ipi_irq_setup(int cpu, irq_hw_number_t hwirq)
{ {
int *dev = per_cpu_ptr(&ipi_dev, cpu); int *dev = per_cpu_ptr(&ipi_dev, cpu);
unsigned int virq = irq_find_mapping(NULL, hwirq);
if (!virq)
panic("Cannot find virq for root domain and hwirq=%lu", hwirq);
/* Boot cpu calls request, all call enable */ /* Boot cpu calls request, all call enable */
if (!cpu) { if (!cpu) {
int rc; int rc;
rc = request_percpu_irq(irq, do_IPI, "IPI Interrupt", dev); rc = request_percpu_irq(virq, do_IPI, "IPI Interrupt", dev);
if (rc) if (rc)
panic("Percpu IRQ request failed for %d\n", irq); panic("Percpu IRQ request failed for %u\n", virq);
} }
enable_percpu_irq(irq, 0); enable_percpu_irq(virq, 0);
return 0; return 0;
} }

View File

@ -152,14 +152,17 @@ static cycle_t arc_read_rtc(struct clocksource *cs)
cycle_t full; cycle_t full;
} stamp; } stamp;
/*
__asm__ __volatile( * hardware has an internal state machine which tracks readout of
"1: \n" * low/high and updates the CTRL.status if
" lr %0, [AUX_RTC_LOW] \n" * - interrupt/exception taken between the two reads
" lr %1, [AUX_RTC_HIGH] \n" * - high increments after low has been read
" lr %2, [AUX_RTC_CTRL] \n" */
" bbit0.nt %2, 31, 1b \n" do {
: "=r" (stamp.low), "=r" (stamp.high), "=r" (status)); stamp.low = read_aux_reg(AUX_RTC_LOW);
stamp.high = read_aux_reg(AUX_RTC_HIGH);
status = read_aux_reg(AUX_RTC_CTRL);
} while (!(status & _BITUL(31)));
return stamp.full; return stamp.full;
} }

View File

@ -105,6 +105,31 @@ static void arc_dma_free(struct device *dev, size_t size, void *vaddr,
__free_pages(page, get_order(size)); __free_pages(page, get_order(size));
} }
static int arc_dma_mmap(struct device *dev, struct vm_area_struct *vma,
void *cpu_addr, dma_addr_t dma_addr, size_t size,
unsigned long attrs)
{
unsigned long user_count = vma_pages(vma);
unsigned long count = PAGE_ALIGN(size) >> PAGE_SHIFT;
unsigned long pfn = __phys_to_pfn(plat_dma_to_phys(dev, dma_addr));
unsigned long off = vma->vm_pgoff;
int ret = -ENXIO;
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
if (dma_mmap_from_coherent(dev, vma, cpu_addr, size, &ret))
return ret;
if (off < count && user_count <= (count - off)) {
ret = remap_pfn_range(vma, vma->vm_start,
pfn + off,
user_count << PAGE_SHIFT,
vma->vm_page_prot);
}
return ret;
}
/* /*
* streaming DMA Mapping API... * streaming DMA Mapping API...
* CPU accesses page via normal paddr, thus needs to explicitly made * CPU accesses page via normal paddr, thus needs to explicitly made
@ -193,6 +218,7 @@ static int arc_dma_supported(struct device *dev, u64 dma_mask)
struct dma_map_ops arc_dma_ops = { struct dma_map_ops arc_dma_ops = {
.alloc = arc_dma_alloc, .alloc = arc_dma_alloc,
.free = arc_dma_free, .free = arc_dma_free,
.mmap = arc_dma_mmap,
.map_page = arc_dma_map_page, .map_page = arc_dma_map_page,
.map_sg = arc_dma_map_sg, .map_sg = arc_dma_map_sg,
.sync_single_for_device = arc_dma_sync_single_for_device, .sync_single_for_device = arc_dma_sync_single_for_device,

View File

@ -140,16 +140,10 @@ static void eznps_init_per_cpu(int cpu)
mtm_enable_core(cpu); mtm_enable_core(cpu);
} }
static void eznps_ipi_clear(int irq)
{
write_aux_reg(CTOP_AUX_IACK, 1 << irq);
}
struct plat_smp_ops plat_smp_ops = { struct plat_smp_ops plat_smp_ops = {
.info = smp_cpuinfo_buf, .info = smp_cpuinfo_buf,
.init_early_smp = eznps_init_cpumasks, .init_early_smp = eznps_init_cpumasks,
.cpu_kick = eznps_smp_wakeup_cpu, .cpu_kick = eznps_smp_wakeup_cpu,
.ipi_send = eznps_ipi_send, .ipi_send = eznps_ipi_send,
.init_per_cpu = eznps_init_per_cpu, .init_per_cpu = eznps_init_per_cpu,
.ipi_clear = eznps_ipi_clear,
}; };

View File

@ -66,6 +66,7 @@ extern char __kvm_hyp_vector[];
extern void __kvm_flush_vm_context(void); extern void __kvm_flush_vm_context(void);
extern void __kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa); extern void __kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa);
extern void __kvm_tlb_flush_vmid(struct kvm *kvm); extern void __kvm_tlb_flush_vmid(struct kvm *kvm);
extern void __kvm_tlb_flush_local_vmid(struct kvm_vcpu *vcpu);
extern int __kvm_vcpu_run(struct kvm_vcpu *vcpu); extern int __kvm_vcpu_run(struct kvm_vcpu *vcpu);

View File

@ -57,6 +57,9 @@ struct kvm_arch {
/* VTTBR value associated with below pgd and vmid */ /* VTTBR value associated with below pgd and vmid */
u64 vttbr; u64 vttbr;
/* The last vcpu id that ran on each physical CPU */
int __percpu *last_vcpu_ran;
/* Timer */ /* Timer */
struct arch_timer_kvm timer; struct arch_timer_kvm timer;

View File

@ -71,6 +71,7 @@
#define ICIALLUIS __ACCESS_CP15(c7, 0, c1, 0) #define ICIALLUIS __ACCESS_CP15(c7, 0, c1, 0)
#define ATS1CPR __ACCESS_CP15(c7, 0, c8, 0) #define ATS1CPR __ACCESS_CP15(c7, 0, c8, 0)
#define TLBIALLIS __ACCESS_CP15(c8, 0, c3, 0) #define TLBIALLIS __ACCESS_CP15(c8, 0, c3, 0)
#define TLBIALL __ACCESS_CP15(c8, 0, c7, 0)
#define TLBIALLNSNHIS __ACCESS_CP15(c8, 4, c3, 4) #define TLBIALLNSNHIS __ACCESS_CP15(c8, 4, c3, 4)
#define PRRR __ACCESS_CP15(c10, 0, c2, 0) #define PRRR __ACCESS_CP15(c10, 0, c2, 0)
#define NMRR __ACCESS_CP15(c10, 0, c2, 1) #define NMRR __ACCESS_CP15(c10, 0, c2, 1)

View File

@ -19,7 +19,7 @@
* This may need to be greater than __NR_last_syscall+1 in order to * This may need to be greater than __NR_last_syscall+1 in order to
* account for the padding in the syscall table * account for the padding in the syscall table
*/ */
#define __NR_syscalls (396) #define __NR_syscalls (400)
#define __ARCH_WANT_STAT64 #define __ARCH_WANT_STAT64
#define __ARCH_WANT_SYS_GETHOSTNAME #define __ARCH_WANT_SYS_GETHOSTNAME

View File

@ -420,6 +420,9 @@
#define __NR_copy_file_range (__NR_SYSCALL_BASE+391) #define __NR_copy_file_range (__NR_SYSCALL_BASE+391)
#define __NR_preadv2 (__NR_SYSCALL_BASE+392) #define __NR_preadv2 (__NR_SYSCALL_BASE+392)
#define __NR_pwritev2 (__NR_SYSCALL_BASE+393) #define __NR_pwritev2 (__NR_SYSCALL_BASE+393)
#define __NR_pkey_mprotect (__NR_SYSCALL_BASE+394)
#define __NR_pkey_alloc (__NR_SYSCALL_BASE+395)
#define __NR_pkey_free (__NR_SYSCALL_BASE+396)
/* /*
* The following SWIs are ARM private. * The following SWIs are ARM private.

View File

@ -403,6 +403,9 @@
CALL(sys_copy_file_range) CALL(sys_copy_file_range)
CALL(sys_preadv2) CALL(sys_preadv2)
CALL(sys_pwritev2) CALL(sys_pwritev2)
CALL(sys_pkey_mprotect)
/* 395 */ CALL(sys_pkey_alloc)
CALL(sys_pkey_free)
#ifndef syscalls_counted #ifndef syscalls_counted
.equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls
#define syscalls_counted #define syscalls_counted

View File

@ -114,11 +114,18 @@ void kvm_arch_check_processor_compat(void *rtn)
*/ */
int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
{ {
int ret = 0; int ret, cpu;
if (type) if (type)
return -EINVAL; return -EINVAL;
kvm->arch.last_vcpu_ran = alloc_percpu(typeof(*kvm->arch.last_vcpu_ran));
if (!kvm->arch.last_vcpu_ran)
return -ENOMEM;
for_each_possible_cpu(cpu)
*per_cpu_ptr(kvm->arch.last_vcpu_ran, cpu) = -1;
ret = kvm_alloc_stage2_pgd(kvm); ret = kvm_alloc_stage2_pgd(kvm);
if (ret) if (ret)
goto out_fail_alloc; goto out_fail_alloc;
@ -141,6 +148,8 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
out_free_stage2_pgd: out_free_stage2_pgd:
kvm_free_stage2_pgd(kvm); kvm_free_stage2_pgd(kvm);
out_fail_alloc: out_fail_alloc:
free_percpu(kvm->arch.last_vcpu_ran);
kvm->arch.last_vcpu_ran = NULL;
return ret; return ret;
} }
@ -168,6 +177,9 @@ void kvm_arch_destroy_vm(struct kvm *kvm)
{ {
int i; int i;
free_percpu(kvm->arch.last_vcpu_ran);
kvm->arch.last_vcpu_ran = NULL;
for (i = 0; i < KVM_MAX_VCPUS; ++i) { for (i = 0; i < KVM_MAX_VCPUS; ++i) {
if (kvm->vcpus[i]) { if (kvm->vcpus[i]) {
kvm_arch_vcpu_free(kvm->vcpus[i]); kvm_arch_vcpu_free(kvm->vcpus[i]);
@ -312,6 +324,19 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
{ {
int *last_ran;
last_ran = this_cpu_ptr(vcpu->kvm->arch.last_vcpu_ran);
/*
* We might get preempted before the vCPU actually runs, but
* over-invalidation doesn't affect correctness.
*/
if (*last_ran != vcpu->vcpu_id) {
kvm_call_hyp(__kvm_tlb_flush_local_vmid, vcpu);
*last_ran = vcpu->vcpu_id;
}
vcpu->cpu = cpu; vcpu->cpu = cpu;
vcpu->arch.host_cpu_context = this_cpu_ptr(kvm_host_cpu_state); vcpu->arch.host_cpu_context = this_cpu_ptr(kvm_host_cpu_state);

View File

@ -55,6 +55,21 @@ void __hyp_text __kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa)
__kvm_tlb_flush_vmid(kvm); __kvm_tlb_flush_vmid(kvm);
} }
void __hyp_text __kvm_tlb_flush_local_vmid(struct kvm_vcpu *vcpu)
{
struct kvm *kvm = kern_hyp_va(kern_hyp_va(vcpu)->kvm);
/* Switch to requested VMID */
write_sysreg(kvm->arch.vttbr, VTTBR);
isb();
write_sysreg(0, TLBIALL);
dsb(nsh);
isb();
write_sysreg(0, VTTBR);
}
void __hyp_text __kvm_flush_vm_context(void) void __hyp_text __kvm_flush_vm_context(void)
{ {
write_sysreg(0, TLBIALLNSNHIS); write_sysreg(0, TLBIALLNSNHIS);

View File

@ -7,7 +7,7 @@
* : r4 = aborted context pc * : r4 = aborted context pc
* : r5 = aborted context psr * : r5 = aborted context psr
* *
* Returns : r4-r5, r10-r11, r13 preserved * Returns : r4-r5, r9-r11, r13 preserved
* *
* Purpose : obtain information about current aborted instruction. * Purpose : obtain information about current aborted instruction.
* Note: we read user space. This means we might cause a data * Note: we read user space. This means we might cause a data
@ -48,7 +48,10 @@ ENTRY(v4t_late_abort)
/* c */ b do_DataAbort @ ldc rd, [rn], #m @ Same as ldr rd, [rn], #m /* c */ b do_DataAbort @ ldc rd, [rn], #m @ Same as ldr rd, [rn], #m
/* d */ b do_DataAbort @ ldc rd, [rn, #m] /* d */ b do_DataAbort @ ldc rd, [rn, #m]
/* e */ b .data_unknown /* e */ b .data_unknown
/* f */ /* f */ b .data_unknown
.data_unknown_r9:
ldr r9, [sp], #4
.data_unknown: @ Part of jumptable .data_unknown: @ Part of jumptable
mov r0, r4 mov r0, r4
mov r1, r8 mov r1, r8
@ -57,6 +60,7 @@ ENTRY(v4t_late_abort)
.data_arm_ldmstm: .data_arm_ldmstm:
tst r8, #1 << 21 @ check writeback bit tst r8, #1 << 21 @ check writeback bit
beq do_DataAbort @ no writeback -> no fixup beq do_DataAbort @ no writeback -> no fixup
str r9, [sp, #-4]!
mov r7, #0x11 mov r7, #0x11
orr r7, r7, #0x1100 orr r7, r7, #0x1100
and r6, r8, r7 and r6, r8, r7
@ -75,12 +79,14 @@ ENTRY(v4t_late_abort)
subne r7, r7, r6, lsl #2 @ Undo increment subne r7, r7, r6, lsl #2 @ Undo increment
addeq r7, r7, r6, lsl #2 @ Undo decrement addeq r7, r7, r6, lsl #2 @ Undo decrement
str r7, [r2, r9, lsr #14] @ Put register 'Rn' str r7, [r2, r9, lsr #14] @ Put register 'Rn'
ldr r9, [sp], #4
b do_DataAbort b do_DataAbort
.data_arm_lateldrhpre: .data_arm_lateldrhpre:
tst r8, #1 << 21 @ Check writeback bit tst r8, #1 << 21 @ Check writeback bit
beq do_DataAbort @ No writeback -> no fixup beq do_DataAbort @ No writeback -> no fixup
.data_arm_lateldrhpost: .data_arm_lateldrhpost:
str r9, [sp, #-4]!
and r9, r8, #0x00f @ get Rm / low nibble of immediate value and r9, r8, #0x00f @ get Rm / low nibble of immediate value
tst r8, #1 << 22 @ if (immediate offset) tst r8, #1 << 22 @ if (immediate offset)
andne r6, r8, #0xf00 @ { immediate high nibble andne r6, r8, #0xf00 @ { immediate high nibble
@ -93,6 +99,7 @@ ENTRY(v4t_late_abort)
subne r7, r7, r6 @ Undo incrmenet subne r7, r7, r6 @ Undo incrmenet
addeq r7, r7, r6 @ Undo decrement addeq r7, r7, r6 @ Undo decrement
str r7, [r2, r9, lsr #14] @ Put register 'Rn' str r7, [r2, r9, lsr #14] @ Put register 'Rn'
ldr r9, [sp], #4
b do_DataAbort b do_DataAbort
.data_arm_lateldrpreconst: .data_arm_lateldrpreconst:
@ -101,12 +108,14 @@ ENTRY(v4t_late_abort)
.data_arm_lateldrpostconst: .data_arm_lateldrpostconst:
movs r6, r8, lsl #20 @ Get offset movs r6, r8, lsl #20 @ Get offset
beq do_DataAbort @ zero -> no fixup beq do_DataAbort @ zero -> no fixup
str r9, [sp, #-4]!
and r9, r8, #15 << 16 @ Extract 'n' from instruction and r9, r8, #15 << 16 @ Extract 'n' from instruction
ldr r7, [r2, r9, lsr #14] @ Get register 'Rn' ldr r7, [r2, r9, lsr #14] @ Get register 'Rn'
tst r8, #1 << 23 @ Check U bit tst r8, #1 << 23 @ Check U bit
subne r7, r7, r6, lsr #20 @ Undo increment subne r7, r7, r6, lsr #20 @ Undo increment
addeq r7, r7, r6, lsr #20 @ Undo decrement addeq r7, r7, r6, lsr #20 @ Undo decrement
str r7, [r2, r9, lsr #14] @ Put register 'Rn' str r7, [r2, r9, lsr #14] @ Put register 'Rn'
ldr r9, [sp], #4
b do_DataAbort b do_DataAbort
.data_arm_lateldrprereg: .data_arm_lateldrprereg:
@ -115,6 +124,7 @@ ENTRY(v4t_late_abort)
.data_arm_lateldrpostreg: .data_arm_lateldrpostreg:
and r7, r8, #15 @ Extract 'm' from instruction and r7, r8, #15 @ Extract 'm' from instruction
ldr r6, [r2, r7, lsl #2] @ Get register 'Rm' ldr r6, [r2, r7, lsl #2] @ Get register 'Rm'
str r9, [sp, #-4]!
mov r9, r8, lsr #7 @ get shift count mov r9, r8, lsr #7 @ get shift count
ands r9, r9, #31 ands r9, r9, #31
and r7, r8, #0x70 @ get shift type and r7, r8, #0x70 @ get shift type
@ -126,33 +136,33 @@ ENTRY(v4t_late_abort)
b .data_arm_apply_r6_and_rn b .data_arm_apply_r6_and_rn
b .data_arm_apply_r6_and_rn @ 1: LSL #0 b .data_arm_apply_r6_and_rn @ 1: LSL #0
nop nop
b .data_unknown @ 2: MUL? b .data_unknown_r9 @ 2: MUL?
nop nop
b .data_unknown @ 3: MUL? b .data_unknown_r9 @ 3: MUL?
nop nop
mov r6, r6, lsr r9 @ 4: LSR #!0 mov r6, r6, lsr r9 @ 4: LSR #!0
b .data_arm_apply_r6_and_rn b .data_arm_apply_r6_and_rn
mov r6, r6, lsr #32 @ 5: LSR #32 mov r6, r6, lsr #32 @ 5: LSR #32
b .data_arm_apply_r6_and_rn b .data_arm_apply_r6_and_rn
b .data_unknown @ 6: MUL? b .data_unknown_r9 @ 6: MUL?
nop nop
b .data_unknown @ 7: MUL? b .data_unknown_r9 @ 7: MUL?
nop nop
mov r6, r6, asr r9 @ 8: ASR #!0 mov r6, r6, asr r9 @ 8: ASR #!0
b .data_arm_apply_r6_and_rn b .data_arm_apply_r6_and_rn
mov r6, r6, asr #32 @ 9: ASR #32 mov r6, r6, asr #32 @ 9: ASR #32
b .data_arm_apply_r6_and_rn b .data_arm_apply_r6_and_rn
b .data_unknown @ A: MUL? b .data_unknown_r9 @ A: MUL?
nop nop
b .data_unknown @ B: MUL? b .data_unknown_r9 @ B: MUL?
nop nop
mov r6, r6, ror r9 @ C: ROR #!0 mov r6, r6, ror r9 @ C: ROR #!0
b .data_arm_apply_r6_and_rn b .data_arm_apply_r6_and_rn
mov r6, r6, rrx @ D: RRX mov r6, r6, rrx @ D: RRX
b .data_arm_apply_r6_and_rn b .data_arm_apply_r6_and_rn
b .data_unknown @ E: MUL? b .data_unknown_r9 @ E: MUL?
nop nop
b .data_unknown @ F: MUL? b .data_unknown_r9 @ F: MUL?
.data_thumb_abort: .data_thumb_abort:
ldrh r8, [r4] @ read instruction ldrh r8, [r4] @ read instruction
@ -190,6 +200,7 @@ ENTRY(v4t_late_abort)
.data_thumb_pushpop: .data_thumb_pushpop:
tst r8, #1 << 10 tst r8, #1 << 10
beq .data_unknown beq .data_unknown
str r9, [sp, #-4]!
and r6, r8, #0x55 @ hweight8(r8) + R bit and r6, r8, #0x55 @ hweight8(r8) + R bit
and r9, r8, #0xaa and r9, r8, #0xaa
add r6, r6, r9, lsr #1 add r6, r6, r9, lsr #1
@ -204,9 +215,11 @@ ENTRY(v4t_late_abort)
addeq r7, r7, r6, lsl #2 @ increment SP if PUSH addeq r7, r7, r6, lsl #2 @ increment SP if PUSH
subne r7, r7, r6, lsl #2 @ decrement SP if POP subne r7, r7, r6, lsl #2 @ decrement SP if POP
str r7, [r2, #13 << 2] str r7, [r2, #13 << 2]
ldr r9, [sp], #4
b do_DataAbort b do_DataAbort
.data_thumb_ldmstm: .data_thumb_ldmstm:
str r9, [sp, #-4]!
and r6, r8, #0x55 @ hweight8(r8) and r6, r8, #0x55 @ hweight8(r8)
and r9, r8, #0xaa and r9, r8, #0xaa
add r6, r6, r9, lsr #1 add r6, r6, r9, lsr #1
@ -219,4 +232,5 @@ ENTRY(v4t_late_abort)
and r6, r6, #15 @ number of regs to transfer and r6, r6, #15 @ number of regs to transfer
sub r7, r7, r6, lsl #2 @ always decrement sub r7, r7, r6, lsl #2 @ always decrement
str r7, [r2, r9, lsr #6] str r7, [r2, r9, lsr #6]
ldr r9, [sp], #4
b do_DataAbort b do_DataAbort

View File

@ -300,8 +300,11 @@
ranges = <0x83000000 0x0 0xfa000000 0x0 0xfa000000 0x0 0x600000 ranges = <0x83000000 0x0 0xfa000000 0x0 0xfa000000 0x0 0x600000
0x81000000 0x0 0xfa600000 0x0 0xfa600000 0x0 0x100000>; 0x81000000 0x0 0xfa600000 0x0 0xfa600000 0x0 0x100000>;
resets = <&cru SRST_PCIE_CORE>, <&cru SRST_PCIE_MGMT>, resets = <&cru SRST_PCIE_CORE>, <&cru SRST_PCIE_MGMT>,
<&cru SRST_PCIE_MGMT_STICKY>, <&cru SRST_PCIE_PIPE>; <&cru SRST_PCIE_MGMT_STICKY>, <&cru SRST_PCIE_PIPE>,
reset-names = "core", "mgmt", "mgmt-sticky", "pipe"; <&cru SRST_PCIE_PM>, <&cru SRST_P_PCIE>,
<&cru SRST_A_PCIE>;
reset-names = "core", "mgmt", "mgmt-sticky", "pipe",
"pm", "pclk", "aclk";
status = "disabled"; status = "disabled";
pcie0_intc: interrupt-controller { pcie0_intc: interrupt-controller {

View File

@ -1,7 +1,7 @@
#ifndef __ASM_ALTERNATIVE_H #ifndef __ASM_ALTERNATIVE_H
#define __ASM_ALTERNATIVE_H #define __ASM_ALTERNATIVE_H
#include <asm/cpufeature.h> #include <asm/cpucaps.h>
#include <asm/insn.h> #include <asm/insn.h>
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__

View File

@ -0,0 +1,40 @@
/*
* arch/arm64/include/asm/cpucaps.h
*
* Copyright (C) 2016 ARM Ltd.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* 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. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __ASM_CPUCAPS_H
#define __ASM_CPUCAPS_H
#define ARM64_WORKAROUND_CLEAN_CACHE 0
#define ARM64_WORKAROUND_DEVICE_LOAD_ACQUIRE 1
#define ARM64_WORKAROUND_845719 2
#define ARM64_HAS_SYSREG_GIC_CPUIF 3
#define ARM64_HAS_PAN 4
#define ARM64_HAS_LSE_ATOMICS 5
#define ARM64_WORKAROUND_CAVIUM_23154 6
#define ARM64_WORKAROUND_834220 7
#define ARM64_HAS_NO_HW_PREFETCH 8
#define ARM64_HAS_UAO 9
#define ARM64_ALT_PAN_NOT_UAO 10
#define ARM64_HAS_VIRT_HOST_EXTN 11
#define ARM64_WORKAROUND_CAVIUM_27456 12
#define ARM64_HAS_32BIT_EL0 13
#define ARM64_HYP_OFFSET_LOW 14
#define ARM64_MISMATCHED_CACHE_LINE_SIZE 15
#define ARM64_NCAPS 16
#endif /* __ASM_CPUCAPS_H */

View File

@ -11,6 +11,7 @@
#include <linux/jump_label.h> #include <linux/jump_label.h>
#include <asm/cpucaps.h>
#include <asm/hwcap.h> #include <asm/hwcap.h>
#include <asm/sysreg.h> #include <asm/sysreg.h>
@ -24,25 +25,6 @@
#define MAX_CPU_FEATURES (8 * sizeof(elf_hwcap)) #define MAX_CPU_FEATURES (8 * sizeof(elf_hwcap))
#define cpu_feature(x) ilog2(HWCAP_ ## x) #define cpu_feature(x) ilog2(HWCAP_ ## x)
#define ARM64_WORKAROUND_CLEAN_CACHE 0
#define ARM64_WORKAROUND_DEVICE_LOAD_ACQUIRE 1
#define ARM64_WORKAROUND_845719 2
#define ARM64_HAS_SYSREG_GIC_CPUIF 3
#define ARM64_HAS_PAN 4
#define ARM64_HAS_LSE_ATOMICS 5
#define ARM64_WORKAROUND_CAVIUM_23154 6
#define ARM64_WORKAROUND_834220 7
#define ARM64_HAS_NO_HW_PREFETCH 8
#define ARM64_HAS_UAO 9
#define ARM64_ALT_PAN_NOT_UAO 10
#define ARM64_HAS_VIRT_HOST_EXTN 11
#define ARM64_WORKAROUND_CAVIUM_27456 12
#define ARM64_HAS_32BIT_EL0 13
#define ARM64_HYP_OFFSET_LOW 14
#define ARM64_MISMATCHED_CACHE_LINE_SIZE 15
#define ARM64_NCAPS 16
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
#include <linux/kernel.h> #include <linux/kernel.h>

View File

@ -54,6 +54,7 @@ extern char __kvm_hyp_vector[];
extern void __kvm_flush_vm_context(void); extern void __kvm_flush_vm_context(void);
extern void __kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa); extern void __kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa);
extern void __kvm_tlb_flush_vmid(struct kvm *kvm); extern void __kvm_tlb_flush_vmid(struct kvm *kvm);
extern void __kvm_tlb_flush_local_vmid(struct kvm_vcpu *vcpu);
extern int __kvm_vcpu_run(struct kvm_vcpu *vcpu); extern int __kvm_vcpu_run(struct kvm_vcpu *vcpu);

View File

@ -62,6 +62,9 @@ struct kvm_arch {
/* VTTBR value associated with above pgd and vmid */ /* VTTBR value associated with above pgd and vmid */
u64 vttbr; u64 vttbr;
/* The last vcpu id that ran on each physical CPU */
int __percpu *last_vcpu_ran;
/* The maximum number of vCPUs depends on the used GIC model */ /* The maximum number of vCPUs depends on the used GIC model */
int max_vcpus; int max_vcpus;

View File

@ -128,7 +128,7 @@ static inline unsigned long __kern_hyp_va(unsigned long v)
return v; return v;
} }
#define kern_hyp_va(v) (typeof(v))(__kern_hyp_va((unsigned long)(v))) #define kern_hyp_va(v) ((typeof(v))(__kern_hyp_va((unsigned long)(v))))
/* /*
* We currently only support a 40bit IPA. * We currently only support a 40bit IPA.

View File

@ -5,7 +5,6 @@
#include <linux/stringify.h> #include <linux/stringify.h>
#include <asm/alternative.h> #include <asm/alternative.h>
#include <asm/cpufeature.h>
#ifdef __ASSEMBLER__ #ifdef __ASSEMBLER__

View File

@ -64,6 +64,21 @@ void __hyp_text __kvm_tlb_flush_vmid(struct kvm *kvm)
write_sysreg(0, vttbr_el2); write_sysreg(0, vttbr_el2);
} }
void __hyp_text __kvm_tlb_flush_local_vmid(struct kvm_vcpu *vcpu)
{
struct kvm *kvm = kern_hyp_va(kern_hyp_va(vcpu)->kvm);
/* Switch to requested VMID */
write_sysreg(kvm->arch.vttbr, vttbr_el2);
isb();
asm volatile("tlbi vmalle1" : : );
dsb(nsh);
isb();
write_sysreg(0, vttbr_el2);
}
void __hyp_text __kvm_flush_vm_context(void) void __hyp_text __kvm_flush_vm_context(void)
{ {
dsb(ishst); dsb(ishst);

View File

@ -263,7 +263,7 @@ KBUILD_CPPFLAGS += -DDATAOFFSET=$(if $(dataoffset-y),$(dataoffset-y),0)
bootvars-y = VMLINUX_LOAD_ADDRESS=$(load-y) \ bootvars-y = VMLINUX_LOAD_ADDRESS=$(load-y) \
VMLINUX_ENTRY_ADDRESS=$(entry-y) \ VMLINUX_ENTRY_ADDRESS=$(entry-y) \
PLATFORM=$(platform-y) PLATFORM="$(platform-y)"
ifdef CONFIG_32BIT ifdef CONFIG_32BIT
bootvars-y += ADDR_BITS=32 bootvars-y += ADDR_BITS=32
endif endif

View File

@ -84,12 +84,13 @@
fpga_regs: system-controller@1f000000 { fpga_regs: system-controller@1f000000 {
compatible = "mti,malta-fpga", "syscon", "simple-mfd"; compatible = "mti,malta-fpga", "syscon", "simple-mfd";
reg = <0x1f000000 0x1000>; reg = <0x1f000000 0x1000>;
native-endian;
reboot { reboot {
compatible = "syscon-reboot"; compatible = "syscon-reboot";
regmap = <&fpga_regs>; regmap = <&fpga_regs>;
offset = <0x500>; offset = <0x500>;
mask = <0x4d>; mask = <0x42>;
}; };
}; };

View File

@ -29,10 +29,20 @@ static __initdata const struct mips_machine *mach;
static __initdata const void *mach_match_data; static __initdata const void *mach_match_data;
void __init prom_init(void) void __init prom_init(void)
{
plat_get_fdt();
BUG_ON(!fdt);
}
void __init *plat_get_fdt(void)
{ {
const struct mips_machine *check_mach; const struct mips_machine *check_mach;
const struct of_device_id *match; const struct of_device_id *match;
if (fdt)
/* Already set up */
return (void *)fdt;
if ((fw_arg0 == -2) && !fdt_check_header((void *)fw_arg1)) { if ((fw_arg0 == -2) && !fdt_check_header((void *)fw_arg1)) {
/* /*
* We booted using the UHI boot protocol, so we have been * We booted using the UHI boot protocol, so we have been
@ -75,12 +85,6 @@ void __init prom_init(void)
/* Retrieve the machine's FDT */ /* Retrieve the machine's FDT */
fdt = mach->fdt; fdt = mach->fdt;
} }
BUG_ON(!fdt);
}
void __init *plat_get_fdt(void)
{
return (void *)fdt; return (void *)fdt;
} }

View File

@ -63,6 +63,8 @@ do { \
extern int fpu_emulator_cop1Handler(struct pt_regs *xcp, extern int fpu_emulator_cop1Handler(struct pt_regs *xcp,
struct mips_fpu_struct *ctx, int has_fpu, struct mips_fpu_struct *ctx, int has_fpu,
void *__user *fault_addr); void *__user *fault_addr);
void force_fcr31_sig(unsigned long fcr31, void __user *fault_addr,
struct task_struct *tsk);
int process_fpemu_return(int sig, void __user *fault_addr, int process_fpemu_return(int sig, void __user *fault_addr,
unsigned long fcr31); unsigned long fcr31);
int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn, int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
@ -81,4 +83,15 @@ static inline void fpu_emulator_init_fpu(void)
set_fpr64(&t->thread.fpu.fpr[i], 0, SIGNALLING_NAN); set_fpr64(&t->thread.fpu.fpr[i], 0, SIGNALLING_NAN);
} }
/*
* Mask the FCSR Cause bits according to the Enable bits, observing
* that Unimplemented is always enabled.
*/
static inline unsigned long mask_fcr31_x(unsigned long fcr31)
{
return fcr31 & (FPU_CSR_UNI_X |
((fcr31 & FPU_CSR_ALL_E) <<
(ffs(FPU_CSR_ALL_X) - ffs(FPU_CSR_ALL_E))));
}
#endif /* _ASM_FPU_EMULATOR_H */ #endif /* _ASM_FPU_EMULATOR_H */

View File

@ -293,7 +293,10 @@ struct kvm_vcpu_arch {
/* Host KSEG0 address of the EI/DI offset */ /* Host KSEG0 address of the EI/DI offset */
void *kseg0_commpage; void *kseg0_commpage;
u32 io_gpr; /* GPR used as IO source/target */ /* Resume PC after MMIO completion */
unsigned long io_pc;
/* GPR used as IO source/target */
u32 io_gpr;
struct hrtimer comparecount_timer; struct hrtimer comparecount_timer;
/* Count timer control KVM register */ /* Count timer control KVM register */
@ -315,8 +318,6 @@ struct kvm_vcpu_arch {
/* Bitmask of pending exceptions to be cleared */ /* Bitmask of pending exceptions to be cleared */
unsigned long pending_exceptions_clr; unsigned long pending_exceptions_clr;
u32 pending_load_cause;
/* Save/Restore the entryhi register when are are preempted/scheduled back in */ /* Save/Restore the entryhi register when are are preempted/scheduled back in */
unsigned long preempt_entryhi; unsigned long preempt_entryhi;

View File

@ -75,6 +75,22 @@ do { if (cpu_has_rw_llb) { \
} \ } \
} while (0) } while (0)
/*
* Check FCSR for any unmasked exceptions pending set with `ptrace',
* clear them and send a signal.
*/
#define __sanitize_fcr31(next) \
do { \
unsigned long fcr31 = mask_fcr31_x(next->thread.fpu.fcr31); \
void __user *pc; \
\
if (unlikely(fcr31)) { \
pc = (void __user *)task_pt_regs(next)->cp0_epc; \
next->thread.fpu.fcr31 &= ~fcr31; \
force_fcr31_sig(fcr31, pc, next); \
} \
} while (0)
/* /*
* For newly created kernel threads switch_to() will return to * For newly created kernel threads switch_to() will return to
* ret_from_kernel_thread, newly created user threads to ret_from_fork. * ret_from_kernel_thread, newly created user threads to ret_from_fork.
@ -85,6 +101,8 @@ do { if (cpu_has_rw_llb) { \
do { \ do { \
__mips_mt_fpaff_switch_to(prev); \ __mips_mt_fpaff_switch_to(prev); \
lose_fpu_inatomic(1, prev); \ lose_fpu_inatomic(1, prev); \
if (tsk_used_math(next)) \
__sanitize_fcr31(next); \
if (cpu_has_dsp) { \ if (cpu_has_dsp) { \
__save_dsp(prev); \ __save_dsp(prev); \
__restore_dsp(next); \ __restore_dsp(next); \

View File

@ -21,6 +21,11 @@ static DEFINE_PER_CPU_ALIGNED(spinlock_t, cpc_core_lock);
static DEFINE_PER_CPU_ALIGNED(unsigned long, cpc_core_lock_flags); static DEFINE_PER_CPU_ALIGNED(unsigned long, cpc_core_lock_flags);
phys_addr_t __weak mips_cpc_default_phys_base(void)
{
return 0;
}
/** /**
* mips_cpc_phys_base - retrieve the physical base address of the CPC * mips_cpc_phys_base - retrieve the physical base address of the CPC
* *
@ -43,8 +48,12 @@ static phys_addr_t mips_cpc_phys_base(void)
if (cpc_base & CM_GCR_CPC_BASE_CPCEN_MSK) if (cpc_base & CM_GCR_CPC_BASE_CPCEN_MSK)
return cpc_base & CM_GCR_CPC_BASE_CPCBASE_MSK; return cpc_base & CM_GCR_CPC_BASE_CPCBASE_MSK;
/* Otherwise, give it the default address & enable it */ /* Otherwise, use the default address */
cpc_base = mips_cpc_default_phys_base(); cpc_base = mips_cpc_default_phys_base();
if (!cpc_base)
return cpc_base;
/* Enable the CPC, mapped at the default address */
write_gcr_cpc_base(cpc_base | CM_GCR_CPC_BASE_CPCEN_MSK); write_gcr_cpc_base(cpc_base | CM_GCR_CPC_BASE_CPCEN_MSK);
return cpc_base; return cpc_base;
} }

View File

@ -899,7 +899,7 @@ static inline int mipsr2_find_op_func(struct pt_regs *regs, u32 inst,
* mipsr2_decoder: Decode and emulate a MIPS R2 instruction * mipsr2_decoder: Decode and emulate a MIPS R2 instruction
* @regs: Process register set * @regs: Process register set
* @inst: Instruction to decode and emulate * @inst: Instruction to decode and emulate
* @fcr31: Floating Point Control and Status Register returned * @fcr31: Floating Point Control and Status Register Cause bits returned
*/ */
int mipsr2_decoder(struct pt_regs *regs, u32 inst, unsigned long *fcr31) int mipsr2_decoder(struct pt_regs *regs, u32 inst, unsigned long *fcr31)
{ {
@ -1172,13 +1172,13 @@ fpu_emul:
err = fpu_emulator_cop1Handler(regs, &current->thread.fpu, 0, err = fpu_emulator_cop1Handler(regs, &current->thread.fpu, 0,
&fault_addr); &fault_addr);
*fcr31 = current->thread.fpu.fcr31;
/* /*
* We can't allow the emulated instruction to leave any of * We can't allow the emulated instruction to leave any
* the cause bits set in $fcr31. * enabled Cause bits set in $fcr31.
*/ */
current->thread.fpu.fcr31 &= ~FPU_CSR_ALL_X; *fcr31 = res = mask_fcr31_x(current->thread.fpu.fcr31);
current->thread.fpu.fcr31 &= ~res;
/* /*
* this is a tricky issue - lose_fpu() uses LL/SC atomics * this is a tricky issue - lose_fpu() uses LL/SC atomics

View File

@ -79,16 +79,15 @@ void ptrace_disable(struct task_struct *child)
} }
/* /*
* Poke at FCSR according to its mask. Don't set the cause bits as * Poke at FCSR according to its mask. Set the Cause bits even
* this is currently not handled correctly in FP context restoration * if a corresponding Enable bit is set. This will be noticed at
* and will cause an oops if a corresponding enable bit is set. * the time the thread is switched to and SIGFPE thrown accordingly.
*/ */
static void ptrace_setfcr31(struct task_struct *child, u32 value) static void ptrace_setfcr31(struct task_struct *child, u32 value)
{ {
u32 fcr31; u32 fcr31;
u32 mask; u32 mask;
value &= ~FPU_CSR_ALL_X;
fcr31 = child->thread.fpu.fcr31; fcr31 = child->thread.fpu.fcr31;
mask = boot_cpu_data.fpu_msk31; mask = boot_cpu_data.fpu_msk31;
child->thread.fpu.fcr31 = (value & ~mask) | (fcr31 & mask); child->thread.fpu.fcr31 = (value & ~mask) | (fcr31 & mask);
@ -817,6 +816,7 @@ long arch_ptrace(struct task_struct *child, long request,
break; break;
#endif #endif
case FPC_CSR: case FPC_CSR:
init_fp_ctx(child);
ptrace_setfcr31(child, data); ptrace_setfcr31(child, data);
break; break;
case DSP_BASE ... DSP_BASE + 5: { case DSP_BASE ... DSP_BASE + 5: {

View File

@ -19,108 +19,86 @@
#include <asm/regdef.h> #include <asm/regdef.h>
#define EX(a,b) \ #define EX(a,b) \
9: a,##b; \
.section __ex_table,"a"; \
PTR 9b,fault; \
.previous
#define EX2(a,b) \
9: a,##b; \ 9: a,##b; \
.section __ex_table,"a"; \ .section __ex_table,"a"; \
PTR 9b,bad_stack; \ PTR 9b,bad_stack; \
PTR 9b+4,bad_stack; \
.previous .previous
.set noreorder .set noreorder
.set mips1 .set mips1
/* Save floating point context */
/**
* _save_fp_context() - save FP context from the FPU
* @a0 - pointer to fpregs field of sigcontext
* @a1 - pointer to fpc_csr field of sigcontext
*
* Save FP context, including the 32 FP data registers and the FP
* control & status register, from the FPU to signal context.
*/
LEAF(_save_fp_context) LEAF(_save_fp_context)
.set push .set push
SET_HARDFLOAT SET_HARDFLOAT
li v0, 0 # assume success li v0, 0 # assume success
cfc1 t1,fcr31 cfc1 t1, fcr31
EX(swc1 $f0,(SC_FPREGS+0)(a0)) EX2(s.d $f0, 0(a0))
EX(swc1 $f1,(SC_FPREGS+8)(a0)) EX2(s.d $f2, 16(a0))
EX(swc1 $f2,(SC_FPREGS+16)(a0)) EX2(s.d $f4, 32(a0))
EX(swc1 $f3,(SC_FPREGS+24)(a0)) EX2(s.d $f6, 48(a0))
EX(swc1 $f4,(SC_FPREGS+32)(a0)) EX2(s.d $f8, 64(a0))
EX(swc1 $f5,(SC_FPREGS+40)(a0)) EX2(s.d $f10, 80(a0))
EX(swc1 $f6,(SC_FPREGS+48)(a0)) EX2(s.d $f12, 96(a0))
EX(swc1 $f7,(SC_FPREGS+56)(a0)) EX2(s.d $f14, 112(a0))
EX(swc1 $f8,(SC_FPREGS+64)(a0)) EX2(s.d $f16, 128(a0))
EX(swc1 $f9,(SC_FPREGS+72)(a0)) EX2(s.d $f18, 144(a0))
EX(swc1 $f10,(SC_FPREGS+80)(a0)) EX2(s.d $f20, 160(a0))
EX(swc1 $f11,(SC_FPREGS+88)(a0)) EX2(s.d $f22, 176(a0))
EX(swc1 $f12,(SC_FPREGS+96)(a0)) EX2(s.d $f24, 192(a0))
EX(swc1 $f13,(SC_FPREGS+104)(a0)) EX2(s.d $f26, 208(a0))
EX(swc1 $f14,(SC_FPREGS+112)(a0)) EX2(s.d $f28, 224(a0))
EX(swc1 $f15,(SC_FPREGS+120)(a0)) EX2(s.d $f30, 240(a0))
EX(swc1 $f16,(SC_FPREGS+128)(a0))
EX(swc1 $f17,(SC_FPREGS+136)(a0))
EX(swc1 $f18,(SC_FPREGS+144)(a0))
EX(swc1 $f19,(SC_FPREGS+152)(a0))
EX(swc1 $f20,(SC_FPREGS+160)(a0))
EX(swc1 $f21,(SC_FPREGS+168)(a0))
EX(swc1 $f22,(SC_FPREGS+176)(a0))
EX(swc1 $f23,(SC_FPREGS+184)(a0))
EX(swc1 $f24,(SC_FPREGS+192)(a0))
EX(swc1 $f25,(SC_FPREGS+200)(a0))
EX(swc1 $f26,(SC_FPREGS+208)(a0))
EX(swc1 $f27,(SC_FPREGS+216)(a0))
EX(swc1 $f28,(SC_FPREGS+224)(a0))
EX(swc1 $f29,(SC_FPREGS+232)(a0))
EX(swc1 $f30,(SC_FPREGS+240)(a0))
EX(swc1 $f31,(SC_FPREGS+248)(a0))
EX(sw t1,(SC_FPC_CSR)(a0))
cfc1 t0,$0 # implementation/version
jr ra jr ra
EX(sw t1, (a1))
.set pop .set pop
.set nomacro
EX(sw t0,(SC_FPC_EIR)(a0))
.set macro
END(_save_fp_context) END(_save_fp_context)
/* /**
* Restore FPU state: * _restore_fp_context() - restore FP context to the FPU
* - fp gp registers * @a0 - pointer to fpregs field of sigcontext
* - cp1 status/control register * @a1 - pointer to fpc_csr field of sigcontext
* *
* We base the decision which registers to restore from the signal stack * Restore FP context, including the 32 FP data registers and the FP
* frame on the current content of c0_status, not on the content of the * control & status register, from signal context to the FPU.
* stack frame which might have been changed by the user.
*/ */
LEAF(_restore_fp_context) LEAF(_restore_fp_context)
.set push .set push
SET_HARDFLOAT SET_HARDFLOAT
li v0, 0 # assume success li v0, 0 # assume success
EX(lw t0,(SC_FPC_CSR)(a0)) EX(lw t0, (a1))
EX(lwc1 $f0,(SC_FPREGS+0)(a0)) EX2(l.d $f0, 0(a0))
EX(lwc1 $f1,(SC_FPREGS+8)(a0)) EX2(l.d $f2, 16(a0))
EX(lwc1 $f2,(SC_FPREGS+16)(a0)) EX2(l.d $f4, 32(a0))
EX(lwc1 $f3,(SC_FPREGS+24)(a0)) EX2(l.d $f6, 48(a0))
EX(lwc1 $f4,(SC_FPREGS+32)(a0)) EX2(l.d $f8, 64(a0))
EX(lwc1 $f5,(SC_FPREGS+40)(a0)) EX2(l.d $f10, 80(a0))
EX(lwc1 $f6,(SC_FPREGS+48)(a0)) EX2(l.d $f12, 96(a0))
EX(lwc1 $f7,(SC_FPREGS+56)(a0)) EX2(l.d $f14, 112(a0))
EX(lwc1 $f8,(SC_FPREGS+64)(a0)) EX2(l.d $f16, 128(a0))
EX(lwc1 $f9,(SC_FPREGS+72)(a0)) EX2(l.d $f18, 144(a0))
EX(lwc1 $f10,(SC_FPREGS+80)(a0)) EX2(l.d $f20, 160(a0))
EX(lwc1 $f11,(SC_FPREGS+88)(a0)) EX2(l.d $f22, 176(a0))
EX(lwc1 $f12,(SC_FPREGS+96)(a0)) EX2(l.d $f24, 192(a0))
EX(lwc1 $f13,(SC_FPREGS+104)(a0)) EX2(l.d $f26, 208(a0))
EX(lwc1 $f14,(SC_FPREGS+112)(a0)) EX2(l.d $f28, 224(a0))
EX(lwc1 $f15,(SC_FPREGS+120)(a0)) EX2(l.d $f30, 240(a0))
EX(lwc1 $f16,(SC_FPREGS+128)(a0))
EX(lwc1 $f17,(SC_FPREGS+136)(a0))
EX(lwc1 $f18,(SC_FPREGS+144)(a0))
EX(lwc1 $f19,(SC_FPREGS+152)(a0))
EX(lwc1 $f20,(SC_FPREGS+160)(a0))
EX(lwc1 $f21,(SC_FPREGS+168)(a0))
EX(lwc1 $f22,(SC_FPREGS+176)(a0))
EX(lwc1 $f23,(SC_FPREGS+184)(a0))
EX(lwc1 $f24,(SC_FPREGS+192)(a0))
EX(lwc1 $f25,(SC_FPREGS+200)(a0))
EX(lwc1 $f26,(SC_FPREGS+208)(a0))
EX(lwc1 $f27,(SC_FPREGS+216)(a0))
EX(lwc1 $f28,(SC_FPREGS+224)(a0))
EX(lwc1 $f29,(SC_FPREGS+232)(a0))
EX(lwc1 $f30,(SC_FPREGS+240)(a0))
EX(lwc1 $f31,(SC_FPREGS+248)(a0))
jr ra jr ra
ctc1 t0,fcr31 ctc1 t0, fcr31
.set pop .set pop
END(_restore_fp_context) END(_restore_fp_context)
.set reorder .set reorder

View File

@ -21,7 +21,14 @@
.set push .set push
SET_HARDFLOAT SET_HARDFLOAT
/* Save floating point context */ /**
* _save_fp_context() - save FP context from the FPU
* @a0 - pointer to fpregs field of sigcontext
* @a1 - pointer to fpc_csr field of sigcontext
*
* Save FP context, including the 32 FP data registers and the FP
* control & status register, from the FPU to signal context.
*/
LEAF(_save_fp_context) LEAF(_save_fp_context)
mfc0 t0,CP0_STATUS mfc0 t0,CP0_STATUS
sll t0,t0,2 sll t0,t0,2
@ -30,59 +37,59 @@
cfc1 t1,fcr31 cfc1 t1,fcr31
/* Store the 16 double precision registers */ /* Store the 16 double precision registers */
sdc1 $f0,(SC_FPREGS+0)(a0) sdc1 $f0,0(a0)
sdc1 $f2,(SC_FPREGS+16)(a0) sdc1 $f2,16(a0)
sdc1 $f4,(SC_FPREGS+32)(a0) sdc1 $f4,32(a0)
sdc1 $f6,(SC_FPREGS+48)(a0) sdc1 $f6,48(a0)
sdc1 $f8,(SC_FPREGS+64)(a0) sdc1 $f8,64(a0)
sdc1 $f10,(SC_FPREGS+80)(a0) sdc1 $f10,80(a0)
sdc1 $f12,(SC_FPREGS+96)(a0) sdc1 $f12,96(a0)
sdc1 $f14,(SC_FPREGS+112)(a0) sdc1 $f14,112(a0)
sdc1 $f16,(SC_FPREGS+128)(a0) sdc1 $f16,128(a0)
sdc1 $f18,(SC_FPREGS+144)(a0) sdc1 $f18,144(a0)
sdc1 $f20,(SC_FPREGS+160)(a0) sdc1 $f20,160(a0)
sdc1 $f22,(SC_FPREGS+176)(a0) sdc1 $f22,176(a0)
sdc1 $f24,(SC_FPREGS+192)(a0) sdc1 $f24,192(a0)
sdc1 $f26,(SC_FPREGS+208)(a0) sdc1 $f26,208(a0)
sdc1 $f28,(SC_FPREGS+224)(a0) sdc1 $f28,224(a0)
sdc1 $f30,(SC_FPREGS+240)(a0) sdc1 $f30,240(a0)
jr ra jr ra
sw t0,SC_FPC_CSR(a0) sw t0,(a1)
1: jr ra 1: jr ra
nop nop
END(_save_fp_context) END(_save_fp_context)
/* Restore FPU state: /**
* - fp gp registers * _restore_fp_context() - restore FP context to the FPU
* - cp1 status/control register * @a0 - pointer to fpregs field of sigcontext
* @a1 - pointer to fpc_csr field of sigcontext
* *
* We base the decision which registers to restore from the signal stack * Restore FP context, including the 32 FP data registers and the FP
* frame on the current content of c0_status, not on the content of the * control & status register, from signal context to the FPU.
* stack frame which might have been changed by the user.
*/ */
LEAF(_restore_fp_context) LEAF(_restore_fp_context)
mfc0 t0,CP0_STATUS mfc0 t0,CP0_STATUS
sll t0,t0,2 sll t0,t0,2
bgez t0,1f bgez t0,1f
lw t0,SC_FPC_CSR(a0) lw t0,(a1)
/* Restore the 16 double precision registers */ /* Restore the 16 double precision registers */
ldc1 $f0,(SC_FPREGS+0)(a0) ldc1 $f0,0(a0)
ldc1 $f2,(SC_FPREGS+16)(a0) ldc1 $f2,16(a0)
ldc1 $f4,(SC_FPREGS+32)(a0) ldc1 $f4,32(a0)
ldc1 $f6,(SC_FPREGS+48)(a0) ldc1 $f6,48(a0)
ldc1 $f8,(SC_FPREGS+64)(a0) ldc1 $f8,64(a0)
ldc1 $f10,(SC_FPREGS+80)(a0) ldc1 $f10,80(a0)
ldc1 $f12,(SC_FPREGS+96)(a0) ldc1 $f12,96(a0)
ldc1 $f14,(SC_FPREGS+112)(a0) ldc1 $f14,112(a0)
ldc1 $f16,(SC_FPREGS+128)(a0) ldc1 $f16,128(a0)
ldc1 $f18,(SC_FPREGS+144)(a0) ldc1 $f18,144(a0)
ldc1 $f20,(SC_FPREGS+160)(a0) ldc1 $f20,160(a0)
ldc1 $f22,(SC_FPREGS+176)(a0) ldc1 $f22,176(a0)
ldc1 $f24,(SC_FPREGS+192)(a0) ldc1 $f24,192(a0)
ldc1 $f26,(SC_FPREGS+208)(a0) ldc1 $f26,208(a0)
ldc1 $f28,(SC_FPREGS+224)(a0) ldc1 $f28,224(a0)
ldc1 $f30,(SC_FPREGS+240)(a0) ldc1 $f30,240(a0)
jr ra jr ra
ctc1 t0,fcr31 ctc1 t0,fcr31
1: jr ra 1: jr ra

View File

@ -200,7 +200,7 @@ static inline __init unsigned long get_random_boot(void)
#if defined(CONFIG_USE_OF) #if defined(CONFIG_USE_OF)
/* Get any additional entropy passed in device tree */ /* Get any additional entropy passed in device tree */
{ if (initial_boot_params) {
int node, len; int node, len;
u64 *prop; u64 *prop;

View File

@ -368,6 +368,19 @@ static void __init bootmem_init(void)
end = PFN_DOWN(boot_mem_map.map[i].addr end = PFN_DOWN(boot_mem_map.map[i].addr
+ boot_mem_map.map[i].size); + boot_mem_map.map[i].size);
#ifndef CONFIG_HIGHMEM
/*
* Skip highmem here so we get an accurate max_low_pfn if low
* memory stops short of high memory.
* If the region overlaps HIGHMEM_START, end is clipped so
* max_pfn excludes the highmem portion.
*/
if (start >= PFN_DOWN(HIGHMEM_START))
continue;
if (end > PFN_DOWN(HIGHMEM_START))
end = PFN_DOWN(HIGHMEM_START);
#endif
if (end > max_low_pfn) if (end > max_low_pfn)
max_low_pfn = end; max_low_pfn = end;
if (start < min_low_pfn) if (start < min_low_pfn)

View File

@ -156,7 +156,7 @@ static void show_backtrace(struct task_struct *task, const struct pt_regs *regs)
print_ip_sym(pc); print_ip_sym(pc);
pc = unwind_stack(task, &sp, pc, &ra); pc = unwind_stack(task, &sp, pc, &ra);
} while (pc); } while (pc);
printk("\n"); pr_cont("\n");
} }
/* /*
@ -174,22 +174,24 @@ static void show_stacktrace(struct task_struct *task,
printk("Stack :"); printk("Stack :");
i = 0; i = 0;
while ((unsigned long) sp & (PAGE_SIZE - 1)) { while ((unsigned long) sp & (PAGE_SIZE - 1)) {
if (i && ((i % (64 / field)) == 0)) if (i && ((i % (64 / field)) == 0)) {
printk("\n "); pr_cont("\n");
printk(" ");
}
if (i > 39) { if (i > 39) {
printk(" ..."); pr_cont(" ...");
break; break;
} }
if (__get_user(stackdata, sp++)) { if (__get_user(stackdata, sp++)) {
printk(" (Bad stack address)"); pr_cont(" (Bad stack address)");
break; break;
} }
printk(" %0*lx", field, stackdata); pr_cont(" %0*lx", field, stackdata);
i++; i++;
} }
printk("\n"); pr_cont("\n");
show_backtrace(task, regs); show_backtrace(task, regs);
} }
@ -229,18 +231,19 @@ static void show_code(unsigned int __user *pc)
long i; long i;
unsigned short __user *pc16 = NULL; unsigned short __user *pc16 = NULL;
printk("\nCode:"); printk("Code:");
if ((unsigned long)pc & 1) if ((unsigned long)pc & 1)
pc16 = (unsigned short __user *)((unsigned long)pc & ~1); pc16 = (unsigned short __user *)((unsigned long)pc & ~1);
for(i = -3 ; i < 6 ; i++) { for(i = -3 ; i < 6 ; i++) {
unsigned int insn; unsigned int insn;
if (pc16 ? __get_user(insn, pc16 + i) : __get_user(insn, pc + i)) { if (pc16 ? __get_user(insn, pc16 + i) : __get_user(insn, pc + i)) {
printk(" (Bad address in epc)\n"); pr_cont(" (Bad address in epc)\n");
break; break;
} }
printk("%c%0*x%c", (i?' ':'<'), pc16 ? 4 : 8, insn, (i?' ':'>')); pr_cont("%c%0*x%c", (i?' ':'<'), pc16 ? 4 : 8, insn, (i?' ':'>'));
} }
pr_cont("\n");
} }
static void __show_regs(const struct pt_regs *regs) static void __show_regs(const struct pt_regs *regs)
@ -259,15 +262,15 @@ static void __show_regs(const struct pt_regs *regs)
if ((i % 4) == 0) if ((i % 4) == 0)
printk("$%2d :", i); printk("$%2d :", i);
if (i == 0) if (i == 0)
printk(" %0*lx", field, 0UL); pr_cont(" %0*lx", field, 0UL);
else if (i == 26 || i == 27) else if (i == 26 || i == 27)
printk(" %*s", field, ""); pr_cont(" %*s", field, "");
else else
printk(" %0*lx", field, regs->regs[i]); pr_cont(" %0*lx", field, regs->regs[i]);
i++; i++;
if ((i % 4) == 0) if ((i % 4) == 0)
printk("\n"); pr_cont("\n");
} }
#ifdef CONFIG_CPU_HAS_SMARTMIPS #ifdef CONFIG_CPU_HAS_SMARTMIPS
@ -288,46 +291,46 @@ static void __show_regs(const struct pt_regs *regs)
if (cpu_has_3kex) { if (cpu_has_3kex) {
if (regs->cp0_status & ST0_KUO) if (regs->cp0_status & ST0_KUO)
printk("KUo "); pr_cont("KUo ");
if (regs->cp0_status & ST0_IEO) if (regs->cp0_status & ST0_IEO)
printk("IEo "); pr_cont("IEo ");
if (regs->cp0_status & ST0_KUP) if (regs->cp0_status & ST0_KUP)
printk("KUp "); pr_cont("KUp ");
if (regs->cp0_status & ST0_IEP) if (regs->cp0_status & ST0_IEP)
printk("IEp "); pr_cont("IEp ");
if (regs->cp0_status & ST0_KUC) if (regs->cp0_status & ST0_KUC)
printk("KUc "); pr_cont("KUc ");
if (regs->cp0_status & ST0_IEC) if (regs->cp0_status & ST0_IEC)
printk("IEc "); pr_cont("IEc ");
} else if (cpu_has_4kex) { } else if (cpu_has_4kex) {
if (regs->cp0_status & ST0_KX) if (regs->cp0_status & ST0_KX)
printk("KX "); pr_cont("KX ");
if (regs->cp0_status & ST0_SX) if (regs->cp0_status & ST0_SX)
printk("SX "); pr_cont("SX ");
if (regs->cp0_status & ST0_UX) if (regs->cp0_status & ST0_UX)
printk("UX "); pr_cont("UX ");
switch (regs->cp0_status & ST0_KSU) { switch (regs->cp0_status & ST0_KSU) {
case KSU_USER: case KSU_USER:
printk("USER "); pr_cont("USER ");
break; break;
case KSU_SUPERVISOR: case KSU_SUPERVISOR:
printk("SUPERVISOR "); pr_cont("SUPERVISOR ");
break; break;
case KSU_KERNEL: case KSU_KERNEL:
printk("KERNEL "); pr_cont("KERNEL ");
break; break;
default: default:
printk("BAD_MODE "); pr_cont("BAD_MODE ");
break; break;
} }
if (regs->cp0_status & ST0_ERL) if (regs->cp0_status & ST0_ERL)
printk("ERL "); pr_cont("ERL ");
if (regs->cp0_status & ST0_EXL) if (regs->cp0_status & ST0_EXL)
printk("EXL "); pr_cont("EXL ");
if (regs->cp0_status & ST0_IE) if (regs->cp0_status & ST0_IE)
printk("IE "); pr_cont("IE ");
} }
printk("\n"); pr_cont("\n");
exccode = (cause & CAUSEF_EXCCODE) >> CAUSEB_EXCCODE; exccode = (cause & CAUSEF_EXCCODE) >> CAUSEB_EXCCODE;
printk("Cause : %08x (ExcCode %02x)\n", cause, exccode); printk("Cause : %08x (ExcCode %02x)\n", cause, exccode);
@ -705,6 +708,32 @@ asmlinkage void do_ov(struct pt_regs *regs)
exception_exit(prev_state); exception_exit(prev_state);
} }
/*
* Send SIGFPE according to FCSR Cause bits, which must have already
* been masked against Enable bits. This is impotant as Inexact can
* happen together with Overflow or Underflow, and `ptrace' can set
* any bits.
*/
void force_fcr31_sig(unsigned long fcr31, void __user *fault_addr,
struct task_struct *tsk)
{
struct siginfo si = { .si_addr = fault_addr, .si_signo = SIGFPE };
if (fcr31 & FPU_CSR_INV_X)
si.si_code = FPE_FLTINV;
else if (fcr31 & FPU_CSR_DIV_X)
si.si_code = FPE_FLTDIV;
else if (fcr31 & FPU_CSR_OVF_X)
si.si_code = FPE_FLTOVF;
else if (fcr31 & FPU_CSR_UDF_X)
si.si_code = FPE_FLTUND;
else if (fcr31 & FPU_CSR_INE_X)
si.si_code = FPE_FLTRES;
else
si.si_code = __SI_FAULT;
force_sig_info(SIGFPE, &si, tsk);
}
int process_fpemu_return(int sig, void __user *fault_addr, unsigned long fcr31) int process_fpemu_return(int sig, void __user *fault_addr, unsigned long fcr31)
{ {
struct siginfo si = { 0 }; struct siginfo si = { 0 };
@ -715,27 +744,7 @@ int process_fpemu_return(int sig, void __user *fault_addr, unsigned long fcr31)
return 0; return 0;
case SIGFPE: case SIGFPE:
si.si_addr = fault_addr; force_fcr31_sig(fcr31, fault_addr, current);
si.si_signo = sig;
/*
* Inexact can happen together with Overflow or Underflow.
* Respect the mask to deliver the correct exception.
*/
fcr31 &= (fcr31 & FPU_CSR_ALL_E) <<
(ffs(FPU_CSR_ALL_X) - ffs(FPU_CSR_ALL_E));
if (fcr31 & FPU_CSR_INV_X)
si.si_code = FPE_FLTINV;
else if (fcr31 & FPU_CSR_DIV_X)
si.si_code = FPE_FLTDIV;
else if (fcr31 & FPU_CSR_OVF_X)
si.si_code = FPE_FLTOVF;
else if (fcr31 & FPU_CSR_UDF_X)
si.si_code = FPE_FLTUND;
else if (fcr31 & FPU_CSR_INE_X)
si.si_code = FPE_FLTRES;
else
si.si_code = __SI_FAULT;
force_sig_info(sig, &si, current);
return 1; return 1;
case SIGBUS: case SIGBUS:
@ -799,13 +808,13 @@ static int simulate_fp(struct pt_regs *regs, unsigned int opcode,
/* Run the emulator */ /* Run the emulator */
sig = fpu_emulator_cop1Handler(regs, &current->thread.fpu, 1, sig = fpu_emulator_cop1Handler(regs, &current->thread.fpu, 1,
&fault_addr); &fault_addr);
fcr31 = current->thread.fpu.fcr31;
/* /*
* We can't allow the emulated instruction to leave any of * We can't allow the emulated instruction to leave any
* the cause bits set in $fcr31. * enabled Cause bits set in $fcr31.
*/ */
current->thread.fpu.fcr31 &= ~FPU_CSR_ALL_X; fcr31 = mask_fcr31_x(current->thread.fpu.fcr31);
current->thread.fpu.fcr31 &= ~fcr31;
/* Restore the hardware register state */ /* Restore the hardware register state */
own_fpu(1); own_fpu(1);
@ -831,7 +840,7 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31)
goto out; goto out;
/* Clear FCSR.Cause before enabling interrupts */ /* Clear FCSR.Cause before enabling interrupts */
write_32bit_cp1_register(CP1_STATUS, fcr31 & ~FPU_CSR_ALL_X); write_32bit_cp1_register(CP1_STATUS, fcr31 & ~mask_fcr31_x(fcr31));
local_irq_enable(); local_irq_enable();
die_if_kernel("FP exception in kernel code", regs); die_if_kernel("FP exception in kernel code", regs);
@ -853,13 +862,13 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31)
/* Run the emulator */ /* Run the emulator */
sig = fpu_emulator_cop1Handler(regs, &current->thread.fpu, 1, sig = fpu_emulator_cop1Handler(regs, &current->thread.fpu, 1,
&fault_addr); &fault_addr);
fcr31 = current->thread.fpu.fcr31;
/* /*
* We can't allow the emulated instruction to leave any of * We can't allow the emulated instruction to leave any
* the cause bits set in $fcr31. * enabled Cause bits set in $fcr31.
*/ */
current->thread.fpu.fcr31 &= ~FPU_CSR_ALL_X; fcr31 = mask_fcr31_x(current->thread.fpu.fcr31);
current->thread.fpu.fcr31 &= ~fcr31;
/* Restore the hardware register state */ /* Restore the hardware register state */
own_fpu(1); /* Using the FPU again. */ own_fpu(1); /* Using the FPU again. */
@ -1424,13 +1433,13 @@ asmlinkage void do_cpu(struct pt_regs *regs)
sig = fpu_emulator_cop1Handler(regs, &current->thread.fpu, 0, sig = fpu_emulator_cop1Handler(regs, &current->thread.fpu, 0,
&fault_addr); &fault_addr);
fcr31 = current->thread.fpu.fcr31;
/* /*
* We can't allow the emulated instruction to leave * We can't allow the emulated instruction to leave
* any of the cause bits set in $fcr31. * any enabled Cause bits set in $fcr31.
*/ */
current->thread.fpu.fcr31 &= ~FPU_CSR_ALL_X; fcr31 = mask_fcr31_x(current->thread.fpu.fcr31);
current->thread.fpu.fcr31 &= ~fcr31;
/* Send a signal if required. */ /* Send a signal if required. */
if (!process_fpemu_return(sig, fault_addr, fcr31) && !err) if (!process_fpemu_return(sig, fault_addr, fcr31) && !err)

View File

@ -790,15 +790,15 @@ enum emulation_result kvm_mips_emul_eret(struct kvm_vcpu *vcpu)
struct mips_coproc *cop0 = vcpu->arch.cop0; struct mips_coproc *cop0 = vcpu->arch.cop0;
enum emulation_result er = EMULATE_DONE; enum emulation_result er = EMULATE_DONE;
if (kvm_read_c0_guest_status(cop0) & ST0_EXL) { if (kvm_read_c0_guest_status(cop0) & ST0_ERL) {
kvm_clear_c0_guest_status(cop0, ST0_ERL);
vcpu->arch.pc = kvm_read_c0_guest_errorepc(cop0);
} else if (kvm_read_c0_guest_status(cop0) & ST0_EXL) {
kvm_debug("[%#lx] ERET to %#lx\n", vcpu->arch.pc, kvm_debug("[%#lx] ERET to %#lx\n", vcpu->arch.pc,
kvm_read_c0_guest_epc(cop0)); kvm_read_c0_guest_epc(cop0));
kvm_clear_c0_guest_status(cop0, ST0_EXL); kvm_clear_c0_guest_status(cop0, ST0_EXL);
vcpu->arch.pc = kvm_read_c0_guest_epc(cop0); vcpu->arch.pc = kvm_read_c0_guest_epc(cop0);
} else if (kvm_read_c0_guest_status(cop0) & ST0_ERL) {
kvm_clear_c0_guest_status(cop0, ST0_ERL);
vcpu->arch.pc = kvm_read_c0_guest_errorepc(cop0);
} else { } else {
kvm_err("[%#lx] ERET when MIPS_SR_EXL|MIPS_SR_ERL == 0\n", kvm_err("[%#lx] ERET when MIPS_SR_EXL|MIPS_SR_ERL == 0\n",
vcpu->arch.pc); vcpu->arch.pc);
@ -1528,13 +1528,25 @@ enum emulation_result kvm_mips_emulate_load(union mips_instruction inst,
struct kvm_vcpu *vcpu) struct kvm_vcpu *vcpu)
{ {
enum emulation_result er = EMULATE_DO_MMIO; enum emulation_result er = EMULATE_DO_MMIO;
unsigned long curr_pc;
u32 op, rt; u32 op, rt;
u32 bytes; u32 bytes;
rt = inst.i_format.rt; rt = inst.i_format.rt;
op = inst.i_format.opcode; op = inst.i_format.opcode;
vcpu->arch.pending_load_cause = cause; /*
* Find the resume PC now while we have safe and easy access to the
* prior branch instruction, and save it for
* kvm_mips_complete_mmio_load() to restore later.
*/
curr_pc = vcpu->arch.pc;
er = update_pc(vcpu, cause);
if (er == EMULATE_FAIL)
return er;
vcpu->arch.io_pc = vcpu->arch.pc;
vcpu->arch.pc = curr_pc;
vcpu->arch.io_gpr = rt; vcpu->arch.io_gpr = rt;
switch (op) { switch (op) {
@ -2494,9 +2506,8 @@ enum emulation_result kvm_mips_complete_mmio_load(struct kvm_vcpu *vcpu,
goto done; goto done;
} }
er = update_pc(vcpu, vcpu->arch.pending_load_cause); /* Restore saved resume PC */
if (er == EMULATE_FAIL) vcpu->arch.pc = vcpu->arch.io_pc;
return er;
switch (run->mmio.len) { switch (run->mmio.len) {
case 4: case 4:
@ -2518,11 +2529,6 @@ enum emulation_result kvm_mips_complete_mmio_load(struct kvm_vcpu *vcpu,
break; break;
} }
if (vcpu->arch.pending_load_cause & CAUSEF_BD)
kvm_debug("[%#lx] Completing %d byte BD Load to gpr %d (0x%08lx) type %d\n",
vcpu->arch.pc, run->mmio.len, vcpu->arch.io_gpr, *gpr,
vcpu->mmio_needed);
done: done:
return er; return er;
} }

View File

@ -426,7 +426,7 @@ int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
static void kvm_mips_check_asids(struct kvm_vcpu *vcpu) static void kvm_mips_check_asids(struct kvm_vcpu *vcpu)
{ {
struct mips_coproc *cop0 = vcpu->arch.cop0; struct mips_coproc *cop0 = vcpu->arch.cop0;
int cpu = smp_processor_id(); int i, cpu = smp_processor_id();
unsigned int gasid; unsigned int gasid;
/* /*
@ -442,6 +442,9 @@ static void kvm_mips_check_asids(struct kvm_vcpu *vcpu)
vcpu); vcpu);
vcpu->arch.guest_user_asid[cpu] = vcpu->arch.guest_user_asid[cpu] =
vcpu->arch.guest_user_mm.context.asid[cpu]; vcpu->arch.guest_user_mm.context.asid[cpu];
for_each_possible_cpu(i)
if (i != cpu)
vcpu->arch.guest_user_asid[cpu] = 0;
vcpu->arch.last_user_gasid = gasid; vcpu->arch.last_user_gasid = gasid;
} }
} }

View File

@ -260,13 +260,9 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
if ((vcpu->arch.guest_user_asid[cpu] ^ asid_cache(cpu)) & if ((vcpu->arch.guest_user_asid[cpu] ^ asid_cache(cpu)) &
asid_version_mask(cpu)) { asid_version_mask(cpu)) {
u32 gasid = kvm_read_c0_guest_entryhi(vcpu->arch.cop0) &
KVM_ENTRYHI_ASID;
kvm_get_new_mmu_context(&vcpu->arch.guest_user_mm, cpu, vcpu); kvm_get_new_mmu_context(&vcpu->arch.guest_user_mm, cpu, vcpu);
vcpu->arch.guest_user_asid[cpu] = vcpu->arch.guest_user_asid[cpu] =
vcpu->arch.guest_user_mm.context.asid[cpu]; vcpu->arch.guest_user_mm.context.asid[cpu];
vcpu->arch.last_user_gasid = gasid;
newasid++; newasid++;
kvm_debug("[%d]: cpu_context: %#lx\n", cpu, kvm_debug("[%d]: cpu_context: %#lx\n", cpu,

View File

@ -135,42 +135,42 @@ static void dump_tlb(int first, int last)
c0 = (entrylo0 & ENTRYLO_C) >> ENTRYLO_C_SHIFT; c0 = (entrylo0 & ENTRYLO_C) >> ENTRYLO_C_SHIFT;
c1 = (entrylo1 & ENTRYLO_C) >> ENTRYLO_C_SHIFT; c1 = (entrylo1 & ENTRYLO_C) >> ENTRYLO_C_SHIFT;
printk("va=%0*lx asid=%0*lx", pr_cont("va=%0*lx asid=%0*lx",
vwidth, (entryhi & ~0x1fffUL), vwidth, (entryhi & ~0x1fffUL),
asidwidth, entryhi & asidmask); asidwidth, entryhi & asidmask);
if (cpu_has_guestid) if (cpu_has_guestid)
printk(" gid=%02lx", pr_cont(" gid=%02lx",
(guestctl1 & MIPS_GCTL1_RID) (guestctl1 & MIPS_GCTL1_RID)
>> MIPS_GCTL1_RID_SHIFT); >> MIPS_GCTL1_RID_SHIFT);
/* RI/XI are in awkward places, so mask them off separately */ /* RI/XI are in awkward places, so mask them off separately */
pa = entrylo0 & ~(MIPS_ENTRYLO_RI | MIPS_ENTRYLO_XI); pa = entrylo0 & ~(MIPS_ENTRYLO_RI | MIPS_ENTRYLO_XI);
if (xpa) if (xpa)
pa |= (unsigned long long)readx_c0_entrylo0() << 30; pa |= (unsigned long long)readx_c0_entrylo0() << 30;
pa = (pa << 6) & PAGE_MASK; pa = (pa << 6) & PAGE_MASK;
printk("\n\t["); pr_cont("\n\t[");
if (cpu_has_rixi) if (cpu_has_rixi)
printk("ri=%d xi=%d ", pr_cont("ri=%d xi=%d ",
(entrylo0 & MIPS_ENTRYLO_RI) ? 1 : 0, (entrylo0 & MIPS_ENTRYLO_RI) ? 1 : 0,
(entrylo0 & MIPS_ENTRYLO_XI) ? 1 : 0); (entrylo0 & MIPS_ENTRYLO_XI) ? 1 : 0);
printk("pa=%0*llx c=%d d=%d v=%d g=%d] [", pr_cont("pa=%0*llx c=%d d=%d v=%d g=%d] [",
pwidth, pa, c0, pwidth, pa, c0,
(entrylo0 & ENTRYLO_D) ? 1 : 0, (entrylo0 & ENTRYLO_D) ? 1 : 0,
(entrylo0 & ENTRYLO_V) ? 1 : 0, (entrylo0 & ENTRYLO_V) ? 1 : 0,
(entrylo0 & ENTRYLO_G) ? 1 : 0); (entrylo0 & ENTRYLO_G) ? 1 : 0);
/* RI/XI are in awkward places, so mask them off separately */ /* RI/XI are in awkward places, so mask them off separately */
pa = entrylo1 & ~(MIPS_ENTRYLO_RI | MIPS_ENTRYLO_XI); pa = entrylo1 & ~(MIPS_ENTRYLO_RI | MIPS_ENTRYLO_XI);
if (xpa) if (xpa)
pa |= (unsigned long long)readx_c0_entrylo1() << 30; pa |= (unsigned long long)readx_c0_entrylo1() << 30;
pa = (pa << 6) & PAGE_MASK; pa = (pa << 6) & PAGE_MASK;
if (cpu_has_rixi) if (cpu_has_rixi)
printk("ri=%d xi=%d ", pr_cont("ri=%d xi=%d ",
(entrylo1 & MIPS_ENTRYLO_RI) ? 1 : 0, (entrylo1 & MIPS_ENTRYLO_RI) ? 1 : 0,
(entrylo1 & MIPS_ENTRYLO_XI) ? 1 : 0); (entrylo1 & MIPS_ENTRYLO_XI) ? 1 : 0);
printk("pa=%0*llx c=%d d=%d v=%d g=%d]\n", pr_cont("pa=%0*llx c=%d d=%d v=%d g=%d]\n",
pwidth, pa, c1, pwidth, pa, c1,
(entrylo1 & ENTRYLO_D) ? 1 : 0, (entrylo1 & ENTRYLO_D) ? 1 : 0,
(entrylo1 & ENTRYLO_V) ? 1 : 0, (entrylo1 & ENTRYLO_V) ? 1 : 0,
(entrylo1 & ENTRYLO_G) ? 1 : 0); (entrylo1 & ENTRYLO_G) ? 1 : 0);
} }
printk("\n"); printk("\n");

View File

@ -53,15 +53,15 @@ static void dump_tlb(int first, int last)
*/ */
printk("Index: %2d ", i); printk("Index: %2d ", i);
printk("va=%08lx asid=%08lx" pr_cont("va=%08lx asid=%08lx"
" [pa=%06lx n=%d d=%d v=%d g=%d]", " [pa=%06lx n=%d d=%d v=%d g=%d]",
entryhi & PAGE_MASK, entryhi & PAGE_MASK,
entryhi & asid_mask, entryhi & asid_mask,
entrylo0 & PAGE_MASK, entrylo0 & PAGE_MASK,
(entrylo0 & R3K_ENTRYLO_N) ? 1 : 0, (entrylo0 & R3K_ENTRYLO_N) ? 1 : 0,
(entrylo0 & R3K_ENTRYLO_D) ? 1 : 0, (entrylo0 & R3K_ENTRYLO_D) ? 1 : 0,
(entrylo0 & R3K_ENTRYLO_V) ? 1 : 0, (entrylo0 & R3K_ENTRYLO_V) ? 1 : 0,
(entrylo0 & R3K_ENTRYLO_G) ? 1 : 0); (entrylo0 & R3K_ENTRYLO_G) ? 1 : 0);
} }
} }
printk("\n"); printk("\n");

View File

@ -324,6 +324,7 @@ static int __init nios2_time_init(struct device_node *timer)
ret = nios2_clocksource_init(timer); ret = nios2_clocksource_init(timer);
break; break;
default: default:
ret = 0;
break; break;
} }

View File

@ -23,6 +23,8 @@
* they shouldn't be hard-coded! * they shouldn't be hard-coded!
*/ */
#define __ro_after_init __read_mostly
#define L1_CACHE_BYTES 16 #define L1_CACHE_BYTES 16
#define L1_CACHE_SHIFT 4 #define L1_CACHE_SHIFT 4

View File

@ -368,7 +368,9 @@
#define __IGNORE_select /* newselect */ #define __IGNORE_select /* newselect */
#define __IGNORE_fadvise64 /* fadvise64_64 */ #define __IGNORE_fadvise64 /* fadvise64_64 */
#define __IGNORE_pkey_mprotect
#define __IGNORE_pkey_alloc
#define __IGNORE_pkey_free
#define LINUX_GATEWAY_ADDR 0x100 #define LINUX_GATEWAY_ADDR 0x100

View File

@ -873,11 +873,11 @@ static void print_parisc_device(struct parisc_device *dev)
if (dev->num_addrs) { if (dev->num_addrs) {
int k; int k;
printk(", additional addresses: "); pr_cont(", additional addresses: ");
for (k = 0; k < dev->num_addrs; k++) for (k = 0; k < dev->num_addrs; k++)
printk("0x%lx ", dev->addr[k]); pr_cont("0x%lx ", dev->addr[k]);
} }
printk("\n"); pr_cont("\n");
} }
/** /**

View File

@ -100,14 +100,12 @@ set_thread_pointer:
.endr .endr
/* This address must remain fixed at 0x100 for glibc's syscalls to work */ /* This address must remain fixed at 0x100 for glibc's syscalls to work */
.align 256 .align LINUX_GATEWAY_ADDR
linux_gateway_entry: linux_gateway_entry:
gate .+8, %r0 /* become privileged */ gate .+8, %r0 /* become privileged */
mtsp %r0,%sr4 /* get kernel space into sr4 */ mtsp %r0,%sr4 /* get kernel space into sr4 */
mtsp %r0,%sr5 /* get kernel space into sr5 */ mtsp %r0,%sr5 /* get kernel space into sr5 */
mtsp %r0,%sr6 /* get kernel space into sr6 */ mtsp %r0,%sr6 /* get kernel space into sr6 */
mfsp %sr7,%r1 /* save user sr7 */
mtsp %r1,%sr3 /* and store it in sr3 */
#ifdef CONFIG_64BIT #ifdef CONFIG_64BIT
/* for now we can *always* set the W bit on entry to the syscall /* for now we can *always* set the W bit on entry to the syscall
@ -133,6 +131,14 @@ linux_gateway_entry:
depdi 0, 31, 32, %r21 depdi 0, 31, 32, %r21
1: 1:
#endif #endif
/* We use a rsm/ssm pair to prevent sr3 from being clobbered
* by external interrupts.
*/
mfsp %sr7,%r1 /* save user sr7 */
rsm PSW_SM_I, %r0 /* disable interrupts */
mtsp %r1,%sr3 /* and store it in sr3 */
mfctl %cr30,%r1 mfctl %cr30,%r1
xor %r1,%r30,%r30 /* ye olde xor trick */ xor %r1,%r30,%r30 /* ye olde xor trick */
xor %r1,%r30,%r1 xor %r1,%r30,%r1
@ -147,6 +153,7 @@ linux_gateway_entry:
*/ */
mtsp %r0,%sr7 /* get kernel space into sr7 */ mtsp %r0,%sr7 /* get kernel space into sr7 */
ssm PSW_SM_I, %r0 /* enable interrupts */
STREGM %r1,FRAME_SIZE(%r30) /* save r1 (usp) here for now */ STREGM %r1,FRAME_SIZE(%r30) /* save r1 (usp) here for now */
mfctl %cr30,%r1 /* get task ptr in %r1 */ mfctl %cr30,%r1 /* get task ptr in %r1 */
LDREG TI_TASK(%r1),%r1 LDREG TI_TASK(%r1),%r1
@ -474,11 +481,6 @@ lws_start:
comiclr,>> __NR_lws_entries, %r20, %r0 comiclr,>> __NR_lws_entries, %r20, %r0
b,n lws_exit_nosys b,n lws_exit_nosys
/* WARNING: Trashing sr2 and sr3 */
mfsp %sr7,%r1 /* get userspace into sr3 */
mtsp %r1,%sr3
mtsp %r0,%sr2 /* get kernel space into sr2 */
/* Load table start */ /* Load table start */
ldil L%lws_table, %r1 ldil L%lws_table, %r1
ldo R%lws_table(%r1), %r28 /* Scratch use of r28 */ ldo R%lws_table(%r1), %r28 /* Scratch use of r28 */
@ -627,9 +629,9 @@ cas_action:
stw %r1, 4(%sr2,%r20) stw %r1, 4(%sr2,%r20)
#endif #endif
/* The load and store could fail */ /* The load and store could fail */
1: ldw,ma 0(%sr3,%r26), %r28 1: ldw,ma 0(%r26), %r28
sub,<> %r28, %r25, %r0 sub,<> %r28, %r25, %r0
2: stw,ma %r24, 0(%sr3,%r26) 2: stw,ma %r24, 0(%r26)
/* Free lock */ /* Free lock */
stw,ma %r20, 0(%sr2,%r20) stw,ma %r20, 0(%sr2,%r20)
#if ENABLE_LWS_DEBUG #if ENABLE_LWS_DEBUG
@ -706,9 +708,9 @@ lws_compare_and_swap_2:
nop nop
/* 8bit load */ /* 8bit load */
4: ldb 0(%sr3,%r25), %r25 4: ldb 0(%r25), %r25
b cas2_lock_start b cas2_lock_start
5: ldb 0(%sr3,%r24), %r24 5: ldb 0(%r24), %r24
nop nop
nop nop
nop nop
@ -716,9 +718,9 @@ lws_compare_and_swap_2:
nop nop
/* 16bit load */ /* 16bit load */
6: ldh 0(%sr3,%r25), %r25 6: ldh 0(%r25), %r25
b cas2_lock_start b cas2_lock_start
7: ldh 0(%sr3,%r24), %r24 7: ldh 0(%r24), %r24
nop nop
nop nop
nop nop
@ -726,9 +728,9 @@ lws_compare_and_swap_2:
nop nop
/* 32bit load */ /* 32bit load */
8: ldw 0(%sr3,%r25), %r25 8: ldw 0(%r25), %r25
b cas2_lock_start b cas2_lock_start
9: ldw 0(%sr3,%r24), %r24 9: ldw 0(%r24), %r24
nop nop
nop nop
nop nop
@ -737,14 +739,14 @@ lws_compare_and_swap_2:
/* 64bit load */ /* 64bit load */
#ifdef CONFIG_64BIT #ifdef CONFIG_64BIT
10: ldd 0(%sr3,%r25), %r25 10: ldd 0(%r25), %r25
11: ldd 0(%sr3,%r24), %r24 11: ldd 0(%r24), %r24
#else #else
/* Load new value into r22/r23 - high/low */ /* Load new value into r22/r23 - high/low */
10: ldw 0(%sr3,%r25), %r22 10: ldw 0(%r25), %r22
11: ldw 4(%sr3,%r25), %r23 11: ldw 4(%r25), %r23
/* Load new value into fr4 for atomic store later */ /* Load new value into fr4 for atomic store later */
12: flddx 0(%sr3,%r24), %fr4 12: flddx 0(%r24), %fr4
#endif #endif
cas2_lock_start: cas2_lock_start:
@ -794,30 +796,30 @@ cas2_action:
ldo 1(%r0),%r28 ldo 1(%r0),%r28
/* 8bit CAS */ /* 8bit CAS */
13: ldb,ma 0(%sr3,%r26), %r29 13: ldb,ma 0(%r26), %r29
sub,= %r29, %r25, %r0 sub,= %r29, %r25, %r0
b,n cas2_end b,n cas2_end
14: stb,ma %r24, 0(%sr3,%r26) 14: stb,ma %r24, 0(%r26)
b cas2_end b cas2_end
copy %r0, %r28 copy %r0, %r28
nop nop
nop nop
/* 16bit CAS */ /* 16bit CAS */
15: ldh,ma 0(%sr3,%r26), %r29 15: ldh,ma 0(%r26), %r29
sub,= %r29, %r25, %r0 sub,= %r29, %r25, %r0
b,n cas2_end b,n cas2_end
16: sth,ma %r24, 0(%sr3,%r26) 16: sth,ma %r24, 0(%r26)
b cas2_end b cas2_end
copy %r0, %r28 copy %r0, %r28
nop nop
nop nop
/* 32bit CAS */ /* 32bit CAS */
17: ldw,ma 0(%sr3,%r26), %r29 17: ldw,ma 0(%r26), %r29
sub,= %r29, %r25, %r0 sub,= %r29, %r25, %r0
b,n cas2_end b,n cas2_end
18: stw,ma %r24, 0(%sr3,%r26) 18: stw,ma %r24, 0(%r26)
b cas2_end b cas2_end
copy %r0, %r28 copy %r0, %r28
nop nop
@ -825,22 +827,22 @@ cas2_action:
/* 64bit CAS */ /* 64bit CAS */
#ifdef CONFIG_64BIT #ifdef CONFIG_64BIT
19: ldd,ma 0(%sr3,%r26), %r29 19: ldd,ma 0(%r26), %r29
sub,*= %r29, %r25, %r0 sub,*= %r29, %r25, %r0
b,n cas2_end b,n cas2_end
20: std,ma %r24, 0(%sr3,%r26) 20: std,ma %r24, 0(%r26)
copy %r0, %r28 copy %r0, %r28
#else #else
/* Compare first word */ /* Compare first word */
19: ldw,ma 0(%sr3,%r26), %r29 19: ldw,ma 0(%r26), %r29
sub,= %r29, %r22, %r0 sub,= %r29, %r22, %r0
b,n cas2_end b,n cas2_end
/* Compare second word */ /* Compare second word */
20: ldw,ma 4(%sr3,%r26), %r29 20: ldw,ma 4(%r26), %r29
sub,= %r29, %r23, %r0 sub,= %r29, %r23, %r0
b,n cas2_end b,n cas2_end
/* Perform the store */ /* Perform the store */
21: fstdx %fr4, 0(%sr3,%r26) 21: fstdx %fr4, 0(%r26)
copy %r0, %r28 copy %r0, %r28
#endif #endif

View File

@ -363,11 +363,11 @@ out:
static int diag224_get_name_table(void) static int diag224_get_name_table(void)
{ {
/* memory must be below 2GB */ /* memory must be below 2GB */
diag224_cpu_names = kmalloc(PAGE_SIZE, GFP_KERNEL | GFP_DMA); diag224_cpu_names = (char *) __get_free_page(GFP_KERNEL | GFP_DMA);
if (!diag224_cpu_names) if (!diag224_cpu_names)
return -ENOMEM; return -ENOMEM;
if (diag224(diag224_cpu_names)) { if (diag224(diag224_cpu_names)) {
kfree(diag224_cpu_names); free_page((unsigned long) diag224_cpu_names);
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
EBCASC(diag224_cpu_names + 16, (*diag224_cpu_names + 1) * 16); EBCASC(diag224_cpu_names + 16, (*diag224_cpu_names + 1) * 16);
@ -376,7 +376,7 @@ static int diag224_get_name_table(void)
static void diag224_delete_name_table(void) static void diag224_delete_name_table(void)
{ {
kfree(diag224_cpu_names); free_page((unsigned long) diag224_cpu_names);
} }
static int diag224_idx2name(int index, char *name) static int diag224_idx2name(int index, char *name)

View File

@ -62,9 +62,11 @@ SECTIONS
. = ALIGN(PAGE_SIZE); . = ALIGN(PAGE_SIZE);
__start_ro_after_init = .; __start_ro_after_init = .;
__start_data_ro_after_init = .;
.data..ro_after_init : { .data..ro_after_init : {
*(.data..ro_after_init) *(.data..ro_after_init)
} }
__end_data_ro_after_init = .;
EXCEPTION_TABLE(16) EXCEPTION_TABLE(16)
. = ALIGN(PAGE_SIZE); . = ALIGN(PAGE_SIZE);
__end_ro_after_init = .; __end_ro_after_init = .;

View File

@ -315,7 +315,7 @@ static void fill_diag(struct sthyi_sctns *sctns)
if (r < 0) if (r < 0)
goto out; goto out;
diag224_buf = kmalloc(PAGE_SIZE, GFP_KERNEL | GFP_DMA); diag224_buf = (void *)__get_free_page(GFP_KERNEL | GFP_DMA);
if (!diag224_buf || diag224(diag224_buf)) if (!diag224_buf || diag224(diag224_buf))
goto out; goto out;
@ -378,7 +378,7 @@ static void fill_diag(struct sthyi_sctns *sctns)
sctns->par.infpval1 |= PAR_WGHT_VLD; sctns->par.infpval1 |= PAR_WGHT_VLD;
out: out:
kfree(diag224_buf); free_page((unsigned long)diag224_buf);
vfree(diag204_buf); vfree(diag204_buf);
} }

View File

@ -423,7 +423,7 @@ static int __s390_dma_map_sg(struct device *dev, struct scatterlist *sg,
dma_addr_t dma_addr_base, dma_addr; dma_addr_t dma_addr_base, dma_addr;
int flags = ZPCI_PTE_VALID; int flags = ZPCI_PTE_VALID;
struct scatterlist *s; struct scatterlist *s;
unsigned long pa; unsigned long pa = 0;
int ret; int ret;
size = PAGE_ALIGN(size); size = PAGE_ALIGN(size);

View File

@ -24,9 +24,10 @@ typedef struct {
unsigned int icache_line_size; unsigned int icache_line_size;
unsigned int ecache_size; unsigned int ecache_size;
unsigned int ecache_line_size; unsigned int ecache_line_size;
unsigned short sock_id; unsigned short sock_id; /* physical package */
unsigned short core_id; unsigned short core_id;
int proc_id; unsigned short max_cache_id; /* groupings of highest shared cache */
unsigned short proc_id; /* strand (aka HW thread) id */
} cpuinfo_sparc; } cpuinfo_sparc;
DECLARE_PER_CPU(cpuinfo_sparc, __cpu_data); DECLARE_PER_CPU(cpuinfo_sparc, __cpu_data);

View File

@ -134,7 +134,7 @@ static inline void arch_write_lock(arch_rwlock_t *rw)
*(volatile __u32 *)&lp->lock = ~0U; *(volatile __u32 *)&lp->lock = ~0U;
} }
static void inline arch_write_unlock(arch_rwlock_t *lock) static inline void arch_write_unlock(arch_rwlock_t *lock)
{ {
__asm__ __volatile__( __asm__ __volatile__(
" st %%g0, [%0]" " st %%g0, [%0]"

View File

@ -96,7 +96,7 @@ static inline void arch_spin_lock_flags(arch_spinlock_t *lock, unsigned long fla
/* Multi-reader locks, these are much saner than the 32-bit Sparc ones... */ /* Multi-reader locks, these are much saner than the 32-bit Sparc ones... */
static void inline arch_read_lock(arch_rwlock_t *lock) static inline void arch_read_lock(arch_rwlock_t *lock)
{ {
unsigned long tmp1, tmp2; unsigned long tmp1, tmp2;
@ -119,7 +119,7 @@ static void inline arch_read_lock(arch_rwlock_t *lock)
: "memory"); : "memory");
} }
static int inline arch_read_trylock(arch_rwlock_t *lock) static inline int arch_read_trylock(arch_rwlock_t *lock)
{ {
int tmp1, tmp2; int tmp1, tmp2;
@ -140,7 +140,7 @@ static int inline arch_read_trylock(arch_rwlock_t *lock)
return tmp1; return tmp1;
} }
static void inline arch_read_unlock(arch_rwlock_t *lock) static inline void arch_read_unlock(arch_rwlock_t *lock)
{ {
unsigned long tmp1, tmp2; unsigned long tmp1, tmp2;
@ -156,7 +156,7 @@ static void inline arch_read_unlock(arch_rwlock_t *lock)
: "memory"); : "memory");
} }
static void inline arch_write_lock(arch_rwlock_t *lock) static inline void arch_write_lock(arch_rwlock_t *lock)
{ {
unsigned long mask, tmp1, tmp2; unsigned long mask, tmp1, tmp2;
@ -181,7 +181,7 @@ static void inline arch_write_lock(arch_rwlock_t *lock)
: "memory"); : "memory");
} }
static void inline arch_write_unlock(arch_rwlock_t *lock) static inline void arch_write_unlock(arch_rwlock_t *lock)
{ {
__asm__ __volatile__( __asm__ __volatile__(
" stw %%g0, [%0]" " stw %%g0, [%0]"
@ -190,7 +190,7 @@ static void inline arch_write_unlock(arch_rwlock_t *lock)
: "memory"); : "memory");
} }
static int inline arch_write_trylock(arch_rwlock_t *lock) static inline int arch_write_trylock(arch_rwlock_t *lock)
{ {
unsigned long mask, tmp1, tmp2, result; unsigned long mask, tmp1, tmp2, result;

View File

@ -44,14 +44,20 @@ int __node_distance(int, int);
#define topology_physical_package_id(cpu) (cpu_data(cpu).proc_id) #define topology_physical_package_id(cpu) (cpu_data(cpu).proc_id)
#define topology_core_id(cpu) (cpu_data(cpu).core_id) #define topology_core_id(cpu) (cpu_data(cpu).core_id)
#define topology_core_cpumask(cpu) (&cpu_core_sib_map[cpu]) #define topology_core_cpumask(cpu) (&cpu_core_sib_map[cpu])
#define topology_core_cache_cpumask(cpu) (&cpu_core_sib_cache_map[cpu])
#define topology_sibling_cpumask(cpu) (&per_cpu(cpu_sibling_map, cpu)) #define topology_sibling_cpumask(cpu) (&per_cpu(cpu_sibling_map, cpu))
#endif /* CONFIG_SMP */ #endif /* CONFIG_SMP */
extern cpumask_t cpu_core_map[NR_CPUS]; extern cpumask_t cpu_core_map[NR_CPUS];
extern cpumask_t cpu_core_sib_map[NR_CPUS]; extern cpumask_t cpu_core_sib_map[NR_CPUS];
extern cpumask_t cpu_core_sib_cache_map[NR_CPUS];
/**
* Return cores that shares the last level cache.
*/
static inline const struct cpumask *cpu_coregroup_mask(int cpu) static inline const struct cpumask *cpu_coregroup_mask(int cpu)
{ {
return &cpu_core_map[cpu]; return &cpu_core_sib_cache_map[cpu];
} }
#endif /* _ASM_SPARC64_TOPOLOGY_H */ #endif /* _ASM_SPARC64_TOPOLOGY_H */

View File

@ -82,7 +82,6 @@ static inline int access_ok(int type, const void __user * addr, unsigned long si
return 1; return 1;
} }
void __ret_efault(void);
void __retl_efault(void); void __retl_efault(void);
/* Uh, these should become the main single-value transfer routines.. /* Uh, these should become the main single-value transfer routines..
@ -189,55 +188,34 @@ int __get_user_bad(void);
unsigned long __must_check ___copy_from_user(void *to, unsigned long __must_check ___copy_from_user(void *to,
const void __user *from, const void __user *from,
unsigned long size); unsigned long size);
unsigned long copy_from_user_fixup(void *to, const void __user *from,
unsigned long size);
static inline unsigned long __must_check static inline unsigned long __must_check
copy_from_user(void *to, const void __user *from, unsigned long size) copy_from_user(void *to, const void __user *from, unsigned long size)
{ {
unsigned long ret;
check_object_size(to, size, false); check_object_size(to, size, false);
ret = ___copy_from_user(to, from, size); return ___copy_from_user(to, from, size);
if (unlikely(ret))
ret = copy_from_user_fixup(to, from, size);
return ret;
} }
#define __copy_from_user copy_from_user #define __copy_from_user copy_from_user
unsigned long __must_check ___copy_to_user(void __user *to, unsigned long __must_check ___copy_to_user(void __user *to,
const void *from, const void *from,
unsigned long size); unsigned long size);
unsigned long copy_to_user_fixup(void __user *to, const void *from,
unsigned long size);
static inline unsigned long __must_check static inline unsigned long __must_check
copy_to_user(void __user *to, const void *from, unsigned long size) copy_to_user(void __user *to, const void *from, unsigned long size)
{ {
unsigned long ret;
check_object_size(from, size, true); check_object_size(from, size, true);
ret = ___copy_to_user(to, from, size); return ___copy_to_user(to, from, size);
if (unlikely(ret))
ret = copy_to_user_fixup(to, from, size);
return ret;
} }
#define __copy_to_user copy_to_user #define __copy_to_user copy_to_user
unsigned long __must_check ___copy_in_user(void __user *to, unsigned long __must_check ___copy_in_user(void __user *to,
const void __user *from, const void __user *from,
unsigned long size); unsigned long size);
unsigned long copy_in_user_fixup(void __user *to, void __user *from,
unsigned long size);
static inline unsigned long __must_check static inline unsigned long __must_check
copy_in_user(void __user *to, void __user *from, unsigned long size) copy_in_user(void __user *to, void __user *from, unsigned long size)
{ {
unsigned long ret = ___copy_in_user(to, from, size); return ___copy_in_user(to, from, size);
if (unlikely(ret))
ret = copy_in_user_fixup(to, from, size);
return ret;
} }
#define __copy_in_user copy_in_user #define __copy_in_user copy_in_user

View File

@ -926,48 +926,11 @@ tlb_type: .word 0 /* Must NOT end up in BSS */
EXPORT_SYMBOL(tlb_type) EXPORT_SYMBOL(tlb_type)
.section ".fixup",#alloc,#execinstr .section ".fixup",#alloc,#execinstr
.globl __ret_efault, __retl_efault, __ret_one, __retl_one
ENTRY(__ret_efault)
ret
restore %g0, -EFAULT, %o0
ENDPROC(__ret_efault)
EXPORT_SYMBOL(__ret_efault)
ENTRY(__retl_efault) ENTRY(__retl_efault)
retl retl
mov -EFAULT, %o0 mov -EFAULT, %o0
ENDPROC(__retl_efault) ENDPROC(__retl_efault)
ENTRY(__retl_one)
retl
mov 1, %o0
ENDPROC(__retl_one)
ENTRY(__retl_one_fp)
VISExitHalf
retl
mov 1, %o0
ENDPROC(__retl_one_fp)
ENTRY(__ret_one_asi)
wr %g0, ASI_AIUS, %asi
ret
restore %g0, 1, %o0
ENDPROC(__ret_one_asi)
ENTRY(__retl_one_asi)
wr %g0, ASI_AIUS, %asi
retl
mov 1, %o0
ENDPROC(__retl_one_asi)
ENTRY(__retl_one_asi_fp)
wr %g0, ASI_AIUS, %asi
VISExitHalf
retl
mov 1, %o0
ENDPROC(__retl_one_asi_fp)
ENTRY(__retl_o1) ENTRY(__retl_o1)
retl retl
mov %o1, %o0 mov %o1, %o0

View File

@ -13,19 +13,30 @@
void arch_jump_label_transform(struct jump_entry *entry, void arch_jump_label_transform(struct jump_entry *entry,
enum jump_label_type type) enum jump_label_type type)
{ {
u32 val;
u32 *insn = (u32 *) (unsigned long) entry->code; u32 *insn = (u32 *) (unsigned long) entry->code;
u32 val;
if (type == JUMP_LABEL_JMP) { if (type == JUMP_LABEL_JMP) {
s32 off = (s32)entry->target - (s32)entry->code; s32 off = (s32)entry->target - (s32)entry->code;
bool use_v9_branch = false;
BUG_ON(off & 3);
#ifdef CONFIG_SPARC64 #ifdef CONFIG_SPARC64
/* ba,pt %xcc, . + (off << 2) */ if (off <= 0xfffff && off >= -0x100000)
val = 0x10680000 | ((u32) off >> 2); use_v9_branch = true;
#else
/* ba . + (off << 2) */
val = 0x10800000 | ((u32) off >> 2);
#endif #endif
if (use_v9_branch) {
/* WDISP19 - target is . + immed << 2 */
/* ba,pt %xcc, . + off */
val = 0x10680000 | (((u32) off >> 2) & 0x7ffff);
} else {
/* WDISP22 - target is . + immed << 2 */
BUG_ON(off > 0x7fffff);
BUG_ON(off < -0x800000);
/* ba . + off */
val = 0x10800000 | (((u32) off >> 2) & 0x3fffff);
}
} else { } else {
val = 0x01000000; val = 0x01000000;
} }

View File

@ -645,13 +645,20 @@ static void __mark_core_id(struct mdesc_handle *hp, u64 node,
cpu_data(*id).core_id = core_id; cpu_data(*id).core_id = core_id;
} }
static void __mark_sock_id(struct mdesc_handle *hp, u64 node, static void __mark_max_cache_id(struct mdesc_handle *hp, u64 node,
int sock_id) int max_cache_id)
{ {
const u64 *id = mdesc_get_property(hp, node, "id", NULL); const u64 *id = mdesc_get_property(hp, node, "id", NULL);
if (*id < num_possible_cpus()) if (*id < num_possible_cpus()) {
cpu_data(*id).sock_id = sock_id; cpu_data(*id).max_cache_id = max_cache_id;
/**
* On systems without explicit socket descriptions socket
* is max_cache_id
*/
cpu_data(*id).sock_id = max_cache_id;
}
} }
static void mark_core_ids(struct mdesc_handle *hp, u64 mp, static void mark_core_ids(struct mdesc_handle *hp, u64 mp,
@ -660,10 +667,11 @@ static void mark_core_ids(struct mdesc_handle *hp, u64 mp,
find_back_node_value(hp, mp, "cpu", __mark_core_id, core_id, 10); find_back_node_value(hp, mp, "cpu", __mark_core_id, core_id, 10);
} }
static void mark_sock_ids(struct mdesc_handle *hp, u64 mp, static void mark_max_cache_ids(struct mdesc_handle *hp, u64 mp,
int sock_id) int max_cache_id)
{ {
find_back_node_value(hp, mp, "cpu", __mark_sock_id, sock_id, 10); find_back_node_value(hp, mp, "cpu", __mark_max_cache_id,
max_cache_id, 10);
} }
static void set_core_ids(struct mdesc_handle *hp) static void set_core_ids(struct mdesc_handle *hp)
@ -694,14 +702,15 @@ static void set_core_ids(struct mdesc_handle *hp)
} }
} }
static int set_sock_ids_by_cache(struct mdesc_handle *hp, int level) static int set_max_cache_ids_by_cache(struct mdesc_handle *hp, int level)
{ {
u64 mp; u64 mp;
int idx = 1; int idx = 1;
int fnd = 0; int fnd = 0;
/* Identify unique sockets by looking for cpus backpointed to by /**
* shared level n caches. * Identify unique highest level of shared cache by looking for cpus
* backpointed to by shared level N caches.
*/ */
mdesc_for_each_node_by_name(hp, mp, "cache") { mdesc_for_each_node_by_name(hp, mp, "cache") {
const u64 *cur_lvl; const u64 *cur_lvl;
@ -709,8 +718,7 @@ static int set_sock_ids_by_cache(struct mdesc_handle *hp, int level)
cur_lvl = mdesc_get_property(hp, mp, "level", NULL); cur_lvl = mdesc_get_property(hp, mp, "level", NULL);
if (*cur_lvl != level) if (*cur_lvl != level)
continue; continue;
mark_max_cache_ids(hp, mp, idx);
mark_sock_ids(hp, mp, idx);
idx++; idx++;
fnd = 1; fnd = 1;
} }
@ -745,15 +753,17 @@ static void set_sock_ids(struct mdesc_handle *hp)
{ {
u64 mp; u64 mp;
/* If machine description exposes sockets data use it. /**
* Otherwise fallback to use shared L3 or L2 caches. * Find the highest level of shared cache which pre-T7 is also
* the socket.
*/ */
if (!set_max_cache_ids_by_cache(hp, 3))
set_max_cache_ids_by_cache(hp, 2);
/* If machine description exposes sockets data use it.*/
mp = mdesc_node_by_name(hp, MDESC_NODE_NULL, "sockets"); mp = mdesc_node_by_name(hp, MDESC_NODE_NULL, "sockets");
if (mp != MDESC_NODE_NULL) if (mp != MDESC_NODE_NULL)
return set_sock_ids_by_socket(hp, mp); set_sock_ids_by_socket(hp, mp);
if (!set_sock_ids_by_cache(hp, 3))
set_sock_ids_by_cache(hp, 2);
} }
static void mark_proc_ids(struct mdesc_handle *hp, u64 mp, int proc_id) static void mark_proc_ids(struct mdesc_handle *hp, u64 mp, int proc_id)

View File

@ -63,9 +63,13 @@ cpumask_t cpu_core_map[NR_CPUS] __read_mostly =
cpumask_t cpu_core_sib_map[NR_CPUS] __read_mostly = { cpumask_t cpu_core_sib_map[NR_CPUS] __read_mostly = {
[0 ... NR_CPUS-1] = CPU_MASK_NONE }; [0 ... NR_CPUS-1] = CPU_MASK_NONE };
cpumask_t cpu_core_sib_cache_map[NR_CPUS] __read_mostly = {
[0 ... NR_CPUS - 1] = CPU_MASK_NONE };
EXPORT_PER_CPU_SYMBOL(cpu_sibling_map); EXPORT_PER_CPU_SYMBOL(cpu_sibling_map);
EXPORT_SYMBOL(cpu_core_map); EXPORT_SYMBOL(cpu_core_map);
EXPORT_SYMBOL(cpu_core_sib_map); EXPORT_SYMBOL(cpu_core_sib_map);
EXPORT_SYMBOL(cpu_core_sib_cache_map);
static cpumask_t smp_commenced_mask; static cpumask_t smp_commenced_mask;
@ -1265,6 +1269,10 @@ void smp_fill_in_sib_core_maps(void)
unsigned int j; unsigned int j;
for_each_present_cpu(j) { for_each_present_cpu(j) {
if (cpu_data(i).max_cache_id ==
cpu_data(j).max_cache_id)
cpumask_set_cpu(j, &cpu_core_sib_cache_map[i]);
if (cpu_data(i).sock_id == cpu_data(j).sock_id) if (cpu_data(i).sock_id == cpu_data(j).sock_id)
cpumask_set_cpu(j, &cpu_core_sib_map[i]); cpumask_set_cpu(j, &cpu_core_sib_map[i]);
} }

View File

@ -3,11 +3,11 @@
* Copyright (C) 2007 David S. Miller (davem@davemloft.net) * Copyright (C) 2007 David S. Miller (davem@davemloft.net)
*/ */
#define EX_LD(x) \ #define EX_LD(x,y) \
98: x; \ 98: x; \
.section __ex_table,"a";\ .section __ex_table,"a";\
.align 4; \ .align 4; \
.word 98b, __retl_one; \ .word 98b, y; \
.text; \ .text; \
.align 4; .align 4;

View File

@ -3,11 +3,11 @@
* Copyright (C) 2007 David S. Miller (davem@davemloft.net) * Copyright (C) 2007 David S. Miller (davem@davemloft.net)
*/ */
#define EX_ST(x) \ #define EX_ST(x,y) \
98: x; \ 98: x; \
.section __ex_table,"a";\ .section __ex_table,"a";\
.align 4; \ .align 4; \
.word 98b, __retl_one; \ .word 98b, y; \
.text; \ .text; \
.align 4; .align 4;

View File

@ -4,21 +4,18 @@
*/ */
#ifdef __KERNEL__ #ifdef __KERNEL__
#include <linux/linkage.h>
#define GLOBAL_SPARE %g7 #define GLOBAL_SPARE %g7
#else #else
#define GLOBAL_SPARE %g5 #define GLOBAL_SPARE %g5
#endif #endif
#ifndef EX_LD #ifndef EX_LD
#define EX_LD(x) x #define EX_LD(x,y) x
#endif #endif
#ifndef EX_ST #ifndef EX_ST
#define EX_ST(x) x #define EX_ST(x,y) x
#endif
#ifndef EX_RETVAL
#define EX_RETVAL(x) x
#endif #endif
#ifndef LOAD #ifndef LOAD
@ -45,6 +42,29 @@
.register %g3,#scratch .register %g3,#scratch
.text .text
#ifndef EX_RETVAL
#define EX_RETVAL(x) x
ENTRY(GEN_retl_o4_1)
add %o4, %o2, %o4
retl
add %o4, 1, %o0
ENDPROC(GEN_retl_o4_1)
ENTRY(GEN_retl_g1_8)
add %g1, %o2, %g1
retl
add %g1, 8, %o0
ENDPROC(GEN_retl_g1_8)
ENTRY(GEN_retl_o2_4)
retl
add %o2, 4, %o0
ENDPROC(GEN_retl_o2_4)
ENTRY(GEN_retl_o2_1)
retl
add %o2, 1, %o0
ENDPROC(GEN_retl_o2_1)
#endif
.align 64 .align 64
.globl FUNC_NAME .globl FUNC_NAME
@ -73,8 +93,8 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
sub %g0, %o4, %o4 sub %g0, %o4, %o4
sub %o2, %o4, %o2 sub %o2, %o4, %o2
1: subcc %o4, 1, %o4 1: subcc %o4, 1, %o4
EX_LD(LOAD(ldub, %o1, %g1)) EX_LD(LOAD(ldub, %o1, %g1),GEN_retl_o4_1)
EX_ST(STORE(stb, %g1, %o0)) EX_ST(STORE(stb, %g1, %o0),GEN_retl_o4_1)
add %o1, 1, %o1 add %o1, 1, %o1
bne,pt %XCC, 1b bne,pt %XCC, 1b
add %o0, 1, %o0 add %o0, 1, %o0
@ -82,8 +102,8 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
andn %o2, 0x7, %g1 andn %o2, 0x7, %g1
sub %o2, %g1, %o2 sub %o2, %g1, %o2
1: subcc %g1, 0x8, %g1 1: subcc %g1, 0x8, %g1
EX_LD(LOAD(ldx, %o1, %g2)) EX_LD(LOAD(ldx, %o1, %g2),GEN_retl_g1_8)
EX_ST(STORE(stx, %g2, %o0)) EX_ST(STORE(stx, %g2, %o0),GEN_retl_g1_8)
add %o1, 0x8, %o1 add %o1, 0x8, %o1
bne,pt %XCC, 1b bne,pt %XCC, 1b
add %o0, 0x8, %o0 add %o0, 0x8, %o0
@ -100,8 +120,8 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
1: 1:
subcc %o2, 4, %o2 subcc %o2, 4, %o2
EX_LD(LOAD(lduw, %o1, %g1)) EX_LD(LOAD(lduw, %o1, %g1),GEN_retl_o2_4)
EX_ST(STORE(stw, %g1, %o1 + %o3)) EX_ST(STORE(stw, %g1, %o1 + %o3),GEN_retl_o2_4)
bgu,pt %XCC, 1b bgu,pt %XCC, 1b
add %o1, 4, %o1 add %o1, 4, %o1
@ -111,8 +131,8 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
.align 32 .align 32
90: 90:
subcc %o2, 1, %o2 subcc %o2, 1, %o2
EX_LD(LOAD(ldub, %o1, %g1)) EX_LD(LOAD(ldub, %o1, %g1),GEN_retl_o2_1)
EX_ST(STORE(stb, %g1, %o1 + %o3)) EX_ST(STORE(stb, %g1, %o1 + %o3),GEN_retl_o2_1)
bgu,pt %XCC, 90b bgu,pt %XCC, 90b
add %o1, 1, %o1 add %o1, 1, %o1
retl retl

View File

@ -38,7 +38,7 @@ lib-$(CONFIG_SPARC64) += NG4patch.o NG4copy_page.o NG4clear_page.o NG4memset.o
lib-$(CONFIG_SPARC64) += GENmemcpy.o GENcopy_from_user.o GENcopy_to_user.o lib-$(CONFIG_SPARC64) += GENmemcpy.o GENcopy_from_user.o GENcopy_to_user.o
lib-$(CONFIG_SPARC64) += GENpatch.o GENpage.o GENbzero.o lib-$(CONFIG_SPARC64) += GENpatch.o GENpage.o GENbzero.o
lib-$(CONFIG_SPARC64) += copy_in_user.o user_fixup.o memmove.o lib-$(CONFIG_SPARC64) += copy_in_user.o memmove.o
lib-$(CONFIG_SPARC64) += mcount.o ipcsum.o xor.o hweight.o ffs.o lib-$(CONFIG_SPARC64) += mcount.o ipcsum.o xor.o hweight.o ffs.o
obj-$(CONFIG_SPARC64) += iomap.o obj-$(CONFIG_SPARC64) += iomap.o

View File

@ -3,19 +3,19 @@
* Copyright (C) 2007 David S. Miller (davem@davemloft.net) * Copyright (C) 2007 David S. Miller (davem@davemloft.net)
*/ */
#define EX_LD(x) \ #define EX_LD(x,y) \
98: x; \ 98: x; \
.section __ex_table,"a";\ .section __ex_table,"a";\
.align 4; \ .align 4; \
.word 98b, __retl_one_asi;\ .word 98b, y; \
.text; \ .text; \
.align 4; .align 4;
#define EX_LD_FP(x) \ #define EX_LD_FP(x,y) \
98: x; \ 98: x; \
.section __ex_table,"a";\ .section __ex_table,"a";\
.align 4; \ .align 4; \
.word 98b, __retl_one_asi_fp;\ .word 98b, y##_fp; \
.text; \ .text; \
.align 4; .align 4;

View File

@ -3,19 +3,19 @@
* Copyright (C) 2007 David S. Miller (davem@davemloft.net) * Copyright (C) 2007 David S. Miller (davem@davemloft.net)
*/ */
#define EX_ST(x) \ #define EX_ST(x,y) \
98: x; \ 98: x; \
.section __ex_table,"a";\ .section __ex_table,"a";\
.align 4; \ .align 4; \
.word 98b, __retl_one_asi;\ .word 98b, y; \
.text; \ .text; \
.align 4; .align 4;
#define EX_ST_FP(x) \ #define EX_ST_FP(x,y) \
98: x; \ 98: x; \
.section __ex_table,"a";\ .section __ex_table,"a";\
.align 4; \ .align 4; \
.word 98b, __retl_one_asi_fp;\ .word 98b, y##_fp; \
.text; \ .text; \
.align 4; .align 4;

View File

@ -4,6 +4,7 @@
*/ */
#ifdef __KERNEL__ #ifdef __KERNEL__
#include <linux/linkage.h>
#include <asm/visasm.h> #include <asm/visasm.h>
#include <asm/asi.h> #include <asm/asi.h>
#define GLOBAL_SPARE %g7 #define GLOBAL_SPARE %g7
@ -32,21 +33,17 @@
#endif #endif
#ifndef EX_LD #ifndef EX_LD
#define EX_LD(x) x #define EX_LD(x,y) x
#endif #endif
#ifndef EX_LD_FP #ifndef EX_LD_FP
#define EX_LD_FP(x) x #define EX_LD_FP(x,y) x
#endif #endif
#ifndef EX_ST #ifndef EX_ST
#define EX_ST(x) x #define EX_ST(x,y) x
#endif #endif
#ifndef EX_ST_FP #ifndef EX_ST_FP
#define EX_ST_FP(x) x #define EX_ST_FP(x,y) x
#endif
#ifndef EX_RETVAL
#define EX_RETVAL(x) x
#endif #endif
#ifndef LOAD #ifndef LOAD
@ -140,45 +137,110 @@
fsrc2 %x6, %f12; \ fsrc2 %x6, %f12; \
fsrc2 %x7, %f14; fsrc2 %x7, %f14;
#define FREG_LOAD_1(base, x0) \ #define FREG_LOAD_1(base, x0) \
EX_LD_FP(LOAD(ldd, base + 0x00, %x0)) EX_LD_FP(LOAD(ldd, base + 0x00, %x0), NG2_retl_o2_plus_g1)
#define FREG_LOAD_2(base, x0, x1) \ #define FREG_LOAD_2(base, x0, x1) \
EX_LD_FP(LOAD(ldd, base + 0x00, %x0)); \ EX_LD_FP(LOAD(ldd, base + 0x00, %x0), NG2_retl_o2_plus_g1); \
EX_LD_FP(LOAD(ldd, base + 0x08, %x1)); EX_LD_FP(LOAD(ldd, base + 0x08, %x1), NG2_retl_o2_plus_g1);
#define FREG_LOAD_3(base, x0, x1, x2) \ #define FREG_LOAD_3(base, x0, x1, x2) \
EX_LD_FP(LOAD(ldd, base + 0x00, %x0)); \ EX_LD_FP(LOAD(ldd, base + 0x00, %x0), NG2_retl_o2_plus_g1); \
EX_LD_FP(LOAD(ldd, base + 0x08, %x1)); \ EX_LD_FP(LOAD(ldd, base + 0x08, %x1), NG2_retl_o2_plus_g1); \
EX_LD_FP(LOAD(ldd, base + 0x10, %x2)); EX_LD_FP(LOAD(ldd, base + 0x10, %x2), NG2_retl_o2_plus_g1);
#define FREG_LOAD_4(base, x0, x1, x2, x3) \ #define FREG_LOAD_4(base, x0, x1, x2, x3) \
EX_LD_FP(LOAD(ldd, base + 0x00, %x0)); \ EX_LD_FP(LOAD(ldd, base + 0x00, %x0), NG2_retl_o2_plus_g1); \
EX_LD_FP(LOAD(ldd, base + 0x08, %x1)); \ EX_LD_FP(LOAD(ldd, base + 0x08, %x1), NG2_retl_o2_plus_g1); \
EX_LD_FP(LOAD(ldd, base + 0x10, %x2)); \ EX_LD_FP(LOAD(ldd, base + 0x10, %x2), NG2_retl_o2_plus_g1); \
EX_LD_FP(LOAD(ldd, base + 0x18, %x3)); EX_LD_FP(LOAD(ldd, base + 0x18, %x3), NG2_retl_o2_plus_g1);
#define FREG_LOAD_5(base, x0, x1, x2, x3, x4) \ #define FREG_LOAD_5(base, x0, x1, x2, x3, x4) \
EX_LD_FP(LOAD(ldd, base + 0x00, %x0)); \ EX_LD_FP(LOAD(ldd, base + 0x00, %x0), NG2_retl_o2_plus_g1); \
EX_LD_FP(LOAD(ldd, base + 0x08, %x1)); \ EX_LD_FP(LOAD(ldd, base + 0x08, %x1), NG2_retl_o2_plus_g1); \
EX_LD_FP(LOAD(ldd, base + 0x10, %x2)); \ EX_LD_FP(LOAD(ldd, base + 0x10, %x2), NG2_retl_o2_plus_g1); \
EX_LD_FP(LOAD(ldd, base + 0x18, %x3)); \ EX_LD_FP(LOAD(ldd, base + 0x18, %x3), NG2_retl_o2_plus_g1); \
EX_LD_FP(LOAD(ldd, base + 0x20, %x4)); EX_LD_FP(LOAD(ldd, base + 0x20, %x4), NG2_retl_o2_plus_g1);
#define FREG_LOAD_6(base, x0, x1, x2, x3, x4, x5) \ #define FREG_LOAD_6(base, x0, x1, x2, x3, x4, x5) \
EX_LD_FP(LOAD(ldd, base + 0x00, %x0)); \ EX_LD_FP(LOAD(ldd, base + 0x00, %x0), NG2_retl_o2_plus_g1); \
EX_LD_FP(LOAD(ldd, base + 0x08, %x1)); \ EX_LD_FP(LOAD(ldd, base + 0x08, %x1), NG2_retl_o2_plus_g1); \
EX_LD_FP(LOAD(ldd, base + 0x10, %x2)); \ EX_LD_FP(LOAD(ldd, base + 0x10, %x2), NG2_retl_o2_plus_g1); \
EX_LD_FP(LOAD(ldd, base + 0x18, %x3)); \ EX_LD_FP(LOAD(ldd, base + 0x18, %x3), NG2_retl_o2_plus_g1); \
EX_LD_FP(LOAD(ldd, base + 0x20, %x4)); \ EX_LD_FP(LOAD(ldd, base + 0x20, %x4), NG2_retl_o2_plus_g1); \
EX_LD_FP(LOAD(ldd, base + 0x28, %x5)); EX_LD_FP(LOAD(ldd, base + 0x28, %x5), NG2_retl_o2_plus_g1);
#define FREG_LOAD_7(base, x0, x1, x2, x3, x4, x5, x6) \ #define FREG_LOAD_7(base, x0, x1, x2, x3, x4, x5, x6) \
EX_LD_FP(LOAD(ldd, base + 0x00, %x0)); \ EX_LD_FP(LOAD(ldd, base + 0x00, %x0), NG2_retl_o2_plus_g1); \
EX_LD_FP(LOAD(ldd, base + 0x08, %x1)); \ EX_LD_FP(LOAD(ldd, base + 0x08, %x1), NG2_retl_o2_plus_g1); \
EX_LD_FP(LOAD(ldd, base + 0x10, %x2)); \ EX_LD_FP(LOAD(ldd, base + 0x10, %x2), NG2_retl_o2_plus_g1); \
EX_LD_FP(LOAD(ldd, base + 0x18, %x3)); \ EX_LD_FP(LOAD(ldd, base + 0x18, %x3), NG2_retl_o2_plus_g1); \
EX_LD_FP(LOAD(ldd, base + 0x20, %x4)); \ EX_LD_FP(LOAD(ldd, base + 0x20, %x4), NG2_retl_o2_plus_g1); \
EX_LD_FP(LOAD(ldd, base + 0x28, %x5)); \ EX_LD_FP(LOAD(ldd, base + 0x28, %x5), NG2_retl_o2_plus_g1); \
EX_LD_FP(LOAD(ldd, base + 0x30, %x6)); EX_LD_FP(LOAD(ldd, base + 0x30, %x6), NG2_retl_o2_plus_g1);
.register %g2,#scratch .register %g2,#scratch
.register %g3,#scratch .register %g3,#scratch
.text .text
#ifndef EX_RETVAL
#define EX_RETVAL(x) x
__restore_fp:
VISExitHalf
__restore_asi:
retl
wr %g0, ASI_AIUS, %asi
ENTRY(NG2_retl_o2)
ba,pt %xcc, __restore_asi
mov %o2, %o0
ENDPROC(NG2_retl_o2)
ENTRY(NG2_retl_o2_plus_1)
ba,pt %xcc, __restore_asi
add %o2, 1, %o0
ENDPROC(NG2_retl_o2_plus_1)
ENTRY(NG2_retl_o2_plus_4)
ba,pt %xcc, __restore_asi
add %o2, 4, %o0
ENDPROC(NG2_retl_o2_plus_4)
ENTRY(NG2_retl_o2_plus_8)
ba,pt %xcc, __restore_asi
add %o2, 8, %o0
ENDPROC(NG2_retl_o2_plus_8)
ENTRY(NG2_retl_o2_plus_o4_plus_1)
add %o4, 1, %o4
ba,pt %xcc, __restore_asi
add %o2, %o4, %o0
ENDPROC(NG2_retl_o2_plus_o4_plus_1)
ENTRY(NG2_retl_o2_plus_o4_plus_8)
add %o4, 8, %o4
ba,pt %xcc, __restore_asi
add %o2, %o4, %o0
ENDPROC(NG2_retl_o2_plus_o4_plus_8)
ENTRY(NG2_retl_o2_plus_o4_plus_16)
add %o4, 16, %o4
ba,pt %xcc, __restore_asi
add %o2, %o4, %o0
ENDPROC(NG2_retl_o2_plus_o4_plus_16)
ENTRY(NG2_retl_o2_plus_g1_fp)
ba,pt %xcc, __restore_fp
add %o2, %g1, %o0
ENDPROC(NG2_retl_o2_plus_g1_fp)
ENTRY(NG2_retl_o2_plus_g1_plus_64_fp)
add %g1, 64, %g1
ba,pt %xcc, __restore_fp
add %o2, %g1, %o0
ENDPROC(NG2_retl_o2_plus_g1_plus_64_fp)
ENTRY(NG2_retl_o2_plus_g1_plus_1)
add %g1, 1, %g1
ba,pt %xcc, __restore_asi
add %o2, %g1, %o0
ENDPROC(NG2_retl_o2_plus_g1_plus_1)
ENTRY(NG2_retl_o2_and_7_plus_o4)
and %o2, 7, %o2
ba,pt %xcc, __restore_asi
add %o2, %o4, %o0
ENDPROC(NG2_retl_o2_and_7_plus_o4)
ENTRY(NG2_retl_o2_and_7_plus_o4_plus_8)
and %o2, 7, %o2
add %o4, 8, %o4
ba,pt %xcc, __restore_asi
add %o2, %o4, %o0
ENDPROC(NG2_retl_o2_and_7_plus_o4_plus_8)
#endif
.align 64 .align 64
.globl FUNC_NAME .globl FUNC_NAME
@ -230,8 +292,8 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
sub %g0, %o4, %o4 ! bytes to align dst sub %g0, %o4, %o4 ! bytes to align dst
sub %o2, %o4, %o2 sub %o2, %o4, %o2
1: subcc %o4, 1, %o4 1: subcc %o4, 1, %o4
EX_LD(LOAD(ldub, %o1, %g1)) EX_LD(LOAD(ldub, %o1, %g1), NG2_retl_o2_plus_o4_plus_1)
EX_ST(STORE(stb, %g1, %o0)) EX_ST(STORE(stb, %g1, %o0), NG2_retl_o2_plus_o4_plus_1)
add %o1, 1, %o1 add %o1, 1, %o1
bne,pt %XCC, 1b bne,pt %XCC, 1b
add %o0, 1, %o0 add %o0, 1, %o0
@ -281,11 +343,11 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
nop nop
/* fall through for 0 < low bits < 8 */ /* fall through for 0 < low bits < 8 */
110: sub %o4, 64, %g2 110: sub %o4, 64, %g2
EX_LD_FP(LOAD_BLK(%g2, %f0)) EX_LD_FP(LOAD_BLK(%g2, %f0), NG2_retl_o2_plus_g1)
1: EX_ST_FP(STORE_INIT(%g0, %o4 + %g3)) 1: EX_ST_FP(STORE_INIT(%g0, %o4 + %g3), NG2_retl_o2_plus_g1)
EX_LD_FP(LOAD_BLK(%o4, %f16)) EX_LD_FP(LOAD_BLK(%o4, %f16), NG2_retl_o2_plus_g1)
FREG_FROB(f0, f2, f4, f6, f8, f10, f12, f14, f16) FREG_FROB(f0, f2, f4, f6, f8, f10, f12, f14, f16)
EX_ST_FP(STORE_BLK(%f0, %o4 + %g3)) EX_ST_FP(STORE_BLK(%f0, %o4 + %g3), NG2_retl_o2_plus_g1)
FREG_MOVE_8(f16, f18, f20, f22, f24, f26, f28, f30) FREG_MOVE_8(f16, f18, f20, f22, f24, f26, f28, f30)
subcc %g1, 64, %g1 subcc %g1, 64, %g1
add %o4, 64, %o4 add %o4, 64, %o4
@ -296,10 +358,10 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
120: sub %o4, 56, %g2 120: sub %o4, 56, %g2
FREG_LOAD_7(%g2, f0, f2, f4, f6, f8, f10, f12) FREG_LOAD_7(%g2, f0, f2, f4, f6, f8, f10, f12)
1: EX_ST_FP(STORE_INIT(%g0, %o4 + %g3)) 1: EX_ST_FP(STORE_INIT(%g0, %o4 + %g3), NG2_retl_o2_plus_g1)
EX_LD_FP(LOAD_BLK(%o4, %f16)) EX_LD_FP(LOAD_BLK(%o4, %f16), NG2_retl_o2_plus_g1)
FREG_FROB(f0, f2, f4, f6, f8, f10, f12, f16, f18) FREG_FROB(f0, f2, f4, f6, f8, f10, f12, f16, f18)
EX_ST_FP(STORE_BLK(%f0, %o4 + %g3)) EX_ST_FP(STORE_BLK(%f0, %o4 + %g3), NG2_retl_o2_plus_g1)
FREG_MOVE_7(f18, f20, f22, f24, f26, f28, f30) FREG_MOVE_7(f18, f20, f22, f24, f26, f28, f30)
subcc %g1, 64, %g1 subcc %g1, 64, %g1
add %o4, 64, %o4 add %o4, 64, %o4
@ -310,10 +372,10 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
130: sub %o4, 48, %g2 130: sub %o4, 48, %g2
FREG_LOAD_6(%g2, f0, f2, f4, f6, f8, f10) FREG_LOAD_6(%g2, f0, f2, f4, f6, f8, f10)
1: EX_ST_FP(STORE_INIT(%g0, %o4 + %g3)) 1: EX_ST_FP(STORE_INIT(%g0, %o4 + %g3), NG2_retl_o2_plus_g1)
EX_LD_FP(LOAD_BLK(%o4, %f16)) EX_LD_FP(LOAD_BLK(%o4, %f16), NG2_retl_o2_plus_g1)
FREG_FROB(f0, f2, f4, f6, f8, f10, f16, f18, f20) FREG_FROB(f0, f2, f4, f6, f8, f10, f16, f18, f20)
EX_ST_FP(STORE_BLK(%f0, %o4 + %g3)) EX_ST_FP(STORE_BLK(%f0, %o4 + %g3), NG2_retl_o2_plus_g1)
FREG_MOVE_6(f20, f22, f24, f26, f28, f30) FREG_MOVE_6(f20, f22, f24, f26, f28, f30)
subcc %g1, 64, %g1 subcc %g1, 64, %g1
add %o4, 64, %o4 add %o4, 64, %o4
@ -324,10 +386,10 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
140: sub %o4, 40, %g2 140: sub %o4, 40, %g2
FREG_LOAD_5(%g2, f0, f2, f4, f6, f8) FREG_LOAD_5(%g2, f0, f2, f4, f6, f8)
1: EX_ST_FP(STORE_INIT(%g0, %o4 + %g3)) 1: EX_ST_FP(STORE_INIT(%g0, %o4 + %g3), NG2_retl_o2_plus_g1)
EX_LD_FP(LOAD_BLK(%o4, %f16)) EX_LD_FP(LOAD_BLK(%o4, %f16), NG2_retl_o2_plus_g1)
FREG_FROB(f0, f2, f4, f6, f8, f16, f18, f20, f22) FREG_FROB(f0, f2, f4, f6, f8, f16, f18, f20, f22)
EX_ST_FP(STORE_BLK(%f0, %o4 + %g3)) EX_ST_FP(STORE_BLK(%f0, %o4 + %g3), NG2_retl_o2_plus_g1)
FREG_MOVE_5(f22, f24, f26, f28, f30) FREG_MOVE_5(f22, f24, f26, f28, f30)
subcc %g1, 64, %g1 subcc %g1, 64, %g1
add %o4, 64, %o4 add %o4, 64, %o4
@ -338,10 +400,10 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
150: sub %o4, 32, %g2 150: sub %o4, 32, %g2
FREG_LOAD_4(%g2, f0, f2, f4, f6) FREG_LOAD_4(%g2, f0, f2, f4, f6)
1: EX_ST_FP(STORE_INIT(%g0, %o4 + %g3)) 1: EX_ST_FP(STORE_INIT(%g0, %o4 + %g3), NG2_retl_o2_plus_g1)
EX_LD_FP(LOAD_BLK(%o4, %f16)) EX_LD_FP(LOAD_BLK(%o4, %f16), NG2_retl_o2_plus_g1)
FREG_FROB(f0, f2, f4, f6, f16, f18, f20, f22, f24) FREG_FROB(f0, f2, f4, f6, f16, f18, f20, f22, f24)
EX_ST_FP(STORE_BLK(%f0, %o4 + %g3)) EX_ST_FP(STORE_BLK(%f0, %o4 + %g3), NG2_retl_o2_plus_g1)
FREG_MOVE_4(f24, f26, f28, f30) FREG_MOVE_4(f24, f26, f28, f30)
subcc %g1, 64, %g1 subcc %g1, 64, %g1
add %o4, 64, %o4 add %o4, 64, %o4
@ -352,10 +414,10 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
160: sub %o4, 24, %g2 160: sub %o4, 24, %g2
FREG_LOAD_3(%g2, f0, f2, f4) FREG_LOAD_3(%g2, f0, f2, f4)
1: EX_ST_FP(STORE_INIT(%g0, %o4 + %g3)) 1: EX_ST_FP(STORE_INIT(%g0, %o4 + %g3), NG2_retl_o2_plus_g1)
EX_LD_FP(LOAD_BLK(%o4, %f16)) EX_LD_FP(LOAD_BLK(%o4, %f16), NG2_retl_o2_plus_g1)
FREG_FROB(f0, f2, f4, f16, f18, f20, f22, f24, f26) FREG_FROB(f0, f2, f4, f16, f18, f20, f22, f24, f26)
EX_ST_FP(STORE_BLK(%f0, %o4 + %g3)) EX_ST_FP(STORE_BLK(%f0, %o4 + %g3), NG2_retl_o2_plus_g1)
FREG_MOVE_3(f26, f28, f30) FREG_MOVE_3(f26, f28, f30)
subcc %g1, 64, %g1 subcc %g1, 64, %g1
add %o4, 64, %o4 add %o4, 64, %o4
@ -366,10 +428,10 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
170: sub %o4, 16, %g2 170: sub %o4, 16, %g2
FREG_LOAD_2(%g2, f0, f2) FREG_LOAD_2(%g2, f0, f2)
1: EX_ST_FP(STORE_INIT(%g0, %o4 + %g3)) 1: EX_ST_FP(STORE_INIT(%g0, %o4 + %g3), NG2_retl_o2_plus_g1)
EX_LD_FP(LOAD_BLK(%o4, %f16)) EX_LD_FP(LOAD_BLK(%o4, %f16), NG2_retl_o2_plus_g1)
FREG_FROB(f0, f2, f16, f18, f20, f22, f24, f26, f28) FREG_FROB(f0, f2, f16, f18, f20, f22, f24, f26, f28)
EX_ST_FP(STORE_BLK(%f0, %o4 + %g3)) EX_ST_FP(STORE_BLK(%f0, %o4 + %g3), NG2_retl_o2_plus_g1)
FREG_MOVE_2(f28, f30) FREG_MOVE_2(f28, f30)
subcc %g1, 64, %g1 subcc %g1, 64, %g1
add %o4, 64, %o4 add %o4, 64, %o4
@ -380,10 +442,10 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
180: sub %o4, 8, %g2 180: sub %o4, 8, %g2
FREG_LOAD_1(%g2, f0) FREG_LOAD_1(%g2, f0)
1: EX_ST_FP(STORE_INIT(%g0, %o4 + %g3)) 1: EX_ST_FP(STORE_INIT(%g0, %o4 + %g3), NG2_retl_o2_plus_g1)
EX_LD_FP(LOAD_BLK(%o4, %f16)) EX_LD_FP(LOAD_BLK(%o4, %f16), NG2_retl_o2_plus_g1)
FREG_FROB(f0, f16, f18, f20, f22, f24, f26, f28, f30) FREG_FROB(f0, f16, f18, f20, f22, f24, f26, f28, f30)
EX_ST_FP(STORE_BLK(%f0, %o4 + %g3)) EX_ST_FP(STORE_BLK(%f0, %o4 + %g3), NG2_retl_o2_plus_g1)
FREG_MOVE_1(f30) FREG_MOVE_1(f30)
subcc %g1, 64, %g1 subcc %g1, 64, %g1
add %o4, 64, %o4 add %o4, 64, %o4
@ -393,10 +455,10 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
nop nop
190: 190:
1: EX_ST_FP(STORE_INIT(%g0, %o4 + %g3)) 1: EX_ST_FP(STORE_INIT(%g0, %o4 + %g3), NG2_retl_o2_plus_g1)
subcc %g1, 64, %g1 subcc %g1, 64, %g1
EX_LD_FP(LOAD_BLK(%o4, %f0)) EX_LD_FP(LOAD_BLK(%o4, %f0), NG2_retl_o2_plus_g1_plus_64)
EX_ST_FP(STORE_BLK(%f0, %o4 + %g3)) EX_ST_FP(STORE_BLK(%f0, %o4 + %g3), NG2_retl_o2_plus_g1_plus_64)
add %o4, 64, %o4 add %o4, 64, %o4
bne,pt %xcc, 1b bne,pt %xcc, 1b
LOAD(prefetch, %o4 + 64, #one_read) LOAD(prefetch, %o4 + 64, #one_read)
@ -423,28 +485,28 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
andn %o2, 0xf, %o4 andn %o2, 0xf, %o4
and %o2, 0xf, %o2 and %o2, 0xf, %o2
1: subcc %o4, 0x10, %o4 1: subcc %o4, 0x10, %o4
EX_LD(LOAD(ldx, %o1, %o5)) EX_LD(LOAD(ldx, %o1, %o5), NG2_retl_o2_plus_o4_plus_16)
add %o1, 0x08, %o1 add %o1, 0x08, %o1
EX_LD(LOAD(ldx, %o1, %g1)) EX_LD(LOAD(ldx, %o1, %g1), NG2_retl_o2_plus_o4_plus_16)
sub %o1, 0x08, %o1 sub %o1, 0x08, %o1
EX_ST(STORE(stx, %o5, %o1 + GLOBAL_SPARE)) EX_ST(STORE(stx, %o5, %o1 + GLOBAL_SPARE), NG2_retl_o2_plus_o4_plus_16)
add %o1, 0x8, %o1 add %o1, 0x8, %o1
EX_ST(STORE(stx, %g1, %o1 + GLOBAL_SPARE)) EX_ST(STORE(stx, %g1, %o1 + GLOBAL_SPARE), NG2_retl_o2_plus_o4_plus_8)
bgu,pt %XCC, 1b bgu,pt %XCC, 1b
add %o1, 0x8, %o1 add %o1, 0x8, %o1
73: andcc %o2, 0x8, %g0 73: andcc %o2, 0x8, %g0
be,pt %XCC, 1f be,pt %XCC, 1f
nop nop
sub %o2, 0x8, %o2 sub %o2, 0x8, %o2
EX_LD(LOAD(ldx, %o1, %o5)) EX_LD(LOAD(ldx, %o1, %o5), NG2_retl_o2_plus_8)
EX_ST(STORE(stx, %o5, %o1 + GLOBAL_SPARE)) EX_ST(STORE(stx, %o5, %o1 + GLOBAL_SPARE), NG2_retl_o2_plus_8)
add %o1, 0x8, %o1 add %o1, 0x8, %o1
1: andcc %o2, 0x4, %g0 1: andcc %o2, 0x4, %g0
be,pt %XCC, 1f be,pt %XCC, 1f
nop nop
sub %o2, 0x4, %o2 sub %o2, 0x4, %o2
EX_LD(LOAD(lduw, %o1, %o5)) EX_LD(LOAD(lduw, %o1, %o5), NG2_retl_o2_plus_4)
EX_ST(STORE(stw, %o5, %o1 + GLOBAL_SPARE)) EX_ST(STORE(stw, %o5, %o1 + GLOBAL_SPARE), NG2_retl_o2_plus_4)
add %o1, 0x4, %o1 add %o1, 0x4, %o1
1: cmp %o2, 0 1: cmp %o2, 0
be,pt %XCC, 85f be,pt %XCC, 85f
@ -460,8 +522,8 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
sub %o2, %g1, %o2 sub %o2, %g1, %o2
1: subcc %g1, 1, %g1 1: subcc %g1, 1, %g1
EX_LD(LOAD(ldub, %o1, %o5)) EX_LD(LOAD(ldub, %o1, %o5), NG2_retl_o2_plus_g1_plus_1)
EX_ST(STORE(stb, %o5, %o1 + GLOBAL_SPARE)) EX_ST(STORE(stb, %o5, %o1 + GLOBAL_SPARE), NG2_retl_o2_plus_g1_plus_1)
bgu,pt %icc, 1b bgu,pt %icc, 1b
add %o1, 1, %o1 add %o1, 1, %o1
@ -477,16 +539,16 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
8: mov 64, GLOBAL_SPARE 8: mov 64, GLOBAL_SPARE
andn %o1, 0x7, %o1 andn %o1, 0x7, %o1
EX_LD(LOAD(ldx, %o1, %g2)) EX_LD(LOAD(ldx, %o1, %g2), NG2_retl_o2)
sub GLOBAL_SPARE, %g1, GLOBAL_SPARE sub GLOBAL_SPARE, %g1, GLOBAL_SPARE
andn %o2, 0x7, %o4 andn %o2, 0x7, %o4
sllx %g2, %g1, %g2 sllx %g2, %g1, %g2
1: add %o1, 0x8, %o1 1: add %o1, 0x8, %o1
EX_LD(LOAD(ldx, %o1, %g3)) EX_LD(LOAD(ldx, %o1, %g3), NG2_retl_o2_and_7_plus_o4)
subcc %o4, 0x8, %o4 subcc %o4, 0x8, %o4
srlx %g3, GLOBAL_SPARE, %o5 srlx %g3, GLOBAL_SPARE, %o5
or %o5, %g2, %o5 or %o5, %g2, %o5
EX_ST(STORE(stx, %o5, %o0)) EX_ST(STORE(stx, %o5, %o0), NG2_retl_o2_and_7_plus_o4_plus_8)
add %o0, 0x8, %o0 add %o0, 0x8, %o0
bgu,pt %icc, 1b bgu,pt %icc, 1b
sllx %g3, %g1, %g2 sllx %g3, %g1, %g2
@ -506,8 +568,8 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
1: 1:
subcc %o2, 4, %o2 subcc %o2, 4, %o2
EX_LD(LOAD(lduw, %o1, %g1)) EX_LD(LOAD(lduw, %o1, %g1), NG2_retl_o2_plus_4)
EX_ST(STORE(stw, %g1, %o1 + GLOBAL_SPARE)) EX_ST(STORE(stw, %g1, %o1 + GLOBAL_SPARE), NG2_retl_o2_plus_4)
bgu,pt %XCC, 1b bgu,pt %XCC, 1b
add %o1, 4, %o1 add %o1, 4, %o1
@ -517,8 +579,8 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
.align 32 .align 32
90: 90:
subcc %o2, 1, %o2 subcc %o2, 1, %o2
EX_LD(LOAD(ldub, %o1, %g1)) EX_LD(LOAD(ldub, %o1, %g1), NG2_retl_o2_plus_1)
EX_ST(STORE(stb, %g1, %o1 + GLOBAL_SPARE)) EX_ST(STORE(stb, %g1, %o1 + GLOBAL_SPARE), NG2_retl_o2_plus_1)
bgu,pt %XCC, 90b bgu,pt %XCC, 90b
add %o1, 1, %o1 add %o1, 1, %o1
retl retl

View File

@ -3,19 +3,19 @@
* Copyright (C) 2012 David S. Miller (davem@davemloft.net) * Copyright (C) 2012 David S. Miller (davem@davemloft.net)
*/ */
#define EX_LD(x) \ #define EX_LD(x, y) \
98: x; \ 98: x; \
.section __ex_table,"a";\ .section __ex_table,"a";\
.align 4; \ .align 4; \
.word 98b, __retl_one_asi;\ .word 98b, y; \
.text; \ .text; \
.align 4; .align 4;
#define EX_LD_FP(x) \ #define EX_LD_FP(x,y) \
98: x; \ 98: x; \
.section __ex_table,"a";\ .section __ex_table,"a";\
.align 4; \ .align 4; \
.word 98b, __retl_one_asi_fp;\ .word 98b, y##_fp; \
.text; \ .text; \
.align 4; .align 4;

View File

@ -3,19 +3,19 @@
* Copyright (C) 2012 David S. Miller (davem@davemloft.net) * Copyright (C) 2012 David S. Miller (davem@davemloft.net)
*/ */
#define EX_ST(x) \ #define EX_ST(x,y) \
98: x; \ 98: x; \
.section __ex_table,"a";\ .section __ex_table,"a";\
.align 4; \ .align 4; \
.word 98b, __retl_one_asi;\ .word 98b, y; \
.text; \ .text; \
.align 4; .align 4;
#define EX_ST_FP(x) \ #define EX_ST_FP(x,y) \
98: x; \ 98: x; \
.section __ex_table,"a";\ .section __ex_table,"a";\
.align 4; \ .align 4; \
.word 98b, __retl_one_asi_fp;\ .word 98b, y##_fp; \
.text; \ .text; \
.align 4; .align 4;

View File

@ -4,6 +4,7 @@
*/ */
#ifdef __KERNEL__ #ifdef __KERNEL__
#include <linux/linkage.h>
#include <asm/visasm.h> #include <asm/visasm.h>
#include <asm/asi.h> #include <asm/asi.h>
#define GLOBAL_SPARE %g7 #define GLOBAL_SPARE %g7
@ -46,22 +47,19 @@
#endif #endif
#ifndef EX_LD #ifndef EX_LD
#define EX_LD(x) x #define EX_LD(x,y) x
#endif #endif
#ifndef EX_LD_FP #ifndef EX_LD_FP
#define EX_LD_FP(x) x #define EX_LD_FP(x,y) x
#endif #endif
#ifndef EX_ST #ifndef EX_ST
#define EX_ST(x) x #define EX_ST(x,y) x
#endif #endif
#ifndef EX_ST_FP #ifndef EX_ST_FP
#define EX_ST_FP(x) x #define EX_ST_FP(x,y) x
#endif #endif
#ifndef EX_RETVAL
#define EX_RETVAL(x) x
#endif
#ifndef LOAD #ifndef LOAD
#define LOAD(type,addr,dest) type [addr], dest #define LOAD(type,addr,dest) type [addr], dest
@ -94,6 +92,158 @@
.register %g3,#scratch .register %g3,#scratch
.text .text
#ifndef EX_RETVAL
#define EX_RETVAL(x) x
__restore_asi_fp:
VISExitHalf
__restore_asi:
retl
wr %g0, ASI_AIUS, %asi
ENTRY(NG4_retl_o2)
ba,pt %xcc, __restore_asi
mov %o2, %o0
ENDPROC(NG4_retl_o2)
ENTRY(NG4_retl_o2_plus_1)
ba,pt %xcc, __restore_asi
add %o2, 1, %o0
ENDPROC(NG4_retl_o2_plus_1)
ENTRY(NG4_retl_o2_plus_4)
ba,pt %xcc, __restore_asi
add %o2, 4, %o0
ENDPROC(NG4_retl_o2_plus_4)
ENTRY(NG4_retl_o2_plus_o5)
ba,pt %xcc, __restore_asi
add %o2, %o5, %o0
ENDPROC(NG4_retl_o2_plus_o5)
ENTRY(NG4_retl_o2_plus_o5_plus_4)
add %o5, 4, %o5
ba,pt %xcc, __restore_asi
add %o2, %o5, %o0
ENDPROC(NG4_retl_o2_plus_o5_plus_4)
ENTRY(NG4_retl_o2_plus_o5_plus_8)
add %o5, 8, %o5
ba,pt %xcc, __restore_asi
add %o2, %o5, %o0
ENDPROC(NG4_retl_o2_plus_o5_plus_8)
ENTRY(NG4_retl_o2_plus_o5_plus_16)
add %o5, 16, %o5
ba,pt %xcc, __restore_asi
add %o2, %o5, %o0
ENDPROC(NG4_retl_o2_plus_o5_plus_16)
ENTRY(NG4_retl_o2_plus_o5_plus_24)
add %o5, 24, %o5
ba,pt %xcc, __restore_asi
add %o2, %o5, %o0
ENDPROC(NG4_retl_o2_plus_o5_plus_24)
ENTRY(NG4_retl_o2_plus_o5_plus_32)
add %o5, 32, %o5
ba,pt %xcc, __restore_asi
add %o2, %o5, %o0
ENDPROC(NG4_retl_o2_plus_o5_plus_32)
ENTRY(NG4_retl_o2_plus_g1)
ba,pt %xcc, __restore_asi
add %o2, %g1, %o0
ENDPROC(NG4_retl_o2_plus_g1)
ENTRY(NG4_retl_o2_plus_g1_plus_1)
add %g1, 1, %g1
ba,pt %xcc, __restore_asi
add %o2, %g1, %o0
ENDPROC(NG4_retl_o2_plus_g1_plus_1)
ENTRY(NG4_retl_o2_plus_g1_plus_8)
add %g1, 8, %g1
ba,pt %xcc, __restore_asi
add %o2, %g1, %o0
ENDPROC(NG4_retl_o2_plus_g1_plus_8)
ENTRY(NG4_retl_o2_plus_o4)
ba,pt %xcc, __restore_asi
add %o2, %o4, %o0
ENDPROC(NG4_retl_o2_plus_o4)
ENTRY(NG4_retl_o2_plus_o4_plus_8)
add %o4, 8, %o4
ba,pt %xcc, __restore_asi
add %o2, %o4, %o0
ENDPROC(NG4_retl_o2_plus_o4_plus_8)
ENTRY(NG4_retl_o2_plus_o4_plus_16)
add %o4, 16, %o4
ba,pt %xcc, __restore_asi
add %o2, %o4, %o0
ENDPROC(NG4_retl_o2_plus_o4_plus_16)
ENTRY(NG4_retl_o2_plus_o4_plus_24)
add %o4, 24, %o4
ba,pt %xcc, __restore_asi
add %o2, %o4, %o0
ENDPROC(NG4_retl_o2_plus_o4_plus_24)
ENTRY(NG4_retl_o2_plus_o4_plus_32)
add %o4, 32, %o4
ba,pt %xcc, __restore_asi
add %o2, %o4, %o0
ENDPROC(NG4_retl_o2_plus_o4_plus_32)
ENTRY(NG4_retl_o2_plus_o4_plus_40)
add %o4, 40, %o4
ba,pt %xcc, __restore_asi
add %o2, %o4, %o0
ENDPROC(NG4_retl_o2_plus_o4_plus_40)
ENTRY(NG4_retl_o2_plus_o4_plus_48)
add %o4, 48, %o4
ba,pt %xcc, __restore_asi
add %o2, %o4, %o0
ENDPROC(NG4_retl_o2_plus_o4_plus_48)
ENTRY(NG4_retl_o2_plus_o4_plus_56)
add %o4, 56, %o4
ba,pt %xcc, __restore_asi
add %o2, %o4, %o0
ENDPROC(NG4_retl_o2_plus_o4_plus_56)
ENTRY(NG4_retl_o2_plus_o4_plus_64)
add %o4, 64, %o4
ba,pt %xcc, __restore_asi
add %o2, %o4, %o0
ENDPROC(NG4_retl_o2_plus_o4_plus_64)
ENTRY(NG4_retl_o2_plus_o4_fp)
ba,pt %xcc, __restore_asi_fp
add %o2, %o4, %o0
ENDPROC(NG4_retl_o2_plus_o4_fp)
ENTRY(NG4_retl_o2_plus_o4_plus_8_fp)
add %o4, 8, %o4
ba,pt %xcc, __restore_asi_fp
add %o2, %o4, %o0
ENDPROC(NG4_retl_o2_plus_o4_plus_8_fp)
ENTRY(NG4_retl_o2_plus_o4_plus_16_fp)
add %o4, 16, %o4
ba,pt %xcc, __restore_asi_fp
add %o2, %o4, %o0
ENDPROC(NG4_retl_o2_plus_o4_plus_16_fp)
ENTRY(NG4_retl_o2_plus_o4_plus_24_fp)
add %o4, 24, %o4
ba,pt %xcc, __restore_asi_fp
add %o2, %o4, %o0
ENDPROC(NG4_retl_o2_plus_o4_plus_24_fp)
ENTRY(NG4_retl_o2_plus_o4_plus_32_fp)
add %o4, 32, %o4
ba,pt %xcc, __restore_asi_fp
add %o2, %o4, %o0
ENDPROC(NG4_retl_o2_plus_o4_plus_32_fp)
ENTRY(NG4_retl_o2_plus_o4_plus_40_fp)
add %o4, 40, %o4
ba,pt %xcc, __restore_asi_fp
add %o2, %o4, %o0
ENDPROC(NG4_retl_o2_plus_o4_plus_40_fp)
ENTRY(NG4_retl_o2_plus_o4_plus_48_fp)
add %o4, 48, %o4
ba,pt %xcc, __restore_asi_fp
add %o2, %o4, %o0
ENDPROC(NG4_retl_o2_plus_o4_plus_48_fp)
ENTRY(NG4_retl_o2_plus_o4_plus_56_fp)
add %o4, 56, %o4
ba,pt %xcc, __restore_asi_fp
add %o2, %o4, %o0
ENDPROC(NG4_retl_o2_plus_o4_plus_56_fp)
ENTRY(NG4_retl_o2_plus_o4_plus_64_fp)
add %o4, 64, %o4
ba,pt %xcc, __restore_asi_fp
add %o2, %o4, %o0
ENDPROC(NG4_retl_o2_plus_o4_plus_64_fp)
#endif
.align 64 .align 64
.globl FUNC_NAME .globl FUNC_NAME
@ -124,12 +274,13 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
brz,pt %g1, 51f brz,pt %g1, 51f
sub %o2, %g1, %o2 sub %o2, %g1, %o2
1: EX_LD(LOAD(ldub, %o1 + 0x00, %g2))
1: EX_LD(LOAD(ldub, %o1 + 0x00, %g2), NG4_retl_o2_plus_g1)
add %o1, 1, %o1 add %o1, 1, %o1
subcc %g1, 1, %g1 subcc %g1, 1, %g1
add %o0, 1, %o0 add %o0, 1, %o0
bne,pt %icc, 1b bne,pt %icc, 1b
EX_ST(STORE(stb, %g2, %o0 - 0x01)) EX_ST(STORE(stb, %g2, %o0 - 0x01), NG4_retl_o2_plus_g1_plus_1)
51: LOAD(prefetch, %o1 + 0x040, #n_reads_strong) 51: LOAD(prefetch, %o1 + 0x040, #n_reads_strong)
LOAD(prefetch, %o1 + 0x080, #n_reads_strong) LOAD(prefetch, %o1 + 0x080, #n_reads_strong)
@ -154,43 +305,43 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
brz,pt %g1, .Llarge_aligned brz,pt %g1, .Llarge_aligned
sub %o2, %g1, %o2 sub %o2, %g1, %o2
1: EX_LD(LOAD(ldx, %o1 + 0x00, %g2)) 1: EX_LD(LOAD(ldx, %o1 + 0x00, %g2), NG4_retl_o2_plus_g1)
add %o1, 8, %o1 add %o1, 8, %o1
subcc %g1, 8, %g1 subcc %g1, 8, %g1
add %o0, 8, %o0 add %o0, 8, %o0
bne,pt %icc, 1b bne,pt %icc, 1b
EX_ST(STORE(stx, %g2, %o0 - 0x08)) EX_ST(STORE(stx, %g2, %o0 - 0x08), NG4_retl_o2_plus_g1_plus_8)
.Llarge_aligned: .Llarge_aligned:
/* len >= 0x80 && src 8-byte aligned && dest 8-byte aligned */ /* len >= 0x80 && src 8-byte aligned && dest 8-byte aligned */
andn %o2, 0x3f, %o4 andn %o2, 0x3f, %o4
sub %o2, %o4, %o2 sub %o2, %o4, %o2
1: EX_LD(LOAD(ldx, %o1 + 0x00, %g1)) 1: EX_LD(LOAD(ldx, %o1 + 0x00, %g1), NG4_retl_o2_plus_o4)
add %o1, 0x40, %o1 add %o1, 0x40, %o1
EX_LD(LOAD(ldx, %o1 - 0x38, %g2)) EX_LD(LOAD(ldx, %o1 - 0x38, %g2), NG4_retl_o2_plus_o4)
subcc %o4, 0x40, %o4 subcc %o4, 0x40, %o4
EX_LD(LOAD(ldx, %o1 - 0x30, %g3)) EX_LD(LOAD(ldx, %o1 - 0x30, %g3), NG4_retl_o2_plus_o4_plus_64)
EX_LD(LOAD(ldx, %o1 - 0x28, GLOBAL_SPARE)) EX_LD(LOAD(ldx, %o1 - 0x28, GLOBAL_SPARE), NG4_retl_o2_plus_o4_plus_64)
EX_LD(LOAD(ldx, %o1 - 0x20, %o5)) EX_LD(LOAD(ldx, %o1 - 0x20, %o5), NG4_retl_o2_plus_o4_plus_64)
EX_ST(STORE_INIT(%g1, %o0)) EX_ST(STORE_INIT(%g1, %o0), NG4_retl_o2_plus_o4_plus_64)
add %o0, 0x08, %o0 add %o0, 0x08, %o0
EX_ST(STORE_INIT(%g2, %o0)) EX_ST(STORE_INIT(%g2, %o0), NG4_retl_o2_plus_o4_plus_56)
add %o0, 0x08, %o0 add %o0, 0x08, %o0
EX_LD(LOAD(ldx, %o1 - 0x18, %g2)) EX_LD(LOAD(ldx, %o1 - 0x18, %g2), NG4_retl_o2_plus_o4_plus_48)
EX_ST(STORE_INIT(%g3, %o0)) EX_ST(STORE_INIT(%g3, %o0), NG4_retl_o2_plus_o4_plus_48)
add %o0, 0x08, %o0 add %o0, 0x08, %o0
EX_LD(LOAD(ldx, %o1 - 0x10, %g3)) EX_LD(LOAD(ldx, %o1 - 0x10, %g3), NG4_retl_o2_plus_o4_plus_40)
EX_ST(STORE_INIT(GLOBAL_SPARE, %o0)) EX_ST(STORE_INIT(GLOBAL_SPARE, %o0), NG4_retl_o2_plus_o4_plus_40)
add %o0, 0x08, %o0 add %o0, 0x08, %o0
EX_LD(LOAD(ldx, %o1 - 0x08, GLOBAL_SPARE)) EX_LD(LOAD(ldx, %o1 - 0x08, GLOBAL_SPARE), NG4_retl_o2_plus_o4_plus_32)
EX_ST(STORE_INIT(%o5, %o0)) EX_ST(STORE_INIT(%o5, %o0), NG4_retl_o2_plus_o4_plus_32)
add %o0, 0x08, %o0 add %o0, 0x08, %o0
EX_ST(STORE_INIT(%g2, %o0)) EX_ST(STORE_INIT(%g2, %o0), NG4_retl_o2_plus_o4_plus_24)
add %o0, 0x08, %o0 add %o0, 0x08, %o0
EX_ST(STORE_INIT(%g3, %o0)) EX_ST(STORE_INIT(%g3, %o0), NG4_retl_o2_plus_o4_plus_16)
add %o0, 0x08, %o0 add %o0, 0x08, %o0
EX_ST(STORE_INIT(GLOBAL_SPARE, %o0)) EX_ST(STORE_INIT(GLOBAL_SPARE, %o0), NG4_retl_o2_plus_o4_plus_8)
add %o0, 0x08, %o0 add %o0, 0x08, %o0
bne,pt %icc, 1b bne,pt %icc, 1b
LOAD(prefetch, %o1 + 0x200, #n_reads_strong) LOAD(prefetch, %o1 + 0x200, #n_reads_strong)
@ -216,17 +367,17 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
sub %o2, %o4, %o2 sub %o2, %o4, %o2
alignaddr %o1, %g0, %g1 alignaddr %o1, %g0, %g1
add %o1, %o4, %o1 add %o1, %o4, %o1
EX_LD_FP(LOAD(ldd, %g1 + 0x00, %f0)) EX_LD_FP(LOAD(ldd, %g1 + 0x00, %f0), NG4_retl_o2_plus_o4)
1: EX_LD_FP(LOAD(ldd, %g1 + 0x08, %f2)) 1: EX_LD_FP(LOAD(ldd, %g1 + 0x08, %f2), NG4_retl_o2_plus_o4)
subcc %o4, 0x40, %o4 subcc %o4, 0x40, %o4
EX_LD_FP(LOAD(ldd, %g1 + 0x10, %f4)) EX_LD_FP(LOAD(ldd, %g1 + 0x10, %f4), NG4_retl_o2_plus_o4_plus_64)
EX_LD_FP(LOAD(ldd, %g1 + 0x18, %f6)) EX_LD_FP(LOAD(ldd, %g1 + 0x18, %f6), NG4_retl_o2_plus_o4_plus_64)
EX_LD_FP(LOAD(ldd, %g1 + 0x20, %f8)) EX_LD_FP(LOAD(ldd, %g1 + 0x20, %f8), NG4_retl_o2_plus_o4_plus_64)
EX_LD_FP(LOAD(ldd, %g1 + 0x28, %f10)) EX_LD_FP(LOAD(ldd, %g1 + 0x28, %f10), NG4_retl_o2_plus_o4_plus_64)
EX_LD_FP(LOAD(ldd, %g1 + 0x30, %f12)) EX_LD_FP(LOAD(ldd, %g1 + 0x30, %f12), NG4_retl_o2_plus_o4_plus_64)
EX_LD_FP(LOAD(ldd, %g1 + 0x38, %f14)) EX_LD_FP(LOAD(ldd, %g1 + 0x38, %f14), NG4_retl_o2_plus_o4_plus_64)
faligndata %f0, %f2, %f16 faligndata %f0, %f2, %f16
EX_LD_FP(LOAD(ldd, %g1 + 0x40, %f0)) EX_LD_FP(LOAD(ldd, %g1 + 0x40, %f0), NG4_retl_o2_plus_o4_plus_64)
faligndata %f2, %f4, %f18 faligndata %f2, %f4, %f18
add %g1, 0x40, %g1 add %g1, 0x40, %g1
faligndata %f4, %f6, %f20 faligndata %f4, %f6, %f20
@ -235,14 +386,14 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
faligndata %f10, %f12, %f26 faligndata %f10, %f12, %f26
faligndata %f12, %f14, %f28 faligndata %f12, %f14, %f28
faligndata %f14, %f0, %f30 faligndata %f14, %f0, %f30
EX_ST_FP(STORE(std, %f16, %o0 + 0x00)) EX_ST_FP(STORE(std, %f16, %o0 + 0x00), NG4_retl_o2_plus_o4_plus_64)
EX_ST_FP(STORE(std, %f18, %o0 + 0x08)) EX_ST_FP(STORE(std, %f18, %o0 + 0x08), NG4_retl_o2_plus_o4_plus_56)
EX_ST_FP(STORE(std, %f20, %o0 + 0x10)) EX_ST_FP(STORE(std, %f20, %o0 + 0x10), NG4_retl_o2_plus_o4_plus_48)
EX_ST_FP(STORE(std, %f22, %o0 + 0x18)) EX_ST_FP(STORE(std, %f22, %o0 + 0x18), NG4_retl_o2_plus_o4_plus_40)
EX_ST_FP(STORE(std, %f24, %o0 + 0x20)) EX_ST_FP(STORE(std, %f24, %o0 + 0x20), NG4_retl_o2_plus_o4_plus_32)
EX_ST_FP(STORE(std, %f26, %o0 + 0x28)) EX_ST_FP(STORE(std, %f26, %o0 + 0x28), NG4_retl_o2_plus_o4_plus_24)
EX_ST_FP(STORE(std, %f28, %o0 + 0x30)) EX_ST_FP(STORE(std, %f28, %o0 + 0x30), NG4_retl_o2_plus_o4_plus_16)
EX_ST_FP(STORE(std, %f30, %o0 + 0x38)) EX_ST_FP(STORE(std, %f30, %o0 + 0x38), NG4_retl_o2_plus_o4_plus_8)
add %o0, 0x40, %o0 add %o0, 0x40, %o0
bne,pt %icc, 1b bne,pt %icc, 1b
LOAD(prefetch, %g1 + 0x200, #n_reads_strong) LOAD(prefetch, %g1 + 0x200, #n_reads_strong)
@ -270,37 +421,38 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
andncc %o2, 0x20 - 1, %o5 andncc %o2, 0x20 - 1, %o5
be,pn %icc, 2f be,pn %icc, 2f
sub %o2, %o5, %o2 sub %o2, %o5, %o2
1: EX_LD(LOAD(ldx, %o1 + 0x00, %g1)) 1: EX_LD(LOAD(ldx, %o1 + 0x00, %g1), NG4_retl_o2_plus_o5)
EX_LD(LOAD(ldx, %o1 + 0x08, %g2)) EX_LD(LOAD(ldx, %o1 + 0x08, %g2), NG4_retl_o2_plus_o5)
EX_LD(LOAD(ldx, %o1 + 0x10, GLOBAL_SPARE)) EX_LD(LOAD(ldx, %o1 + 0x10, GLOBAL_SPARE), NG4_retl_o2_plus_o5)
EX_LD(LOAD(ldx, %o1 + 0x18, %o4)) EX_LD(LOAD(ldx, %o1 + 0x18, %o4), NG4_retl_o2_plus_o5)
add %o1, 0x20, %o1 add %o1, 0x20, %o1
subcc %o5, 0x20, %o5 subcc %o5, 0x20, %o5
EX_ST(STORE(stx, %g1, %o0 + 0x00)) EX_ST(STORE(stx, %g1, %o0 + 0x00), NG4_retl_o2_plus_o5_plus_32)
EX_ST(STORE(stx, %g2, %o0 + 0x08)) EX_ST(STORE(stx, %g2, %o0 + 0x08), NG4_retl_o2_plus_o5_plus_24)
EX_ST(STORE(stx, GLOBAL_SPARE, %o0 + 0x10)) EX_ST(STORE(stx, GLOBAL_SPARE, %o0 + 0x10), NG4_retl_o2_plus_o5_plus_24)
EX_ST(STORE(stx, %o4, %o0 + 0x18)) EX_ST(STORE(stx, %o4, %o0 + 0x18), NG4_retl_o2_plus_o5_plus_8)
bne,pt %icc, 1b bne,pt %icc, 1b
add %o0, 0x20, %o0 add %o0, 0x20, %o0
2: andcc %o2, 0x18, %o5 2: andcc %o2, 0x18, %o5
be,pt %icc, 3f be,pt %icc, 3f
sub %o2, %o5, %o2 sub %o2, %o5, %o2
1: EX_LD(LOAD(ldx, %o1 + 0x00, %g1))
1: EX_LD(LOAD(ldx, %o1 + 0x00, %g1), NG4_retl_o2_plus_o5)
add %o1, 0x08, %o1 add %o1, 0x08, %o1
add %o0, 0x08, %o0 add %o0, 0x08, %o0
subcc %o5, 0x08, %o5 subcc %o5, 0x08, %o5
bne,pt %icc, 1b bne,pt %icc, 1b
EX_ST(STORE(stx, %g1, %o0 - 0x08)) EX_ST(STORE(stx, %g1, %o0 - 0x08), NG4_retl_o2_plus_o5_plus_8)
3: brz,pt %o2, .Lexit 3: brz,pt %o2, .Lexit
cmp %o2, 0x04 cmp %o2, 0x04
bl,pn %icc, .Ltiny bl,pn %icc, .Ltiny
nop nop
EX_LD(LOAD(lduw, %o1 + 0x00, %g1)) EX_LD(LOAD(lduw, %o1 + 0x00, %g1), NG4_retl_o2)
add %o1, 0x04, %o1 add %o1, 0x04, %o1
add %o0, 0x04, %o0 add %o0, 0x04, %o0
subcc %o2, 0x04, %o2 subcc %o2, 0x04, %o2
bne,pn %icc, .Ltiny bne,pn %icc, .Ltiny
EX_ST(STORE(stw, %g1, %o0 - 0x04)) EX_ST(STORE(stw, %g1, %o0 - 0x04), NG4_retl_o2_plus_4)
ba,a,pt %icc, .Lexit ba,a,pt %icc, .Lexit
.Lmedium_unaligned: .Lmedium_unaligned:
/* First get dest 8 byte aligned. */ /* First get dest 8 byte aligned. */
@ -309,12 +461,12 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
brz,pt %g1, 2f brz,pt %g1, 2f
sub %o2, %g1, %o2 sub %o2, %g1, %o2
1: EX_LD(LOAD(ldub, %o1 + 0x00, %g2)) 1: EX_LD(LOAD(ldub, %o1 + 0x00, %g2), NG4_retl_o2_plus_g1)
add %o1, 1, %o1 add %o1, 1, %o1
subcc %g1, 1, %g1 subcc %g1, 1, %g1
add %o0, 1, %o0 add %o0, 1, %o0
bne,pt %icc, 1b bne,pt %icc, 1b
EX_ST(STORE(stb, %g2, %o0 - 0x01)) EX_ST(STORE(stb, %g2, %o0 - 0x01), NG4_retl_o2_plus_g1_plus_1)
2: 2:
and %o1, 0x7, %g1 and %o1, 0x7, %g1
brz,pn %g1, .Lmedium_noprefetch brz,pn %g1, .Lmedium_noprefetch
@ -322,16 +474,16 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
mov 64, %g2 mov 64, %g2
sub %g2, %g1, %g2 sub %g2, %g1, %g2
andn %o1, 0x7, %o1 andn %o1, 0x7, %o1
EX_LD(LOAD(ldx, %o1 + 0x00, %o4)) EX_LD(LOAD(ldx, %o1 + 0x00, %o4), NG4_retl_o2)
sllx %o4, %g1, %o4 sllx %o4, %g1, %o4
andn %o2, 0x08 - 1, %o5 andn %o2, 0x08 - 1, %o5
sub %o2, %o5, %o2 sub %o2, %o5, %o2
1: EX_LD(LOAD(ldx, %o1 + 0x08, %g3)) 1: EX_LD(LOAD(ldx, %o1 + 0x08, %g3), NG4_retl_o2_plus_o5)
add %o1, 0x08, %o1 add %o1, 0x08, %o1
subcc %o5, 0x08, %o5 subcc %o5, 0x08, %o5
srlx %g3, %g2, GLOBAL_SPARE srlx %g3, %g2, GLOBAL_SPARE
or GLOBAL_SPARE, %o4, GLOBAL_SPARE or GLOBAL_SPARE, %o4, GLOBAL_SPARE
EX_ST(STORE(stx, GLOBAL_SPARE, %o0 + 0x00)) EX_ST(STORE(stx, GLOBAL_SPARE, %o0 + 0x00), NG4_retl_o2_plus_o5_plus_8)
add %o0, 0x08, %o0 add %o0, 0x08, %o0
bne,pt %icc, 1b bne,pt %icc, 1b
sllx %g3, %g1, %o4 sllx %g3, %g1, %o4
@ -342,17 +494,17 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
ba,pt %icc, .Lsmall_unaligned ba,pt %icc, .Lsmall_unaligned
.Ltiny: .Ltiny:
EX_LD(LOAD(ldub, %o1 + 0x00, %g1)) EX_LD(LOAD(ldub, %o1 + 0x00, %g1), NG4_retl_o2)
subcc %o2, 1, %o2 subcc %o2, 1, %o2
be,pn %icc, .Lexit be,pn %icc, .Lexit
EX_ST(STORE(stb, %g1, %o0 + 0x00)) EX_ST(STORE(stb, %g1, %o0 + 0x00), NG4_retl_o2_plus_1)
EX_LD(LOAD(ldub, %o1 + 0x01, %g1)) EX_LD(LOAD(ldub, %o1 + 0x01, %g1), NG4_retl_o2)
subcc %o2, 1, %o2 subcc %o2, 1, %o2
be,pn %icc, .Lexit be,pn %icc, .Lexit
EX_ST(STORE(stb, %g1, %o0 + 0x01)) EX_ST(STORE(stb, %g1, %o0 + 0x01), NG4_retl_o2_plus_1)
EX_LD(LOAD(ldub, %o1 + 0x02, %g1)) EX_LD(LOAD(ldub, %o1 + 0x02, %g1), NG4_retl_o2)
ba,pt %icc, .Lexit ba,pt %icc, .Lexit
EX_ST(STORE(stb, %g1, %o0 + 0x02)) EX_ST(STORE(stb, %g1, %o0 + 0x02), NG4_retl_o2)
.Lsmall: .Lsmall:
andcc %g2, 0x3, %g0 andcc %g2, 0x3, %g0
@ -360,22 +512,22 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
andn %o2, 0x4 - 1, %o5 andn %o2, 0x4 - 1, %o5
sub %o2, %o5, %o2 sub %o2, %o5, %o2
1: 1:
EX_LD(LOAD(lduw, %o1 + 0x00, %g1)) EX_LD(LOAD(lduw, %o1 + 0x00, %g1), NG4_retl_o2_plus_o5)
add %o1, 0x04, %o1 add %o1, 0x04, %o1
subcc %o5, 0x04, %o5 subcc %o5, 0x04, %o5
add %o0, 0x04, %o0 add %o0, 0x04, %o0
bne,pt %icc, 1b bne,pt %icc, 1b
EX_ST(STORE(stw, %g1, %o0 - 0x04)) EX_ST(STORE(stw, %g1, %o0 - 0x04), NG4_retl_o2_plus_o5_plus_4)
brz,pt %o2, .Lexit brz,pt %o2, .Lexit
nop nop
ba,a,pt %icc, .Ltiny ba,a,pt %icc, .Ltiny
.Lsmall_unaligned: .Lsmall_unaligned:
1: EX_LD(LOAD(ldub, %o1 + 0x00, %g1)) 1: EX_LD(LOAD(ldub, %o1 + 0x00, %g1), NG4_retl_o2)
add %o1, 1, %o1 add %o1, 1, %o1
add %o0, 1, %o0 add %o0, 1, %o0
subcc %o2, 1, %o2 subcc %o2, 1, %o2
bne,pt %icc, 1b bne,pt %icc, 1b
EX_ST(STORE(stb, %g1, %o0 - 0x01)) EX_ST(STORE(stb, %g1, %o0 - 0x01), NG4_retl_o2_plus_1)
ba,a,pt %icc, .Lexit ba,a,pt %icc, .Lexit
.size FUNC_NAME, .-FUNC_NAME .size FUNC_NAME, .-FUNC_NAME

View File

@ -3,11 +3,11 @@
* Copyright (C) 2006, 2007 David S. Miller (davem@davemloft.net) * Copyright (C) 2006, 2007 David S. Miller (davem@davemloft.net)
*/ */
#define EX_LD(x) \ #define EX_LD(x,y) \
98: x; \ 98: x; \
.section __ex_table,"a";\ .section __ex_table,"a";\
.align 4; \ .align 4; \
.word 98b, __ret_one_asi;\ .word 98b, y; \
.text; \ .text; \
.align 4; .align 4;

View File

@ -3,11 +3,11 @@
* Copyright (C) 2006, 2007 David S. Miller (davem@davemloft.net) * Copyright (C) 2006, 2007 David S. Miller (davem@davemloft.net)
*/ */
#define EX_ST(x) \ #define EX_ST(x,y) \
98: x; \ 98: x; \
.section __ex_table,"a";\ .section __ex_table,"a";\
.align 4; \ .align 4; \
.word 98b, __ret_one_asi;\ .word 98b, y; \
.text; \ .text; \
.align 4; .align 4;

View File

@ -4,6 +4,7 @@
*/ */
#ifdef __KERNEL__ #ifdef __KERNEL__
#include <linux/linkage.h>
#include <asm/asi.h> #include <asm/asi.h>
#include <asm/thread_info.h> #include <asm/thread_info.h>
#define GLOBAL_SPARE %g7 #define GLOBAL_SPARE %g7
@ -27,15 +28,11 @@
#endif #endif
#ifndef EX_LD #ifndef EX_LD
#define EX_LD(x) x #define EX_LD(x,y) x
#endif #endif
#ifndef EX_ST #ifndef EX_ST
#define EX_ST(x) x #define EX_ST(x,y) x
#endif
#ifndef EX_RETVAL
#define EX_RETVAL(x) x
#endif #endif
#ifndef LOAD #ifndef LOAD
@ -79,6 +76,92 @@
.register %g3,#scratch .register %g3,#scratch
.text .text
#ifndef EX_RETVAL
#define EX_RETVAL(x) x
__restore_asi:
ret
wr %g0, ASI_AIUS, %asi
restore
ENTRY(NG_ret_i2_plus_i4_plus_1)
ba,pt %xcc, __restore_asi
add %i2, %i5, %i0
ENDPROC(NG_ret_i2_plus_i4_plus_1)
ENTRY(NG_ret_i2_plus_g1)
ba,pt %xcc, __restore_asi
add %i2, %g1, %i0
ENDPROC(NG_ret_i2_plus_g1)
ENTRY(NG_ret_i2_plus_g1_minus_8)
sub %g1, 8, %g1
ba,pt %xcc, __restore_asi
add %i2, %g1, %i0
ENDPROC(NG_ret_i2_plus_g1_minus_8)
ENTRY(NG_ret_i2_plus_g1_minus_16)
sub %g1, 16, %g1
ba,pt %xcc, __restore_asi
add %i2, %g1, %i0
ENDPROC(NG_ret_i2_plus_g1_minus_16)
ENTRY(NG_ret_i2_plus_g1_minus_24)
sub %g1, 24, %g1
ba,pt %xcc, __restore_asi
add %i2, %g1, %i0
ENDPROC(NG_ret_i2_plus_g1_minus_24)
ENTRY(NG_ret_i2_plus_g1_minus_32)
sub %g1, 32, %g1
ba,pt %xcc, __restore_asi
add %i2, %g1, %i0
ENDPROC(NG_ret_i2_plus_g1_minus_32)
ENTRY(NG_ret_i2_plus_g1_minus_40)
sub %g1, 40, %g1
ba,pt %xcc, __restore_asi
add %i2, %g1, %i0
ENDPROC(NG_ret_i2_plus_g1_minus_40)
ENTRY(NG_ret_i2_plus_g1_minus_48)
sub %g1, 48, %g1
ba,pt %xcc, __restore_asi
add %i2, %g1, %i0
ENDPROC(NG_ret_i2_plus_g1_minus_48)
ENTRY(NG_ret_i2_plus_g1_minus_56)
sub %g1, 56, %g1
ba,pt %xcc, __restore_asi
add %i2, %g1, %i0
ENDPROC(NG_ret_i2_plus_g1_minus_56)
ENTRY(NG_ret_i2_plus_i4)
ba,pt %xcc, __restore_asi
add %i2, %i4, %i0
ENDPROC(NG_ret_i2_plus_i4)
ENTRY(NG_ret_i2_plus_i4_minus_8)
sub %i4, 8, %i4
ba,pt %xcc, __restore_asi
add %i2, %i4, %i0
ENDPROC(NG_ret_i2_plus_i4_minus_8)
ENTRY(NG_ret_i2_plus_8)
ba,pt %xcc, __restore_asi
add %i2, 8, %i0
ENDPROC(NG_ret_i2_plus_8)
ENTRY(NG_ret_i2_plus_4)
ba,pt %xcc, __restore_asi
add %i2, 4, %i0
ENDPROC(NG_ret_i2_plus_4)
ENTRY(NG_ret_i2_plus_1)
ba,pt %xcc, __restore_asi
add %i2, 1, %i0
ENDPROC(NG_ret_i2_plus_1)
ENTRY(NG_ret_i2_plus_g1_plus_1)
add %g1, 1, %g1
ba,pt %xcc, __restore_asi
add %i2, %g1, %i0
ENDPROC(NG_ret_i2_plus_g1_plus_1)
ENTRY(NG_ret_i2)
ba,pt %xcc, __restore_asi
mov %i2, %i0
ENDPROC(NG_ret_i2)
ENTRY(NG_ret_i2_and_7_plus_i4)
and %i2, 7, %i2
ba,pt %xcc, __restore_asi
add %i2, %i4, %i0
ENDPROC(NG_ret_i2_and_7_plus_i4)
#endif
.align 64 .align 64
.globl FUNC_NAME .globl FUNC_NAME
@ -126,8 +209,8 @@ FUNC_NAME: /* %i0=dst, %i1=src, %i2=len */
sub %g0, %i4, %i4 ! bytes to align dst sub %g0, %i4, %i4 ! bytes to align dst
sub %i2, %i4, %i2 sub %i2, %i4, %i2
1: subcc %i4, 1, %i4 1: subcc %i4, 1, %i4
EX_LD(LOAD(ldub, %i1, %g1)) EX_LD(LOAD(ldub, %i1, %g1), NG_ret_i2_plus_i4_plus_1)
EX_ST(STORE(stb, %g1, %o0)) EX_ST(STORE(stb, %g1, %o0), NG_ret_i2_plus_i4_plus_1)
add %i1, 1, %i1 add %i1, 1, %i1
bne,pt %XCC, 1b bne,pt %XCC, 1b
add %o0, 1, %o0 add %o0, 1, %o0
@ -160,7 +243,7 @@ FUNC_NAME: /* %i0=dst, %i1=src, %i2=len */
and %i4, 0x7, GLOBAL_SPARE and %i4, 0x7, GLOBAL_SPARE
sll GLOBAL_SPARE, 3, GLOBAL_SPARE sll GLOBAL_SPARE, 3, GLOBAL_SPARE
mov 64, %i5 mov 64, %i5
EX_LD(LOAD_TWIN(%i1, %g2, %g3)) EX_LD(LOAD_TWIN(%i1, %g2, %g3), NG_ret_i2_plus_g1)
sub %i5, GLOBAL_SPARE, %i5 sub %i5, GLOBAL_SPARE, %i5
mov 16, %o4 mov 16, %o4
mov 32, %o5 mov 32, %o5
@ -178,31 +261,31 @@ FUNC_NAME: /* %i0=dst, %i1=src, %i2=len */
srlx WORD3, PRE_SHIFT, TMP; \ srlx WORD3, PRE_SHIFT, TMP; \
or WORD2, TMP, WORD2; or WORD2, TMP, WORD2;
8: EX_LD(LOAD_TWIN(%i1 + %o4, %o2, %o3)) 8: EX_LD(LOAD_TWIN(%i1 + %o4, %o2, %o3), NG_ret_i2_plus_g1)
MIX_THREE_WORDS(%g2, %g3, %o2, %i5, GLOBAL_SPARE, %o1) MIX_THREE_WORDS(%g2, %g3, %o2, %i5, GLOBAL_SPARE, %o1)
LOAD(prefetch, %i1 + %i3, #one_read) LOAD(prefetch, %i1 + %i3, #one_read)
EX_ST(STORE_INIT(%g2, %o0 + 0x00)) EX_ST(STORE_INIT(%g2, %o0 + 0x00), NG_ret_i2_plus_g1)
EX_ST(STORE_INIT(%g3, %o0 + 0x08)) EX_ST(STORE_INIT(%g3, %o0 + 0x08), NG_ret_i2_plus_g1_minus_8)
EX_LD(LOAD_TWIN(%i1 + %o5, %g2, %g3)) EX_LD(LOAD_TWIN(%i1 + %o5, %g2, %g3), NG_ret_i2_plus_g1_minus_16)
MIX_THREE_WORDS(%o2, %o3, %g2, %i5, GLOBAL_SPARE, %o1) MIX_THREE_WORDS(%o2, %o3, %g2, %i5, GLOBAL_SPARE, %o1)
EX_ST(STORE_INIT(%o2, %o0 + 0x10)) EX_ST(STORE_INIT(%o2, %o0 + 0x10), NG_ret_i2_plus_g1_minus_16)
EX_ST(STORE_INIT(%o3, %o0 + 0x18)) EX_ST(STORE_INIT(%o3, %o0 + 0x18), NG_ret_i2_plus_g1_minus_24)
EX_LD(LOAD_TWIN(%i1 + %o7, %o2, %o3)) EX_LD(LOAD_TWIN(%i1 + %o7, %o2, %o3), NG_ret_i2_plus_g1_minus_32)
MIX_THREE_WORDS(%g2, %g3, %o2, %i5, GLOBAL_SPARE, %o1) MIX_THREE_WORDS(%g2, %g3, %o2, %i5, GLOBAL_SPARE, %o1)
EX_ST(STORE_INIT(%g2, %o0 + 0x20)) EX_ST(STORE_INIT(%g2, %o0 + 0x20), NG_ret_i2_plus_g1_minus_32)
EX_ST(STORE_INIT(%g3, %o0 + 0x28)) EX_ST(STORE_INIT(%g3, %o0 + 0x28), NG_ret_i2_plus_g1_minus_40)
EX_LD(LOAD_TWIN(%i1 + %i3, %g2, %g3)) EX_LD(LOAD_TWIN(%i1 + %i3, %g2, %g3), NG_ret_i2_plus_g1_minus_48)
add %i1, 64, %i1 add %i1, 64, %i1
MIX_THREE_WORDS(%o2, %o3, %g2, %i5, GLOBAL_SPARE, %o1) MIX_THREE_WORDS(%o2, %o3, %g2, %i5, GLOBAL_SPARE, %o1)
EX_ST(STORE_INIT(%o2, %o0 + 0x30)) EX_ST(STORE_INIT(%o2, %o0 + 0x30), NG_ret_i2_plus_g1_minus_48)
EX_ST(STORE_INIT(%o3, %o0 + 0x38)) EX_ST(STORE_INIT(%o3, %o0 + 0x38), NG_ret_i2_plus_g1_minus_56)
subcc %g1, 64, %g1 subcc %g1, 64, %g1
bne,pt %XCC, 8b bne,pt %XCC, 8b
@ -211,31 +294,31 @@ FUNC_NAME: /* %i0=dst, %i1=src, %i2=len */
ba,pt %XCC, 60f ba,pt %XCC, 60f
add %i1, %i4, %i1 add %i1, %i4, %i1
9: EX_LD(LOAD_TWIN(%i1 + %o4, %o2, %o3)) 9: EX_LD(LOAD_TWIN(%i1 + %o4, %o2, %o3), NG_ret_i2_plus_g1)
MIX_THREE_WORDS(%g3, %o2, %o3, %i5, GLOBAL_SPARE, %o1) MIX_THREE_WORDS(%g3, %o2, %o3, %i5, GLOBAL_SPARE, %o1)
LOAD(prefetch, %i1 + %i3, #one_read) LOAD(prefetch, %i1 + %i3, #one_read)
EX_ST(STORE_INIT(%g3, %o0 + 0x00)) EX_ST(STORE_INIT(%g3, %o0 + 0x00), NG_ret_i2_plus_g1)
EX_ST(STORE_INIT(%o2, %o0 + 0x08)) EX_ST(STORE_INIT(%o2, %o0 + 0x08), NG_ret_i2_plus_g1_minus_8)
EX_LD(LOAD_TWIN(%i1 + %o5, %g2, %g3)) EX_LD(LOAD_TWIN(%i1 + %o5, %g2, %g3), NG_ret_i2_plus_g1_minus_16)
MIX_THREE_WORDS(%o3, %g2, %g3, %i5, GLOBAL_SPARE, %o1) MIX_THREE_WORDS(%o3, %g2, %g3, %i5, GLOBAL_SPARE, %o1)
EX_ST(STORE_INIT(%o3, %o0 + 0x10)) EX_ST(STORE_INIT(%o3, %o0 + 0x10), NG_ret_i2_plus_g1_minus_16)
EX_ST(STORE_INIT(%g2, %o0 + 0x18)) EX_ST(STORE_INIT(%g2, %o0 + 0x18), NG_ret_i2_plus_g1_minus_24)
EX_LD(LOAD_TWIN(%i1 + %o7, %o2, %o3)) EX_LD(LOAD_TWIN(%i1 + %o7, %o2, %o3), NG_ret_i2_plus_g1_minus_32)
MIX_THREE_WORDS(%g3, %o2, %o3, %i5, GLOBAL_SPARE, %o1) MIX_THREE_WORDS(%g3, %o2, %o3, %i5, GLOBAL_SPARE, %o1)
EX_ST(STORE_INIT(%g3, %o0 + 0x20)) EX_ST(STORE_INIT(%g3, %o0 + 0x20), NG_ret_i2_plus_g1_minus_32)
EX_ST(STORE_INIT(%o2, %o0 + 0x28)) EX_ST(STORE_INIT(%o2, %o0 + 0x28), NG_ret_i2_plus_g1_minus_40)
EX_LD(LOAD_TWIN(%i1 + %i3, %g2, %g3)) EX_LD(LOAD_TWIN(%i1 + %i3, %g2, %g3), NG_ret_i2_plus_g1_minus_48)
add %i1, 64, %i1 add %i1, 64, %i1
MIX_THREE_WORDS(%o3, %g2, %g3, %i5, GLOBAL_SPARE, %o1) MIX_THREE_WORDS(%o3, %g2, %g3, %i5, GLOBAL_SPARE, %o1)
EX_ST(STORE_INIT(%o3, %o0 + 0x30)) EX_ST(STORE_INIT(%o3, %o0 + 0x30), NG_ret_i2_plus_g1_minus_48)
EX_ST(STORE_INIT(%g2, %o0 + 0x38)) EX_ST(STORE_INIT(%g2, %o0 + 0x38), NG_ret_i2_plus_g1_minus_56)
subcc %g1, 64, %g1 subcc %g1, 64, %g1
bne,pt %XCC, 9b bne,pt %XCC, 9b
@ -249,25 +332,25 @@ FUNC_NAME: /* %i0=dst, %i1=src, %i2=len */
* one twin load ahead, then add 8 back into source when * one twin load ahead, then add 8 back into source when
* we finish the loop. * we finish the loop.
*/ */
EX_LD(LOAD_TWIN(%i1, %o4, %o5)) EX_LD(LOAD_TWIN(%i1, %o4, %o5), NG_ret_i2_plus_g1)
mov 16, %o7 mov 16, %o7
mov 32, %g2 mov 32, %g2
mov 48, %g3 mov 48, %g3
mov 64, %o1 mov 64, %o1
1: EX_LD(LOAD_TWIN(%i1 + %o7, %o2, %o3)) 1: EX_LD(LOAD_TWIN(%i1 + %o7, %o2, %o3), NG_ret_i2_plus_g1)
LOAD(prefetch, %i1 + %o1, #one_read) LOAD(prefetch, %i1 + %o1, #one_read)
EX_ST(STORE_INIT(%o5, %o0 + 0x00)) ! initializes cache line EX_ST(STORE_INIT(%o5, %o0 + 0x00), NG_ret_i2_plus_g1) ! initializes cache line
EX_ST(STORE_INIT(%o2, %o0 + 0x08)) EX_ST(STORE_INIT(%o2, %o0 + 0x08), NG_ret_i2_plus_g1_minus_8)
EX_LD(LOAD_TWIN(%i1 + %g2, %o4, %o5)) EX_LD(LOAD_TWIN(%i1 + %g2, %o4, %o5), NG_ret_i2_plus_g1_minus_16)
EX_ST(STORE_INIT(%o3, %o0 + 0x10)) EX_ST(STORE_INIT(%o3, %o0 + 0x10), NG_ret_i2_plus_g1_minus_16)
EX_ST(STORE_INIT(%o4, %o0 + 0x18)) EX_ST(STORE_INIT(%o4, %o0 + 0x18), NG_ret_i2_plus_g1_minus_24)
EX_LD(LOAD_TWIN(%i1 + %g3, %o2, %o3)) EX_LD(LOAD_TWIN(%i1 + %g3, %o2, %o3), NG_ret_i2_plus_g1_minus_32)
EX_ST(STORE_INIT(%o5, %o0 + 0x20)) EX_ST(STORE_INIT(%o5, %o0 + 0x20), NG_ret_i2_plus_g1_minus_32)
EX_ST(STORE_INIT(%o2, %o0 + 0x28)) EX_ST(STORE_INIT(%o2, %o0 + 0x28), NG_ret_i2_plus_g1_minus_40)
EX_LD(LOAD_TWIN(%i1 + %o1, %o4, %o5)) EX_LD(LOAD_TWIN(%i1 + %o1, %o4, %o5), NG_ret_i2_plus_g1_minus_48)
add %i1, 64, %i1 add %i1, 64, %i1
EX_ST(STORE_INIT(%o3, %o0 + 0x30)) EX_ST(STORE_INIT(%o3, %o0 + 0x30), NG_ret_i2_plus_g1_minus_48)
EX_ST(STORE_INIT(%o4, %o0 + 0x38)) EX_ST(STORE_INIT(%o4, %o0 + 0x38), NG_ret_i2_plus_g1_minus_56)
subcc %g1, 64, %g1 subcc %g1, 64, %g1
bne,pt %XCC, 1b bne,pt %XCC, 1b
add %o0, 64, %o0 add %o0, 64, %o0
@ -282,20 +365,20 @@ FUNC_NAME: /* %i0=dst, %i1=src, %i2=len */
mov 32, %g2 mov 32, %g2
mov 48, %g3 mov 48, %g3
mov 64, %o1 mov 64, %o1
1: EX_LD(LOAD_TWIN(%i1 + %g0, %o4, %o5)) 1: EX_LD(LOAD_TWIN(%i1 + %g0, %o4, %o5), NG_ret_i2_plus_g1)
EX_LD(LOAD_TWIN(%i1 + %o7, %o2, %o3)) EX_LD(LOAD_TWIN(%i1 + %o7, %o2, %o3), NG_ret_i2_plus_g1)
LOAD(prefetch, %i1 + %o1, #one_read) LOAD(prefetch, %i1 + %o1, #one_read)
EX_ST(STORE_INIT(%o4, %o0 + 0x00)) ! initializes cache line EX_ST(STORE_INIT(%o4, %o0 + 0x00), NG_ret_i2_plus_g1) ! initializes cache line
EX_ST(STORE_INIT(%o5, %o0 + 0x08)) EX_ST(STORE_INIT(%o5, %o0 + 0x08), NG_ret_i2_plus_g1_minus_8)
EX_LD(LOAD_TWIN(%i1 + %g2, %o4, %o5)) EX_LD(LOAD_TWIN(%i1 + %g2, %o4, %o5), NG_ret_i2_plus_g1_minus_16)
EX_ST(STORE_INIT(%o2, %o0 + 0x10)) EX_ST(STORE_INIT(%o2, %o0 + 0x10), NG_ret_i2_plus_g1_minus_16)
EX_ST(STORE_INIT(%o3, %o0 + 0x18)) EX_ST(STORE_INIT(%o3, %o0 + 0x18), NG_ret_i2_plus_g1_minus_24)
EX_LD(LOAD_TWIN(%i1 + %g3, %o2, %o3)) EX_LD(LOAD_TWIN(%i1 + %g3, %o2, %o3), NG_ret_i2_plus_g1_minus_32)
add %i1, 64, %i1 add %i1, 64, %i1
EX_ST(STORE_INIT(%o4, %o0 + 0x20)) EX_ST(STORE_INIT(%o4, %o0 + 0x20), NG_ret_i2_plus_g1_minus_32)
EX_ST(STORE_INIT(%o5, %o0 + 0x28)) EX_ST(STORE_INIT(%o5, %o0 + 0x28), NG_ret_i2_plus_g1_minus_40)
EX_ST(STORE_INIT(%o2, %o0 + 0x30)) EX_ST(STORE_INIT(%o2, %o0 + 0x30), NG_ret_i2_plus_g1_minus_48)
EX_ST(STORE_INIT(%o3, %o0 + 0x38)) EX_ST(STORE_INIT(%o3, %o0 + 0x38), NG_ret_i2_plus_g1_minus_56)
subcc %g1, 64, %g1 subcc %g1, 64, %g1
bne,pt %XCC, 1b bne,pt %XCC, 1b
add %o0, 64, %o0 add %o0, 64, %o0
@ -321,28 +404,28 @@ FUNC_NAME: /* %i0=dst, %i1=src, %i2=len */
andn %i2, 0xf, %i4 andn %i2, 0xf, %i4
and %i2, 0xf, %i2 and %i2, 0xf, %i2
1: subcc %i4, 0x10, %i4 1: subcc %i4, 0x10, %i4
EX_LD(LOAD(ldx, %i1, %o4)) EX_LD(LOAD(ldx, %i1, %o4), NG_ret_i2_plus_i4)
add %i1, 0x08, %i1 add %i1, 0x08, %i1
EX_LD(LOAD(ldx, %i1, %g1)) EX_LD(LOAD(ldx, %i1, %g1), NG_ret_i2_plus_i4)
sub %i1, 0x08, %i1 sub %i1, 0x08, %i1
EX_ST(STORE(stx, %o4, %i1 + %i3)) EX_ST(STORE(stx, %o4, %i1 + %i3), NG_ret_i2_plus_i4)
add %i1, 0x8, %i1 add %i1, 0x8, %i1
EX_ST(STORE(stx, %g1, %i1 + %i3)) EX_ST(STORE(stx, %g1, %i1 + %i3), NG_ret_i2_plus_i4_minus_8)
bgu,pt %XCC, 1b bgu,pt %XCC, 1b
add %i1, 0x8, %i1 add %i1, 0x8, %i1
73: andcc %i2, 0x8, %g0 73: andcc %i2, 0x8, %g0
be,pt %XCC, 1f be,pt %XCC, 1f
nop nop
sub %i2, 0x8, %i2 sub %i2, 0x8, %i2
EX_LD(LOAD(ldx, %i1, %o4)) EX_LD(LOAD(ldx, %i1, %o4), NG_ret_i2_plus_8)
EX_ST(STORE(stx, %o4, %i1 + %i3)) EX_ST(STORE(stx, %o4, %i1 + %i3), NG_ret_i2_plus_8)
add %i1, 0x8, %i1 add %i1, 0x8, %i1
1: andcc %i2, 0x4, %g0 1: andcc %i2, 0x4, %g0
be,pt %XCC, 1f be,pt %XCC, 1f
nop nop
sub %i2, 0x4, %i2 sub %i2, 0x4, %i2
EX_LD(LOAD(lduw, %i1, %i5)) EX_LD(LOAD(lduw, %i1, %i5), NG_ret_i2_plus_4)
EX_ST(STORE(stw, %i5, %i1 + %i3)) EX_ST(STORE(stw, %i5, %i1 + %i3), NG_ret_i2_plus_4)
add %i1, 0x4, %i1 add %i1, 0x4, %i1
1: cmp %i2, 0 1: cmp %i2, 0
be,pt %XCC, 85f be,pt %XCC, 85f
@ -358,8 +441,8 @@ FUNC_NAME: /* %i0=dst, %i1=src, %i2=len */
sub %i2, %g1, %i2 sub %i2, %g1, %i2
1: subcc %g1, 1, %g1 1: subcc %g1, 1, %g1
EX_LD(LOAD(ldub, %i1, %i5)) EX_LD(LOAD(ldub, %i1, %i5), NG_ret_i2_plus_g1_plus_1)
EX_ST(STORE(stb, %i5, %i1 + %i3)) EX_ST(STORE(stb, %i5, %i1 + %i3), NG_ret_i2_plus_g1_plus_1)
bgu,pt %icc, 1b bgu,pt %icc, 1b
add %i1, 1, %i1 add %i1, 1, %i1
@ -375,16 +458,16 @@ FUNC_NAME: /* %i0=dst, %i1=src, %i2=len */
8: mov 64, %i3 8: mov 64, %i3
andn %i1, 0x7, %i1 andn %i1, 0x7, %i1
EX_LD(LOAD(ldx, %i1, %g2)) EX_LD(LOAD(ldx, %i1, %g2), NG_ret_i2)
sub %i3, %g1, %i3 sub %i3, %g1, %i3
andn %i2, 0x7, %i4 andn %i2, 0x7, %i4
sllx %g2, %g1, %g2 sllx %g2, %g1, %g2
1: add %i1, 0x8, %i1 1: add %i1, 0x8, %i1
EX_LD(LOAD(ldx, %i1, %g3)) EX_LD(LOAD(ldx, %i1, %g3), NG_ret_i2_and_7_plus_i4)
subcc %i4, 0x8, %i4 subcc %i4, 0x8, %i4
srlx %g3, %i3, %i5 srlx %g3, %i3, %i5
or %i5, %g2, %i5 or %i5, %g2, %i5
EX_ST(STORE(stx, %i5, %o0)) EX_ST(STORE(stx, %i5, %o0), NG_ret_i2_and_7_plus_i4)
add %o0, 0x8, %o0 add %o0, 0x8, %o0
bgu,pt %icc, 1b bgu,pt %icc, 1b
sllx %g3, %g1, %g2 sllx %g3, %g1, %g2
@ -404,8 +487,8 @@ FUNC_NAME: /* %i0=dst, %i1=src, %i2=len */
1: 1:
subcc %i2, 4, %i2 subcc %i2, 4, %i2
EX_LD(LOAD(lduw, %i1, %g1)) EX_LD(LOAD(lduw, %i1, %g1), NG_ret_i2_plus_4)
EX_ST(STORE(stw, %g1, %i1 + %i3)) EX_ST(STORE(stw, %g1, %i1 + %i3), NG_ret_i2_plus_4)
bgu,pt %XCC, 1b bgu,pt %XCC, 1b
add %i1, 4, %i1 add %i1, 4, %i1
@ -415,8 +498,8 @@ FUNC_NAME: /* %i0=dst, %i1=src, %i2=len */
.align 32 .align 32
90: 90:
subcc %i2, 1, %i2 subcc %i2, 1, %i2
EX_LD(LOAD(ldub, %i1, %g1)) EX_LD(LOAD(ldub, %i1, %g1), NG_ret_i2_plus_1)
EX_ST(STORE(stb, %g1, %i1 + %i3)) EX_ST(STORE(stb, %g1, %i1 + %i3), NG_ret_i2_plus_1)
bgu,pt %XCC, 90b bgu,pt %XCC, 90b
add %i1, 1, %i1 add %i1, 1, %i1
ret ret

View File

@ -3,19 +3,19 @@
* Copyright (C) 1999, 2000, 2004 David S. Miller (davem@redhat.com) * Copyright (C) 1999, 2000, 2004 David S. Miller (davem@redhat.com)
*/ */
#define EX_LD(x) \ #define EX_LD(x,y) \
98: x; \ 98: x; \
.section __ex_table,"a";\ .section __ex_table,"a";\
.align 4; \ .align 4; \
.word 98b, __retl_one; \ .word 98b, y; \
.text; \ .text; \
.align 4; .align 4;
#define EX_LD_FP(x) \ #define EX_LD_FP(x,y) \
98: x; \ 98: x; \
.section __ex_table,"a";\ .section __ex_table,"a";\
.align 4; \ .align 4; \
.word 98b, __retl_one_fp;\ .word 98b, y; \
.text; \ .text; \
.align 4; .align 4;

View File

@ -3,19 +3,19 @@
* Copyright (C) 1999, 2000, 2004 David S. Miller (davem@redhat.com) * Copyright (C) 1999, 2000, 2004 David S. Miller (davem@redhat.com)
*/ */
#define EX_ST(x) \ #define EX_ST(x,y) \
98: x; \ 98: x; \
.section __ex_table,"a";\ .section __ex_table,"a";\
.align 4; \ .align 4; \
.word 98b, __retl_one; \ .word 98b, y; \
.text; \ .text; \
.align 4; .align 4;
#define EX_ST_FP(x) \ #define EX_ST_FP(x,y) \
98: x; \ 98: x; \
.section __ex_table,"a";\ .section __ex_table,"a";\
.align 4; \ .align 4; \
.word 98b, __retl_one_fp;\ .word 98b, y; \
.text; \ .text; \
.align 4; .align 4;

View File

@ -5,6 +5,7 @@
*/ */
#ifdef __KERNEL__ #ifdef __KERNEL__
#include <linux/linkage.h>
#include <asm/visasm.h> #include <asm/visasm.h>
#include <asm/asi.h> #include <asm/asi.h>
#include <asm/export.h> #include <asm/export.h>
@ -24,21 +25,17 @@
#endif #endif
#ifndef EX_LD #ifndef EX_LD
#define EX_LD(x) x #define EX_LD(x,y) x
#endif #endif
#ifndef EX_LD_FP #ifndef EX_LD_FP
#define EX_LD_FP(x) x #define EX_LD_FP(x,y) x
#endif #endif
#ifndef EX_ST #ifndef EX_ST
#define EX_ST(x) x #define EX_ST(x,y) x
#endif #endif
#ifndef EX_ST_FP #ifndef EX_ST_FP
#define EX_ST_FP(x) x #define EX_ST_FP(x,y) x
#endif
#ifndef EX_RETVAL
#define EX_RETVAL(x) x
#endif #endif
#ifndef LOAD #ifndef LOAD
@ -79,53 +76,169 @@
faligndata %f7, %f8, %f60; \ faligndata %f7, %f8, %f60; \
faligndata %f8, %f9, %f62; faligndata %f8, %f9, %f62;
#define MAIN_LOOP_CHUNK(src, dest, fdest, fsrc, len, jmptgt) \ #define MAIN_LOOP_CHUNK(src, dest, fdest, fsrc, jmptgt) \
EX_LD_FP(LOAD_BLK(%src, %fdest)); \ EX_LD_FP(LOAD_BLK(%src, %fdest), U1_gs_80_fp); \
EX_ST_FP(STORE_BLK(%fsrc, %dest)); \ EX_ST_FP(STORE_BLK(%fsrc, %dest), U1_gs_80_fp); \
add %src, 0x40, %src; \ add %src, 0x40, %src; \
subcc %len, 0x40, %len; \ subcc %GLOBAL_SPARE, 0x40, %GLOBAL_SPARE; \
be,pn %xcc, jmptgt; \ be,pn %xcc, jmptgt; \
add %dest, 0x40, %dest; \ add %dest, 0x40, %dest; \
#define LOOP_CHUNK1(src, dest, len, branch_dest) \ #define LOOP_CHUNK1(src, dest, branch_dest) \
MAIN_LOOP_CHUNK(src, dest, f0, f48, len, branch_dest) MAIN_LOOP_CHUNK(src, dest, f0, f48, branch_dest)
#define LOOP_CHUNK2(src, dest, len, branch_dest) \ #define LOOP_CHUNK2(src, dest, branch_dest) \
MAIN_LOOP_CHUNK(src, dest, f16, f48, len, branch_dest) MAIN_LOOP_CHUNK(src, dest, f16, f48, branch_dest)
#define LOOP_CHUNK3(src, dest, len, branch_dest) \ #define LOOP_CHUNK3(src, dest, branch_dest) \
MAIN_LOOP_CHUNK(src, dest, f32, f48, len, branch_dest) MAIN_LOOP_CHUNK(src, dest, f32, f48, branch_dest)
#define DO_SYNC membar #Sync; #define DO_SYNC membar #Sync;
#define STORE_SYNC(dest, fsrc) \ #define STORE_SYNC(dest, fsrc) \
EX_ST_FP(STORE_BLK(%fsrc, %dest)); \ EX_ST_FP(STORE_BLK(%fsrc, %dest), U1_gs_80_fp); \
add %dest, 0x40, %dest; \ add %dest, 0x40, %dest; \
DO_SYNC DO_SYNC
#define STORE_JUMP(dest, fsrc, target) \ #define STORE_JUMP(dest, fsrc, target) \
EX_ST_FP(STORE_BLK(%fsrc, %dest)); \ EX_ST_FP(STORE_BLK(%fsrc, %dest), U1_gs_40_fp); \
add %dest, 0x40, %dest; \ add %dest, 0x40, %dest; \
ba,pt %xcc, target; \ ba,pt %xcc, target; \
nop; nop;
#define FINISH_VISCHUNK(dest, f0, f1, left) \ #define FINISH_VISCHUNK(dest, f0, f1) \
subcc %left, 8, %left;\ subcc %g3, 8, %g3; \
bl,pn %xcc, 95f; \ bl,pn %xcc, 95f; \
faligndata %f0, %f1, %f48; \ faligndata %f0, %f1, %f48; \
EX_ST_FP(STORE(std, %f48, %dest)); \ EX_ST_FP(STORE(std, %f48, %dest), U1_g3_8_fp); \
add %dest, 8, %dest; add %dest, 8, %dest;
#define UNEVEN_VISCHUNK_LAST(dest, f0, f1, left) \ #define UNEVEN_VISCHUNK_LAST(dest, f0, f1) \
subcc %left, 8, %left; \ subcc %g3, 8, %g3; \
bl,pn %xcc, 95f; \ bl,pn %xcc, 95f; \
fsrc2 %f0, %f1; fsrc2 %f0, %f1;
#define UNEVEN_VISCHUNK(dest, f0, f1, left) \ #define UNEVEN_VISCHUNK(dest, f0, f1) \
UNEVEN_VISCHUNK_LAST(dest, f0, f1, left) \ UNEVEN_VISCHUNK_LAST(dest, f0, f1) \
ba,a,pt %xcc, 93f; ba,a,pt %xcc, 93f;
.register %g2,#scratch .register %g2,#scratch
.register %g3,#scratch .register %g3,#scratch
.text .text
#ifndef EX_RETVAL
#define EX_RETVAL(x) x
ENTRY(U1_g1_1_fp)
VISExitHalf
add %g1, 1, %g1
add %g1, %g2, %g1
retl
add %g1, %o2, %o0
ENDPROC(U1_g1_1_fp)
ENTRY(U1_g2_0_fp)
VISExitHalf
retl
add %g2, %o2, %o0
ENDPROC(U1_g2_0_fp)
ENTRY(U1_g2_8_fp)
VISExitHalf
add %g2, 8, %g2
retl
add %g2, %o2, %o0
ENDPROC(U1_g2_8_fp)
ENTRY(U1_gs_0_fp)
VISExitHalf
add %GLOBAL_SPARE, %g3, %o0
retl
add %o0, %o2, %o0
ENDPROC(U1_gs_0_fp)
ENTRY(U1_gs_80_fp)
VISExitHalf
add %GLOBAL_SPARE, 0x80, %GLOBAL_SPARE
add %GLOBAL_SPARE, %g3, %o0
retl
add %o0, %o2, %o0
ENDPROC(U1_gs_80_fp)
ENTRY(U1_gs_40_fp)
VISExitHalf
add %GLOBAL_SPARE, 0x40, %GLOBAL_SPARE
add %GLOBAL_SPARE, %g3, %o0
retl
add %o0, %o2, %o0
ENDPROC(U1_gs_40_fp)
ENTRY(U1_g3_0_fp)
VISExitHalf
retl
add %g3, %o2, %o0
ENDPROC(U1_g3_0_fp)
ENTRY(U1_g3_8_fp)
VISExitHalf
add %g3, 8, %g3
retl
add %g3, %o2, %o0
ENDPROC(U1_g3_8_fp)
ENTRY(U1_o2_0_fp)
VISExitHalf
retl
mov %o2, %o0
ENDPROC(U1_o2_0_fp)
ENTRY(U1_o2_1_fp)
VISExitHalf
retl
add %o2, 1, %o0
ENDPROC(U1_o2_1_fp)
ENTRY(U1_gs_0)
VISExitHalf
retl
add %GLOBAL_SPARE, %o2, %o0
ENDPROC(U1_gs_0)
ENTRY(U1_gs_8)
VISExitHalf
add %GLOBAL_SPARE, %o2, %GLOBAL_SPARE
retl
add %GLOBAL_SPARE, 0x8, %o0
ENDPROC(U1_gs_8)
ENTRY(U1_gs_10)
VISExitHalf
add %GLOBAL_SPARE, %o2, %GLOBAL_SPARE
retl
add %GLOBAL_SPARE, 0x10, %o0
ENDPROC(U1_gs_10)
ENTRY(U1_o2_0)
retl
mov %o2, %o0
ENDPROC(U1_o2_0)
ENTRY(U1_o2_8)
retl
add %o2, 8, %o0
ENDPROC(U1_o2_8)
ENTRY(U1_o2_4)
retl
add %o2, 4, %o0
ENDPROC(U1_o2_4)
ENTRY(U1_o2_1)
retl
add %o2, 1, %o0
ENDPROC(U1_o2_1)
ENTRY(U1_g1_0)
retl
add %g1, %o2, %o0
ENDPROC(U1_g1_0)
ENTRY(U1_g1_1)
add %g1, 1, %g1
retl
add %g1, %o2, %o0
ENDPROC(U1_g1_1)
ENTRY(U1_gs_0_o2_adj)
and %o2, 7, %o2
retl
add %GLOBAL_SPARE, %o2, %o0
ENDPROC(U1_gs_0_o2_adj)
ENTRY(U1_gs_8_o2_adj)
and %o2, 7, %o2
add %GLOBAL_SPARE, 8, %GLOBAL_SPARE
retl
add %GLOBAL_SPARE, %o2, %o0
ENDPROC(U1_gs_8_o2_adj)
#endif
.align 64 .align 64
.globl FUNC_NAME .globl FUNC_NAME
@ -167,8 +280,8 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
and %g2, 0x38, %g2 and %g2, 0x38, %g2
1: subcc %g1, 0x1, %g1 1: subcc %g1, 0x1, %g1
EX_LD_FP(LOAD(ldub, %o1 + 0x00, %o3)) EX_LD_FP(LOAD(ldub, %o1 + 0x00, %o3), U1_g1_1_fp)
EX_ST_FP(STORE(stb, %o3, %o1 + %GLOBAL_SPARE)) EX_ST_FP(STORE(stb, %o3, %o1 + %GLOBAL_SPARE), U1_g1_1_fp)
bgu,pt %XCC, 1b bgu,pt %XCC, 1b
add %o1, 0x1, %o1 add %o1, 0x1, %o1
@ -179,20 +292,20 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
be,pt %icc, 3f be,pt %icc, 3f
alignaddr %o1, %g0, %o1 alignaddr %o1, %g0, %o1
EX_LD_FP(LOAD(ldd, %o1, %f4)) EX_LD_FP(LOAD(ldd, %o1, %f4), U1_g2_0_fp)
1: EX_LD_FP(LOAD(ldd, %o1 + 0x8, %f6)) 1: EX_LD_FP(LOAD(ldd, %o1 + 0x8, %f6), U1_g2_0_fp)
add %o1, 0x8, %o1 add %o1, 0x8, %o1
subcc %g2, 0x8, %g2 subcc %g2, 0x8, %g2
faligndata %f4, %f6, %f0 faligndata %f4, %f6, %f0
EX_ST_FP(STORE(std, %f0, %o0)) EX_ST_FP(STORE(std, %f0, %o0), U1_g2_8_fp)
be,pn %icc, 3f be,pn %icc, 3f
add %o0, 0x8, %o0 add %o0, 0x8, %o0
EX_LD_FP(LOAD(ldd, %o1 + 0x8, %f4)) EX_LD_FP(LOAD(ldd, %o1 + 0x8, %f4), U1_g2_0_fp)
add %o1, 0x8, %o1 add %o1, 0x8, %o1
subcc %g2, 0x8, %g2 subcc %g2, 0x8, %g2
faligndata %f6, %f4, %f0 faligndata %f6, %f4, %f0
EX_ST_FP(STORE(std, %f0, %o0)) EX_ST_FP(STORE(std, %f0, %o0), U1_g2_8_fp)
bne,pt %icc, 1b bne,pt %icc, 1b
add %o0, 0x8, %o0 add %o0, 0x8, %o0
@ -215,13 +328,13 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
add %g1, %GLOBAL_SPARE, %g1 add %g1, %GLOBAL_SPARE, %g1
subcc %o2, %g3, %o2 subcc %o2, %g3, %o2
EX_LD_FP(LOAD_BLK(%o1, %f0)) EX_LD_FP(LOAD_BLK(%o1, %f0), U1_gs_0_fp)
add %o1, 0x40, %o1 add %o1, 0x40, %o1
add %g1, %g3, %g1 add %g1, %g3, %g1
EX_LD_FP(LOAD_BLK(%o1, %f16)) EX_LD_FP(LOAD_BLK(%o1, %f16), U1_gs_0_fp)
add %o1, 0x40, %o1 add %o1, 0x40, %o1
sub %GLOBAL_SPARE, 0x80, %GLOBAL_SPARE sub %GLOBAL_SPARE, 0x80, %GLOBAL_SPARE
EX_LD_FP(LOAD_BLK(%o1, %f32)) EX_LD_FP(LOAD_BLK(%o1, %f32), U1_gs_80_fp)
add %o1, 0x40, %o1 add %o1, 0x40, %o1
/* There are 8 instances of the unrolled loop, /* There are 8 instances of the unrolled loop,
@ -241,11 +354,11 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
.align 64 .align 64
1: FREG_FROB(f0, f2, f4, f6, f8, f10,f12,f14,f16) 1: FREG_FROB(f0, f2, f4, f6, f8, f10,f12,f14,f16)
LOOP_CHUNK1(o1, o0, GLOBAL_SPARE, 1f) LOOP_CHUNK1(o1, o0, 1f)
FREG_FROB(f16,f18,f20,f22,f24,f26,f28,f30,f32) FREG_FROB(f16,f18,f20,f22,f24,f26,f28,f30,f32)
LOOP_CHUNK2(o1, o0, GLOBAL_SPARE, 2f) LOOP_CHUNK2(o1, o0, 2f)
FREG_FROB(f32,f34,f36,f38,f40,f42,f44,f46,f0) FREG_FROB(f32,f34,f36,f38,f40,f42,f44,f46,f0)
LOOP_CHUNK3(o1, o0, GLOBAL_SPARE, 3f) LOOP_CHUNK3(o1, o0, 3f)
ba,pt %xcc, 1b+4 ba,pt %xcc, 1b+4
faligndata %f0, %f2, %f48 faligndata %f0, %f2, %f48
1: FREG_FROB(f16,f18,f20,f22,f24,f26,f28,f30,f32) 1: FREG_FROB(f16,f18,f20,f22,f24,f26,f28,f30,f32)
@ -262,11 +375,11 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
STORE_JUMP(o0, f48, 56f) STORE_JUMP(o0, f48, 56f)
1: FREG_FROB(f2, f4, f6, f8, f10,f12,f14,f16,f18) 1: FREG_FROB(f2, f4, f6, f8, f10,f12,f14,f16,f18)
LOOP_CHUNK1(o1, o0, GLOBAL_SPARE, 1f) LOOP_CHUNK1(o1, o0, 1f)
FREG_FROB(f18,f20,f22,f24,f26,f28,f30,f32,f34) FREG_FROB(f18,f20,f22,f24,f26,f28,f30,f32,f34)
LOOP_CHUNK2(o1, o0, GLOBAL_SPARE, 2f) LOOP_CHUNK2(o1, o0, 2f)
FREG_FROB(f34,f36,f38,f40,f42,f44,f46,f0, f2) FREG_FROB(f34,f36,f38,f40,f42,f44,f46,f0, f2)
LOOP_CHUNK3(o1, o0, GLOBAL_SPARE, 3f) LOOP_CHUNK3(o1, o0, 3f)
ba,pt %xcc, 1b+4 ba,pt %xcc, 1b+4
faligndata %f2, %f4, %f48 faligndata %f2, %f4, %f48
1: FREG_FROB(f18,f20,f22,f24,f26,f28,f30,f32,f34) 1: FREG_FROB(f18,f20,f22,f24,f26,f28,f30,f32,f34)
@ -283,11 +396,11 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
STORE_JUMP(o0, f48, 57f) STORE_JUMP(o0, f48, 57f)
1: FREG_FROB(f4, f6, f8, f10,f12,f14,f16,f18,f20) 1: FREG_FROB(f4, f6, f8, f10,f12,f14,f16,f18,f20)
LOOP_CHUNK1(o1, o0, GLOBAL_SPARE, 1f) LOOP_CHUNK1(o1, o0, 1f)
FREG_FROB(f20,f22,f24,f26,f28,f30,f32,f34,f36) FREG_FROB(f20,f22,f24,f26,f28,f30,f32,f34,f36)
LOOP_CHUNK2(o1, o0, GLOBAL_SPARE, 2f) LOOP_CHUNK2(o1, o0, 2f)
FREG_FROB(f36,f38,f40,f42,f44,f46,f0, f2, f4) FREG_FROB(f36,f38,f40,f42,f44,f46,f0, f2, f4)
LOOP_CHUNK3(o1, o0, GLOBAL_SPARE, 3f) LOOP_CHUNK3(o1, o0, 3f)
ba,pt %xcc, 1b+4 ba,pt %xcc, 1b+4
faligndata %f4, %f6, %f48 faligndata %f4, %f6, %f48
1: FREG_FROB(f20,f22,f24,f26,f28,f30,f32,f34,f36) 1: FREG_FROB(f20,f22,f24,f26,f28,f30,f32,f34,f36)
@ -304,11 +417,11 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
STORE_JUMP(o0, f48, 58f) STORE_JUMP(o0, f48, 58f)
1: FREG_FROB(f6, f8, f10,f12,f14,f16,f18,f20,f22) 1: FREG_FROB(f6, f8, f10,f12,f14,f16,f18,f20,f22)
LOOP_CHUNK1(o1, o0, GLOBAL_SPARE, 1f) LOOP_CHUNK1(o1, o0, 1f)
FREG_FROB(f22,f24,f26,f28,f30,f32,f34,f36,f38) FREG_FROB(f22,f24,f26,f28,f30,f32,f34,f36,f38)
LOOP_CHUNK2(o1, o0, GLOBAL_SPARE, 2f) LOOP_CHUNK2(o1, o0, 2f)
FREG_FROB(f38,f40,f42,f44,f46,f0, f2, f4, f6) FREG_FROB(f38,f40,f42,f44,f46,f0, f2, f4, f6)
LOOP_CHUNK3(o1, o0, GLOBAL_SPARE, 3f) LOOP_CHUNK3(o1, o0, 3f)
ba,pt %xcc, 1b+4 ba,pt %xcc, 1b+4
faligndata %f6, %f8, %f48 faligndata %f6, %f8, %f48
1: FREG_FROB(f22,f24,f26,f28,f30,f32,f34,f36,f38) 1: FREG_FROB(f22,f24,f26,f28,f30,f32,f34,f36,f38)
@ -325,11 +438,11 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
STORE_JUMP(o0, f48, 59f) STORE_JUMP(o0, f48, 59f)
1: FREG_FROB(f8, f10,f12,f14,f16,f18,f20,f22,f24) 1: FREG_FROB(f8, f10,f12,f14,f16,f18,f20,f22,f24)
LOOP_CHUNK1(o1, o0, GLOBAL_SPARE, 1f) LOOP_CHUNK1(o1, o0, 1f)
FREG_FROB(f24,f26,f28,f30,f32,f34,f36,f38,f40) FREG_FROB(f24,f26,f28,f30,f32,f34,f36,f38,f40)
LOOP_CHUNK2(o1, o0, GLOBAL_SPARE, 2f) LOOP_CHUNK2(o1, o0, 2f)
FREG_FROB(f40,f42,f44,f46,f0, f2, f4, f6, f8) FREG_FROB(f40,f42,f44,f46,f0, f2, f4, f6, f8)
LOOP_CHUNK3(o1, o0, GLOBAL_SPARE, 3f) LOOP_CHUNK3(o1, o0, 3f)
ba,pt %xcc, 1b+4 ba,pt %xcc, 1b+4
faligndata %f8, %f10, %f48 faligndata %f8, %f10, %f48
1: FREG_FROB(f24,f26,f28,f30,f32,f34,f36,f38,f40) 1: FREG_FROB(f24,f26,f28,f30,f32,f34,f36,f38,f40)
@ -346,11 +459,11 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
STORE_JUMP(o0, f48, 60f) STORE_JUMP(o0, f48, 60f)
1: FREG_FROB(f10,f12,f14,f16,f18,f20,f22,f24,f26) 1: FREG_FROB(f10,f12,f14,f16,f18,f20,f22,f24,f26)
LOOP_CHUNK1(o1, o0, GLOBAL_SPARE, 1f) LOOP_CHUNK1(o1, o0, 1f)
FREG_FROB(f26,f28,f30,f32,f34,f36,f38,f40,f42) FREG_FROB(f26,f28,f30,f32,f34,f36,f38,f40,f42)
LOOP_CHUNK2(o1, o0, GLOBAL_SPARE, 2f) LOOP_CHUNK2(o1, o0, 2f)
FREG_FROB(f42,f44,f46,f0, f2, f4, f6, f8, f10) FREG_FROB(f42,f44,f46,f0, f2, f4, f6, f8, f10)
LOOP_CHUNK3(o1, o0, GLOBAL_SPARE, 3f) LOOP_CHUNK3(o1, o0, 3f)
ba,pt %xcc, 1b+4 ba,pt %xcc, 1b+4
faligndata %f10, %f12, %f48 faligndata %f10, %f12, %f48
1: FREG_FROB(f26,f28,f30,f32,f34,f36,f38,f40,f42) 1: FREG_FROB(f26,f28,f30,f32,f34,f36,f38,f40,f42)
@ -367,11 +480,11 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
STORE_JUMP(o0, f48, 61f) STORE_JUMP(o0, f48, 61f)
1: FREG_FROB(f12,f14,f16,f18,f20,f22,f24,f26,f28) 1: FREG_FROB(f12,f14,f16,f18,f20,f22,f24,f26,f28)
LOOP_CHUNK1(o1, o0, GLOBAL_SPARE, 1f) LOOP_CHUNK1(o1, o0, 1f)
FREG_FROB(f28,f30,f32,f34,f36,f38,f40,f42,f44) FREG_FROB(f28,f30,f32,f34,f36,f38,f40,f42,f44)
LOOP_CHUNK2(o1, o0, GLOBAL_SPARE, 2f) LOOP_CHUNK2(o1, o0, 2f)
FREG_FROB(f44,f46,f0, f2, f4, f6, f8, f10,f12) FREG_FROB(f44,f46,f0, f2, f4, f6, f8, f10,f12)
LOOP_CHUNK3(o1, o0, GLOBAL_SPARE, 3f) LOOP_CHUNK3(o1, o0, 3f)
ba,pt %xcc, 1b+4 ba,pt %xcc, 1b+4
faligndata %f12, %f14, %f48 faligndata %f12, %f14, %f48
1: FREG_FROB(f28,f30,f32,f34,f36,f38,f40,f42,f44) 1: FREG_FROB(f28,f30,f32,f34,f36,f38,f40,f42,f44)
@ -388,11 +501,11 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
STORE_JUMP(o0, f48, 62f) STORE_JUMP(o0, f48, 62f)
1: FREG_FROB(f14,f16,f18,f20,f22,f24,f26,f28,f30) 1: FREG_FROB(f14,f16,f18,f20,f22,f24,f26,f28,f30)
LOOP_CHUNK1(o1, o0, GLOBAL_SPARE, 1f) LOOP_CHUNK1(o1, o0, 1f)
FREG_FROB(f30,f32,f34,f36,f38,f40,f42,f44,f46) FREG_FROB(f30,f32,f34,f36,f38,f40,f42,f44,f46)
LOOP_CHUNK2(o1, o0, GLOBAL_SPARE, 2f) LOOP_CHUNK2(o1, o0, 2f)
FREG_FROB(f46,f0, f2, f4, f6, f8, f10,f12,f14) FREG_FROB(f46,f0, f2, f4, f6, f8, f10,f12,f14)
LOOP_CHUNK3(o1, o0, GLOBAL_SPARE, 3f) LOOP_CHUNK3(o1, o0, 3f)
ba,pt %xcc, 1b+4 ba,pt %xcc, 1b+4
faligndata %f14, %f16, %f48 faligndata %f14, %f16, %f48
1: FREG_FROB(f30,f32,f34,f36,f38,f40,f42,f44,f46) 1: FREG_FROB(f30,f32,f34,f36,f38,f40,f42,f44,f46)
@ -408,53 +521,53 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
FREG_FROB(f30,f32,f34,f36,f38,f40,f42,f44,f46) FREG_FROB(f30,f32,f34,f36,f38,f40,f42,f44,f46)
STORE_JUMP(o0, f48, 63f) STORE_JUMP(o0, f48, 63f)
40: FINISH_VISCHUNK(o0, f0, f2, g3) 40: FINISH_VISCHUNK(o0, f0, f2)
41: FINISH_VISCHUNK(o0, f2, f4, g3) 41: FINISH_VISCHUNK(o0, f2, f4)
42: FINISH_VISCHUNK(o0, f4, f6, g3) 42: FINISH_VISCHUNK(o0, f4, f6)
43: FINISH_VISCHUNK(o0, f6, f8, g3) 43: FINISH_VISCHUNK(o0, f6, f8)
44: FINISH_VISCHUNK(o0, f8, f10, g3) 44: FINISH_VISCHUNK(o0, f8, f10)
45: FINISH_VISCHUNK(o0, f10, f12, g3) 45: FINISH_VISCHUNK(o0, f10, f12)
46: FINISH_VISCHUNK(o0, f12, f14, g3) 46: FINISH_VISCHUNK(o0, f12, f14)
47: UNEVEN_VISCHUNK(o0, f14, f0, g3) 47: UNEVEN_VISCHUNK(o0, f14, f0)
48: FINISH_VISCHUNK(o0, f16, f18, g3) 48: FINISH_VISCHUNK(o0, f16, f18)
49: FINISH_VISCHUNK(o0, f18, f20, g3) 49: FINISH_VISCHUNK(o0, f18, f20)
50: FINISH_VISCHUNK(o0, f20, f22, g3) 50: FINISH_VISCHUNK(o0, f20, f22)
51: FINISH_VISCHUNK(o0, f22, f24, g3) 51: FINISH_VISCHUNK(o0, f22, f24)
52: FINISH_VISCHUNK(o0, f24, f26, g3) 52: FINISH_VISCHUNK(o0, f24, f26)
53: FINISH_VISCHUNK(o0, f26, f28, g3) 53: FINISH_VISCHUNK(o0, f26, f28)
54: FINISH_VISCHUNK(o0, f28, f30, g3) 54: FINISH_VISCHUNK(o0, f28, f30)
55: UNEVEN_VISCHUNK(o0, f30, f0, g3) 55: UNEVEN_VISCHUNK(o0, f30, f0)
56: FINISH_VISCHUNK(o0, f32, f34, g3) 56: FINISH_VISCHUNK(o0, f32, f34)
57: FINISH_VISCHUNK(o0, f34, f36, g3) 57: FINISH_VISCHUNK(o0, f34, f36)
58: FINISH_VISCHUNK(o0, f36, f38, g3) 58: FINISH_VISCHUNK(o0, f36, f38)
59: FINISH_VISCHUNK(o0, f38, f40, g3) 59: FINISH_VISCHUNK(o0, f38, f40)
60: FINISH_VISCHUNK(o0, f40, f42, g3) 60: FINISH_VISCHUNK(o0, f40, f42)
61: FINISH_VISCHUNK(o0, f42, f44, g3) 61: FINISH_VISCHUNK(o0, f42, f44)
62: FINISH_VISCHUNK(o0, f44, f46, g3) 62: FINISH_VISCHUNK(o0, f44, f46)
63: UNEVEN_VISCHUNK_LAST(o0, f46, f0, g3) 63: UNEVEN_VISCHUNK_LAST(o0, f46, f0)
93: EX_LD_FP(LOAD(ldd, %o1, %f2)) 93: EX_LD_FP(LOAD(ldd, %o1, %f2), U1_g3_0_fp)
add %o1, 8, %o1 add %o1, 8, %o1
subcc %g3, 8, %g3 subcc %g3, 8, %g3
faligndata %f0, %f2, %f8 faligndata %f0, %f2, %f8
EX_ST_FP(STORE(std, %f8, %o0)) EX_ST_FP(STORE(std, %f8, %o0), U1_g3_8_fp)
bl,pn %xcc, 95f bl,pn %xcc, 95f
add %o0, 8, %o0 add %o0, 8, %o0
EX_LD_FP(LOAD(ldd, %o1, %f0)) EX_LD_FP(LOAD(ldd, %o1, %f0), U1_g3_0_fp)
add %o1, 8, %o1 add %o1, 8, %o1
subcc %g3, 8, %g3 subcc %g3, 8, %g3
faligndata %f2, %f0, %f8 faligndata %f2, %f0, %f8
EX_ST_FP(STORE(std, %f8, %o0)) EX_ST_FP(STORE(std, %f8, %o0), U1_g3_8_fp)
bge,pt %xcc, 93b bge,pt %xcc, 93b
add %o0, 8, %o0 add %o0, 8, %o0
95: brz,pt %o2, 2f 95: brz,pt %o2, 2f
mov %g1, %o1 mov %g1, %o1
1: EX_LD_FP(LOAD(ldub, %o1, %o3)) 1: EX_LD_FP(LOAD(ldub, %o1, %o3), U1_o2_0_fp)
add %o1, 1, %o1 add %o1, 1, %o1
subcc %o2, 1, %o2 subcc %o2, 1, %o2
EX_ST_FP(STORE(stb, %o3, %o0)) EX_ST_FP(STORE(stb, %o3, %o0), U1_o2_1_fp)
bne,pt %xcc, 1b bne,pt %xcc, 1b
add %o0, 1, %o0 add %o0, 1, %o0
@ -470,27 +583,27 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
72: andn %o2, 0xf, %GLOBAL_SPARE 72: andn %o2, 0xf, %GLOBAL_SPARE
and %o2, 0xf, %o2 and %o2, 0xf, %o2
1: EX_LD(LOAD(ldx, %o1 + 0x00, %o5)) 1: EX_LD(LOAD(ldx, %o1 + 0x00, %o5), U1_gs_0)
EX_LD(LOAD(ldx, %o1 + 0x08, %g1)) EX_LD(LOAD(ldx, %o1 + 0x08, %g1), U1_gs_0)
subcc %GLOBAL_SPARE, 0x10, %GLOBAL_SPARE subcc %GLOBAL_SPARE, 0x10, %GLOBAL_SPARE
EX_ST(STORE(stx, %o5, %o1 + %o3)) EX_ST(STORE(stx, %o5, %o1 + %o3), U1_gs_10)
add %o1, 0x8, %o1 add %o1, 0x8, %o1
EX_ST(STORE(stx, %g1, %o1 + %o3)) EX_ST(STORE(stx, %g1, %o1 + %o3), U1_gs_8)
bgu,pt %XCC, 1b bgu,pt %XCC, 1b
add %o1, 0x8, %o1 add %o1, 0x8, %o1
73: andcc %o2, 0x8, %g0 73: andcc %o2, 0x8, %g0
be,pt %XCC, 1f be,pt %XCC, 1f
nop nop
EX_LD(LOAD(ldx, %o1, %o5)) EX_LD(LOAD(ldx, %o1, %o5), U1_o2_0)
sub %o2, 0x8, %o2 sub %o2, 0x8, %o2
EX_ST(STORE(stx, %o5, %o1 + %o3)) EX_ST(STORE(stx, %o5, %o1 + %o3), U1_o2_8)
add %o1, 0x8, %o1 add %o1, 0x8, %o1
1: andcc %o2, 0x4, %g0 1: andcc %o2, 0x4, %g0
be,pt %XCC, 1f be,pt %XCC, 1f
nop nop
EX_LD(LOAD(lduw, %o1, %o5)) EX_LD(LOAD(lduw, %o1, %o5), U1_o2_0)
sub %o2, 0x4, %o2 sub %o2, 0x4, %o2
EX_ST(STORE(stw, %o5, %o1 + %o3)) EX_ST(STORE(stw, %o5, %o1 + %o3), U1_o2_4)
add %o1, 0x4, %o1 add %o1, 0x4, %o1
1: cmp %o2, 0 1: cmp %o2, 0
be,pt %XCC, 85f be,pt %XCC, 85f
@ -504,9 +617,9 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
sub %g0, %g1, %g1 sub %g0, %g1, %g1
sub %o2, %g1, %o2 sub %o2, %g1, %o2
1: EX_LD(LOAD(ldub, %o1, %o5)) 1: EX_LD(LOAD(ldub, %o1, %o5), U1_g1_0)
subcc %g1, 1, %g1 subcc %g1, 1, %g1
EX_ST(STORE(stb, %o5, %o1 + %o3)) EX_ST(STORE(stb, %o5, %o1 + %o3), U1_g1_1)
bgu,pt %icc, 1b bgu,pt %icc, 1b
add %o1, 1, %o1 add %o1, 1, %o1
@ -522,16 +635,16 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
8: mov 64, %o3 8: mov 64, %o3
andn %o1, 0x7, %o1 andn %o1, 0x7, %o1
EX_LD(LOAD(ldx, %o1, %g2)) EX_LD(LOAD(ldx, %o1, %g2), U1_o2_0)
sub %o3, %g1, %o3 sub %o3, %g1, %o3
andn %o2, 0x7, %GLOBAL_SPARE andn %o2, 0x7, %GLOBAL_SPARE
sllx %g2, %g1, %g2 sllx %g2, %g1, %g2
1: EX_LD(LOAD(ldx, %o1 + 0x8, %g3)) 1: EX_LD(LOAD(ldx, %o1 + 0x8, %g3), U1_gs_0_o2_adj)
subcc %GLOBAL_SPARE, 0x8, %GLOBAL_SPARE subcc %GLOBAL_SPARE, 0x8, %GLOBAL_SPARE
add %o1, 0x8, %o1 add %o1, 0x8, %o1
srlx %g3, %o3, %o5 srlx %g3, %o3, %o5
or %o5, %g2, %o5 or %o5, %g2, %o5
EX_ST(STORE(stx, %o5, %o0)) EX_ST(STORE(stx, %o5, %o0), U1_gs_8_o2_adj)
add %o0, 0x8, %o0 add %o0, 0x8, %o0
bgu,pt %icc, 1b bgu,pt %icc, 1b
sllx %g3, %g1, %g2 sllx %g3, %g1, %g2
@ -549,9 +662,9 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
bne,pn %XCC, 90f bne,pn %XCC, 90f
sub %o0, %o1, %o3 sub %o0, %o1, %o3
1: EX_LD(LOAD(lduw, %o1, %g1)) 1: EX_LD(LOAD(lduw, %o1, %g1), U1_o2_0)
subcc %o2, 4, %o2 subcc %o2, 4, %o2
EX_ST(STORE(stw, %g1, %o1 + %o3)) EX_ST(STORE(stw, %g1, %o1 + %o3), U1_o2_4)
bgu,pt %XCC, 1b bgu,pt %XCC, 1b
add %o1, 4, %o1 add %o1, 4, %o1
@ -559,9 +672,9 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
mov EX_RETVAL(%o4), %o0 mov EX_RETVAL(%o4), %o0
.align 32 .align 32
90: EX_LD(LOAD(ldub, %o1, %g1)) 90: EX_LD(LOAD(ldub, %o1, %g1), U1_o2_0)
subcc %o2, 1, %o2 subcc %o2, 1, %o2
EX_ST(STORE(stb, %g1, %o1 + %o3)) EX_ST(STORE(stb, %g1, %o1 + %o3), U1_o2_1)
bgu,pt %XCC, 90b bgu,pt %XCC, 90b
add %o1, 1, %o1 add %o1, 1, %o1
retl retl

Some files were not shown because too many files have changed in this diff Show More