diff options
Diffstat (limited to 'arch/xtensa')
41 files changed, 311 insertions, 213 deletions
diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig index f61058617ada..f4126cf997a4 100644 --- a/arch/xtensa/Kconfig +++ b/arch/xtensa/Kconfig @@ -15,6 +15,7 @@ config XTENSA select GENERIC_SCHED_CLOCK select HAVE_DEBUG_KMEMLEAK select HAVE_DMA_API_DEBUG + select HAVE_DMA_CONTIGUOUS select HAVE_EXIT_THREAD select HAVE_FUNCTION_TRACER select HAVE_FUTEX_CMPXCHG if !MMU diff --git a/arch/xtensa/Makefile b/arch/xtensa/Makefile index e54189427b31..7ee02fe4a63d 100644 --- a/arch/xtensa/Makefile +++ b/arch/xtensa/Makefile @@ -93,11 +93,7 @@ endif boot := arch/xtensa/boot -all: zImage - -bzImage : zImage - -zImage: vmlinux +all Image zImage uImage: vmlinux $(Q)$(MAKE) $(build)=$(boot) $@ %.dtb: @@ -107,6 +103,8 @@ dtbs: scripts $(Q)$(MAKE) $(build)=$(boot)/dts define archhelp + @echo '* Image - Kernel ELF image with reset vector' @echo '* zImage - Compressed kernel image (arch/xtensa/boot/images/zImage.*)' + @echo '* uImage - U-Boot wrapped image' @echo ' dtbs - Build device tree blobs for enabled boards' endef diff --git a/arch/xtensa/boot/Makefile b/arch/xtensa/boot/Makefile index ca20a892021b..53e4178711e6 100644 --- a/arch/xtensa/boot/Makefile +++ b/arch/xtensa/boot/Makefile @@ -21,14 +21,17 @@ subdir-y := lib # Subdirs for the boot loader(s) -bootdir-$(CONFIG_XTENSA_PLATFORM_ISS) += boot-elf -bootdir-$(CONFIG_XTENSA_PLATFORM_XT2000) += boot-redboot boot-elf boot-uboot -bootdir-$(CONFIG_XTENSA_PLATFORM_XTFPGA) += boot-redboot boot-elf boot-uboot +boot-$(CONFIG_XTENSA_PLATFORM_ISS) += Image +boot-$(CONFIG_XTENSA_PLATFORM_XT2000) += Image zImage uImage +boot-$(CONFIG_XTENSA_PLATFORM_XTFPGA) += Image zImage uImage -zImage Image: $(bootdir-y) +all: $(boot-y) +Image: boot-elf +zImage: boot-redboot +uImage: $(obj)/uImage -$(bootdir-y): $(addprefix $(obj)/,$(subdir-y)) \ - $(addprefix $(obj)/,$(host-progs)) +boot-elf boot-redboot: $(addprefix $(obj)/,$(subdir-y)) \ + $(addprefix $(obj)/,$(host-progs)) $(Q)$(MAKE) $(build)=$(obj)/$@ $(MAKECMDGOALS) OBJCOPYFLAGS = --strip-all -R .comment -R .note.gnu.build-id -O binary @@ -41,4 +44,10 @@ vmlinux.bin.gz: vmlinux.bin FORCE boot-elf: vmlinux.bin boot-redboot: vmlinux.bin.gz -boot-uboot: vmlinux.bin.gz + +UIMAGE_LOADADDR = $(CONFIG_KERNEL_LOAD_ADDRESS) +UIMAGE_COMPRESSION = gzip + +$(obj)/uImage: vmlinux.bin.gz FORCE + $(call if_changed,uimage) + $(Q)$(kecho) ' Kernel: $@ is ready' diff --git a/arch/xtensa/boot/boot-elf/Makefile b/arch/xtensa/boot/boot-elf/Makefile index 89db089f5a12..521471981356 100644 --- a/arch/xtensa/boot/boot-elf/Makefile +++ b/arch/xtensa/boot/boot-elf/Makefile @@ -31,4 +31,4 @@ $(obj)/../Image.elf: $(obj)/Image.o $(obj)/boot.lds -o $@ $(obj)/Image.o $(Q)$(kecho) ' Kernel: $@ is ready' -zImage: $(obj)/../Image.elf +all Image: $(obj)/../Image.elf diff --git a/arch/xtensa/boot/boot-redboot/Makefile b/arch/xtensa/boot/boot-redboot/Makefile index 8be8b9436981..8632473ad319 100644 --- a/arch/xtensa/boot/boot-redboot/Makefile +++ b/arch/xtensa/boot/boot-redboot/Makefile @@ -32,4 +32,4 @@ $(obj)/../zImage.redboot: $(obj)/zImage.elf $(Q)$(OBJCOPY) -S -O binary $< $@ $(Q)$(kecho) ' Kernel: $@ is ready' -zImage: $(obj)/../zImage.redboot +all zImage: $(obj)/../zImage.redboot diff --git a/arch/xtensa/boot/boot-uboot/Makefile b/arch/xtensa/boot/boot-uboot/Makefile deleted file mode 100644 index 0f4c417b4196..000000000000 --- a/arch/xtensa/boot/boot-uboot/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -# -# This file is subject to the terms and conditions of the GNU General Public -# License. See the file "COPYING" in the main directory of this archive -# for more details. -# - -UIMAGE_LOADADDR = $(CONFIG_KERNEL_LOAD_ADDRESS) -UIMAGE_COMPRESSION = gzip - -$(obj)/../uImage: vmlinux.bin.gz FORCE - $(call if_changed,uimage) - $(Q)$(kecho) ' Kernel: $@ is ready' - -zImage: $(obj)/../uImage diff --git a/arch/xtensa/boot/dts/kc705.dts b/arch/xtensa/boot/dts/kc705.dts index b1f4ee8c9a22..6106bdc097ad 100644 --- a/arch/xtensa/boot/dts/kc705.dts +++ b/arch/xtensa/boot/dts/kc705.dts @@ -11,4 +11,20 @@ device_type = "memory"; reg = <0x00000000 0x38000000>; }; + + reserved-memory { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + /* global autoconfigured region for contiguous allocations */ + linux,cma { + compatible = "shared-dma-pool"; + reusable; + size = <0x04000000>; + alignment = <0x2000>; + alloc-ranges = <0x00000000 0x20000000>; + linux,cma-default; + }; + }; }; diff --git a/arch/xtensa/include/asm/Kbuild b/arch/xtensa/include/asm/Kbuild index 28cf4c5d65ef..f41408c53fe1 100644 --- a/arch/xtensa/include/asm/Kbuild +++ b/arch/xtensa/include/asm/Kbuild @@ -1,8 +1,8 @@ generic-y += bitsperlong.h generic-y += bug.h generic-y += clkdev.h -generic-y += cputime.h generic-y += div64.h +generic-y += dma-contiguous.h generic-y += emergency-restart.h generic-y += errno.h generic-y += exec.h @@ -31,3 +31,4 @@ generic-y += topology.h generic-y += trace_clock.h generic-y += word-at-a-time.h generic-y += xor.h +generic-y += kprobes.h diff --git a/arch/xtensa/include/asm/checksum.h b/arch/xtensa/include/asm/checksum.h index ec35074fcb03..3ae74d7e074b 100644 --- a/arch/xtensa/include/asm/checksum.h +++ b/arch/xtensa/include/asm/checksum.h @@ -12,7 +12,7 @@ #define _XTENSA_CHECKSUM_H #include <linux/in6.h> -#include <asm/uaccess.h> +#include <linux/uaccess.h> #include <variant/core.h> /* diff --git a/arch/xtensa/include/asm/device.h b/arch/xtensa/include/asm/device.h index fe1f5c878493..1deeb8ebbb1b 100644 --- a/arch/xtensa/include/asm/device.h +++ b/arch/xtensa/include/asm/device.h @@ -6,11 +6,7 @@ #ifndef _ASM_XTENSA_DEVICE_H #define _ASM_XTENSA_DEVICE_H -struct dma_map_ops; - struct dev_archdata { - /* DMA operations on that device */ - struct dma_map_ops *dma_ops; }; struct pdev_archdata { diff --git a/arch/xtensa/include/asm/dma-mapping.h b/arch/xtensa/include/asm/dma-mapping.h index 3fc1170a6488..c6140fa8c0be 100644 --- a/arch/xtensa/include/asm/dma-mapping.h +++ b/arch/xtensa/include/asm/dma-mapping.h @@ -18,14 +18,11 @@ #define DMA_ERROR_CODE (~(dma_addr_t)0x0) -extern struct dma_map_ops xtensa_dma_map_ops; +extern const struct dma_map_ops xtensa_dma_map_ops; -static inline struct dma_map_ops *get_dma_ops(struct device *dev) +static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus) { - if (dev && dev->archdata.dma_ops) - return dev->archdata.dma_ops; - else - return &xtensa_dma_map_ops; + return &xtensa_dma_map_ops; } void dma_cache_sync(struct device *dev, void *vaddr, size_t size, diff --git a/arch/xtensa/include/asm/mmu_context.h b/arch/xtensa/include/asm/mmu_context.h index 04c8ebdc4517..f7e186dfc4e4 100644 --- a/arch/xtensa/include/asm/mmu_context.h +++ b/arch/xtensa/include/asm/mmu_context.h @@ -17,6 +17,7 @@ #include <linux/stringify.h> #include <linux/sched.h> +#include <linux/mm_types.h> #include <asm/vectors.h> diff --git a/arch/xtensa/include/asm/mutex.h b/arch/xtensa/include/asm/mutex.h deleted file mode 100644 index 458c1f7fbc18..000000000000 --- a/arch/xtensa/include/asm/mutex.h +++ /dev/null @@ -1,9 +0,0 @@ -/* - * Pull in the generic implementation for the mutex fastpath. - * - * TODO: implement optimized primitives instead, or leave the generic - * implementation in place, or pick the atomic_xchg() based generic - * implementation. (see asm-generic/mutex-xchg.h for details) - */ - -#include <asm-generic/mutex-dec.h> diff --git a/arch/xtensa/include/asm/page.h b/arch/xtensa/include/asm/page.h index 976b1d70edbc..4ddbfd57a7c8 100644 --- a/arch/xtensa/include/asm/page.h +++ b/arch/xtensa/include/asm/page.h @@ -164,8 +164,21 @@ void copy_user_highpage(struct page *to, struct page *from, #define ARCH_PFN_OFFSET (PHYS_OFFSET >> PAGE_SHIFT) +#ifdef CONFIG_MMU +static inline unsigned long ___pa(unsigned long va) +{ + unsigned long off = va - PAGE_OFFSET; + + if (off >= XCHAL_KSEG_SIZE) + off -= XCHAL_KSEG_SIZE; + + return off + PHYS_OFFSET; +} +#define __pa(x) ___pa((unsigned long)(x)) +#else #define __pa(x) \ ((unsigned long) (x) - PAGE_OFFSET + PHYS_OFFSET) +#endif #define __va(x) \ ((void *)((unsigned long) (x) - PHYS_OFFSET + PAGE_OFFSET)) #define pfn_valid(pfn) \ diff --git a/arch/xtensa/include/asm/pgtable.h b/arch/xtensa/include/asm/pgtable.h index 8aa0e0d9cbb2..30dd5b2e4ad5 100644 --- a/arch/xtensa/include/asm/pgtable.h +++ b/arch/xtensa/include/asm/pgtable.h @@ -11,6 +11,7 @@ #ifndef _XTENSA_PGTABLE_H #define _XTENSA_PGTABLE_H +#define __ARCH_USE_5LEVEL_HACK #include <asm-generic/pgtable-nopmd.h> #include <asm/page.h> #include <asm/kmem_layout.h> diff --git a/arch/xtensa/include/asm/processor.h b/arch/xtensa/include/asm/processor.h index b42d68bfe3cf..86ffcd68e496 100644 --- a/arch/xtensa/include/asm/processor.h +++ b/arch/xtensa/include/asm/processor.h @@ -206,7 +206,6 @@ extern unsigned long get_wchan(struct task_struct *p); #define KSTK_ESP(tsk) (task_pt_regs(tsk)->areg[1]) #define cpu_relax() barrier() -#define cpu_relax_lowlatency() cpu_relax() /* Special register access. */ diff --git a/arch/xtensa/include/asm/segment.h b/arch/xtensa/include/asm/segment.h index a2eb547a1a75..98964ad15ca2 100644 --- a/arch/xtensa/include/asm/segment.h +++ b/arch/xtensa/include/asm/segment.h @@ -11,6 +11,6 @@ #ifndef _XTENSA_SEGMENT_H #define _XTENSA_SEGMENT_H -#include <asm/uaccess.h> +#include <linux/uaccess.h> #endif /* _XTENSA_SEGEMENT_H */ diff --git a/arch/xtensa/include/asm/vectors.h b/arch/xtensa/include/asm/vectors.h index 77d41cc7a688..65d3da9db19b 100644 --- a/arch/xtensa/include/asm/vectors.h +++ b/arch/xtensa/include/asm/vectors.h @@ -67,7 +67,11 @@ static inline unsigned long xtensa_get_kio_paddr(void) #endif /* CONFIG_MMU */ #define RESET_VECTOR1_VADDR (XCHAL_RESET_VECTOR1_VADDR) +#ifdef CONFIG_VECTORS_OFFSET #define VECBASE_VADDR (KERNELOFFSET - CONFIG_VECTORS_OFFSET) +#else +#define VECBASE_VADDR _vecbase +#endif #if defined(XCHAL_HAVE_VECBASE) && XCHAL_HAVE_VECBASE diff --git a/arch/xtensa/include/uapi/asm/socket.h b/arch/xtensa/include/uapi/asm/socket.h index 81435d995e11..9fdbe1fe0473 100644 --- a/arch/xtensa/include/uapi/asm/socket.h +++ b/arch/xtensa/include/uapi/asm/socket.h @@ -101,4 +101,6 @@ #define SO_CNX_ADVICE 53 +#define SCM_TIMESTAMPING_OPT_STATS 54 + #endif /* _XTENSA_SOCKET_H */ diff --git a/arch/xtensa/include/uapi/asm/unistd.h b/arch/xtensa/include/uapi/asm/unistd.h index cd400af4a6b2..6be7eb27fd29 100644 --- a/arch/xtensa/include/uapi/asm/unistd.h +++ b/arch/xtensa/include/uapi/asm/unistd.h @@ -774,7 +774,10 @@ __SYSCALL(349, sys_pkey_alloc, 2) #define __NR_pkey_free 350 __SYSCALL(350, sys_pkey_free, 1) -#define __NR_syscall_count 351 +#define __NR_statx 351 +__SYSCALL(351, sys_statx, 5) + +#define __NR_syscall_count 352 /* * sysxtensa syscall handler diff --git a/arch/xtensa/kernel/Makefile b/arch/xtensa/kernel/Makefile index c31f5d5afc7d..264fb89c444e 100644 --- a/arch/xtensa/kernel/Makefile +++ b/arch/xtensa/kernel/Makefile @@ -14,6 +14,7 @@ obj-$(CONFIG_FUNCTION_TRACER) += mcount.o obj-$(CONFIG_SMP) += smp.o mxhead.o obj-$(CONFIG_XTENSA_VARIANT_HAVE_PERF_EVENTS) += perf_event.o obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o +obj-$(CONFIG_S32C1I_SELFTEST) += s32c1i_selftest.o AFLAGS_head.o += -mtext-section-literals AFLAGS_mxhead.o += -mtext-section-literals diff --git a/arch/xtensa/kernel/asm-offsets.c b/arch/xtensa/kernel/asm-offsets.c index 8e10e357ee32..bcb5beb81177 100644 --- a/arch/xtensa/kernel/asm-offsets.c +++ b/arch/xtensa/kernel/asm-offsets.c @@ -24,7 +24,7 @@ #include <asm/ptrace.h> #include <asm/traps.h> -#include <asm/uaccess.h> +#include <linux/uaccess.h> int main(void) { diff --git a/arch/xtensa/kernel/irq.c b/arch/xtensa/kernel/irq.c index 4ac3d23161cf..a265edd6ac37 100644 --- a/arch/xtensa/kernel/irq.c +++ b/arch/xtensa/kernel/irq.c @@ -25,7 +25,7 @@ #include <linux/of.h> #include <asm/mxregs.h> -#include <asm/uaccess.h> +#include <linux/uaccess.h> #include <asm/platform.h> DECLARE_PER_CPU(unsigned long, nmi_count); diff --git a/arch/xtensa/kernel/pci-dma.c b/arch/xtensa/kernel/pci-dma.c index 1e68806d6695..cec86a1c2acc 100644 --- a/arch/xtensa/kernel/pci-dma.c +++ b/arch/xtensa/kernel/pci-dma.c @@ -15,6 +15,7 @@ * Joe Taylor <joe@tensilica.com, joetylr@yahoo.com> */ +#include <linux/dma-contiguous.h> #include <linux/gfp.h> #include <linux/highmem.h> #include <linux/mm.h> @@ -146,6 +147,8 @@ static void *xtensa_dma_alloc(struct device *dev, size_t size, { unsigned long ret; unsigned long uncached = 0; + unsigned long count = PAGE_ALIGN(size) >> PAGE_SHIFT; + struct page *page = NULL; /* ignore region speicifiers */ @@ -153,11 +156,19 @@ static void *xtensa_dma_alloc(struct device *dev, size_t size, if (dev == NULL || (dev->coherent_dma_mask < 0xffffffff)) flag |= GFP_DMA; - ret = (unsigned long)__get_free_pages(flag, get_order(size)); - if (ret == 0) + if (gfpflags_allow_blocking(flag)) + page = dma_alloc_from_contiguous(dev, count, get_order(size), + flag); + + if (!page) + page = alloc_pages(flag, get_order(size)); + + if (!page) return NULL; + ret = (unsigned long)page_address(page); + /* We currently don't support coherent memory outside KSEG */ BUG_ON(ret < XCHAL_KSEG_CACHED_VADDR || @@ -170,16 +181,19 @@ static void *xtensa_dma_alloc(struct device *dev, size_t size, return (void *)uncached; } -static void xtensa_dma_free(struct device *hwdev, size_t size, void *vaddr, +static void xtensa_dma_free(struct device *dev, size_t size, void *vaddr, dma_addr_t dma_handle, unsigned long attrs) { unsigned long addr = (unsigned long)vaddr + XCHAL_KSEG_CACHED_VADDR - XCHAL_KSEG_BYPASS_VADDR; + struct page *page = virt_to_page(addr); + unsigned long count = PAGE_ALIGN(size) >> PAGE_SHIFT; BUG_ON(addr < XCHAL_KSEG_CACHED_VADDR || addr > XCHAL_KSEG_CACHED_VADDR + XCHAL_KSEG_SIZE - 1); - free_pages(addr, get_order(size)); + if (!dma_release_from_contiguous(dev, page, count)) + __free_pages(page, get_order(size)); } static dma_addr_t xtensa_map_page(struct device *dev, struct page *page, @@ -189,7 +203,9 @@ static dma_addr_t xtensa_map_page(struct device *dev, struct page *page, { dma_addr_t dma_handle = page_to_phys(page) + offset; - xtensa_sync_single_for_device(dev, dma_handle, size, dir); + if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC)) + xtensa_sync_single_for_device(dev, dma_handle, size, dir); + return dma_handle; } @@ -197,7 +213,8 @@ static void xtensa_unmap_page(struct device *dev, dma_addr_t dma_handle, size_t size, enum dma_data_direction dir, unsigned long attrs) { - xtensa_sync_single_for_cpu(dev, dma_handle, size, dir); + if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC)) + xtensa_sync_single_for_cpu(dev, dma_handle, size, dir); } static int xtensa_map_sg(struct device *dev, struct scatterlist *sg, @@ -233,7 +250,7 @@ int xtensa_dma_mapping_error(struct device *dev, dma_addr_t dma_addr) return 0; } -struct dma_map_ops xtensa_dma_map_ops = { +const struct dma_map_ops xtensa_dma_map_ops = { .alloc = xtensa_dma_alloc, .free = xtensa_dma_free, .map_page = xtensa_map_page, diff --git a/arch/xtensa/kernel/perf_event.c b/arch/xtensa/kernel/perf_event.c index 0fecc8a2c0b5..ff1d81385ed7 100644 --- a/arch/xtensa/kernel/perf_event.c +++ b/arch/xtensa/kernel/perf_event.c @@ -422,7 +422,7 @@ static int __init xtensa_pmu_init(void) int irq = irq_create_mapping(NULL, XCHAL_PROFILING_INTERRUPT); ret = cpuhp_setup_state(CPUHP_AP_PERF_XTENSA_STARTING, - "AP_PERF_XTENSA_STARTING", xtensa_pmu_setup, + "perf/xtensa:starting", xtensa_pmu_setup, NULL); if (ret) { pr_err("xtensa_pmu: failed to register CPU-hotplug.\n"); diff --git a/arch/xtensa/kernel/process.c b/arch/xtensa/kernel/process.c index e0ded48561db..58f96d1230d4 100644 --- a/arch/xtensa/kernel/process.c +++ b/arch/xtensa/kernel/process.c @@ -17,6 +17,9 @@ #include <linux/errno.h> #include <linux/sched.h> +#include <linux/sched/debug.h> +#include <linux/sched/task.h> +#include <linux/sched/task_stack.h> #include <linux/kernel.h> #include <linux/mm.h> #include <linux/smp.h> @@ -35,7 +38,7 @@ #include <linux/rcupdate.h> #include <asm/pgtable.h> -#include <asm/uaccess.h> +#include <linux/uaccess.h> #include <asm/io.h> #include <asm/processor.h> #include <asm/platform.h> diff --git a/arch/xtensa/kernel/ptrace.c b/arch/xtensa/kernel/ptrace.c index a651f3a628ee..e0f583fed06a 100644 --- a/arch/xtensa/kernel/ptrace.c +++ b/arch/xtensa/kernel/ptrace.c @@ -20,6 +20,7 @@ #include <linux/perf_event.h> #include <linux/ptrace.h> #include <linux/sched.h> +#include <linux/sched/task_stack.h> #include <linux/security.h> #include <linux/signal.h> #include <linux/smp.h> @@ -29,7 +30,7 @@ #include <asm/page.h> #include <asm/pgtable.h> #include <asm/ptrace.h> -#include <asm/uaccess.h> +#include <linux/uaccess.h> void user_enable_single_step(struct task_struct *child) diff --git a/arch/xtensa/kernel/s32c1i_selftest.c b/arch/xtensa/kernel/s32c1i_selftest.c new file mode 100644 index 000000000000..07e56e3a9a8b --- /dev/null +++ b/arch/xtensa/kernel/s32c1i_selftest.c @@ -0,0 +1,128 @@ +/* + * S32C1I selftest. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2016 Cadence Design Systems Inc. + */ + +#include <linux/init.h> +#include <linux/kernel.h> + +#include <asm/traps.h> + +#if XCHAL_HAVE_S32C1I + +static int __initdata rcw_word, rcw_probe_pc, rcw_exc; + +/* + * Basic atomic compare-and-swap, that records PC of S32C1I for probing. + * + * If *v == cmp, set *v = set. Return previous *v. + */ +static inline int probed_compare_swap(int *v, int cmp, int set) +{ + int tmp; + + __asm__ __volatile__( + " movi %1, 1f\n" + " s32i %1, %4, 0\n" + " wsr %2, scompare1\n" + "1: s32c1i %0, %3, 0\n" + : "=a" (set), "=&a" (tmp) + : "a" (cmp), "a" (v), "a" (&rcw_probe_pc), "0" (set) + : "memory" + ); + return set; +} + +/* Handle probed exception */ + +static void __init do_probed_exception(struct pt_regs *regs, + unsigned long exccause) +{ + if (regs->pc == rcw_probe_pc) { /* exception on s32c1i ? */ + regs->pc += 3; /* skip the s32c1i instruction */ + rcw_exc = exccause; + } else { + do_unhandled(regs, exccause); + } +} + +/* Simple test of S32C1I (soc bringup assist) */ + +static int __init check_s32c1i(void) +{ + int n, cause1, cause2; + void *handbus, *handdata, *handaddr; /* temporarily saved handlers */ + + rcw_probe_pc = 0; + handbus = trap_set_handler(EXCCAUSE_LOAD_STORE_ERROR, + do_probed_exception); + handdata = trap_set_handler(EXCCAUSE_LOAD_STORE_DATA_ERROR, + do_probed_exception); + handaddr = trap_set_handler(EXCCAUSE_LOAD_STORE_ADDR_ERROR, + do_probed_exception); + + /* First try an S32C1I that does not store: */ + rcw_exc = 0; + rcw_word = 1; + n = probed_compare_swap(&rcw_word, 0, 2); + cause1 = rcw_exc; + + /* took exception? */ + if (cause1 != 0) { + /* unclean exception? */ + if (n != 2 || rcw_word != 1) + panic("S32C1I exception error"); + } else if (rcw_word != 1 || n != 1) { + panic("S32C1I compare error"); + } + + /* Then an S32C1I that stores: */ + rcw_exc = 0; + rcw_word = 0x1234567; + n = probed_compare_swap(&rcw_word, 0x1234567, 0xabcde); + cause2 = rcw_exc; + + if (cause2 != 0) { + /* unclean exception? */ + if (n != 0xabcde || rcw_word != 0x1234567) + panic("S32C1I exception error (b)"); + } else if (rcw_word != 0xabcde || n != 0x1234567) { + panic("S32C1I store error"); + } + + /* Verify consistency of exceptions: */ + if (cause1 || cause2) { + pr_warn("S32C1I took exception %d, %d\n", cause1, cause2); + /* If emulation of S32C1I upon bus error gets implemented, + * we can get rid of this panic for single core (not SMP) + */ + panic("S32C1I exceptions not currently supported"); + } + if (cause1 != cause2) + panic("inconsistent S32C1I exceptions"); + + trap_set_handler(EXCCAUSE_LOAD_STORE_ERROR, handbus); + trap_set_handler(EXCCAUSE_LOAD_STORE_DATA_ERROR, handdata); + trap_set_handler(EXCCAUSE_LOAD_STORE_ADDR_ERROR, handaddr); + return 0; +} + +#else /* XCHAL_HAVE_S32C1I */ + +/* This condition should not occur with a commercially deployed processor. + * Display reminder for early engr test or demo chips / FPGA bitstreams + */ +static int __init check_s32c1i(void) +{ + pr_warn("Processor configuration lacks atomic compare-and-swap support!\n"); + return 0; +} + +#endif /* XCHAL_HAVE_S32C1I */ + +early_initcall(check_s32c1i); diff --git a/arch/xtensa/kernel/setup.c b/arch/xtensa/kernel/setup.c index 88a044af7504..197e75b400b1 100644 --- a/arch/xtensa/kernel/setup.c +++ b/arch/xtensa/kernel/setup.c @@ -31,10 +31,6 @@ # include <linux/console.h> #endif -#ifdef CONFIG_RTC -# include <linux/timex.h> -#endif - #ifdef CONFIG_PROC_FS # include <linux/seq_file.h> #endif @@ -48,24 +44,22 @@ #include <asm/page.h> #include <asm/setup.h> #include <asm/param.h> -#include <asm/traps.h> #include <asm/smp.h> #include <asm/sysmem.h> #include <platform/hardware.h> #if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE) -struct screen_info screen_info = { 0, 24, 0, 0, 0, 80, 0, 0, 0, 24, 1, 16}; -#endif - -#ifdef CONFIG_BLK_DEV_FD -extern struct fd_ops no_fd_ops; -struct fd_ops *fd_ops; +struct screen_info screen_info = { + .orig_x = 0, + .orig_y = 24, + .orig_video_cols = 80, + .orig_video_lines = 24, + .orig_video_isVGA = 1, + .orig_video_points = 16, +}; #endif -extern struct rtc_ops no_rtc_ops; -struct rtc_ops *rtc_ops; - #ifdef CONFIG_BLK_DEV_INITRD extern unsigned long initrd_start; extern unsigned long initrd_end; @@ -77,7 +71,6 @@ extern int initrd_below_start_ok; void *dtb_start = __dtb_start; #endif -unsigned char aux_device_present; extern unsigned long loops_per_jiffy; /* Command line specified as configuration option. */ @@ -133,6 +126,8 @@ static int __init parse_tag_initrd(const bp_tag_t* tag) __tagtable(BP_TAG_INITRD, parse_tag_initrd); +#endif /* CONFIG_BLK_DEV_INITRD */ + #ifdef CONFIG_OF static int __init parse_tag_fdt(const bp_tag_t *tag) @@ -145,8 +140,6 @@ __tagtable(BP_TAG_FDT, parse_tag_fdt); #endif /* CONFIG_OF */ -#endif /* CONFIG_BLK_DEV_INITRD */ - static int __init parse_tag_cmdline(const bp_tag_t* tag) { strlcpy(command_line, (char *)(tag->data), COMMAND_LINE_SIZE); @@ -317,120 +310,6 @@ extern char _SecondaryResetVector_text_start; extern char _SecondaryResetVector_text_end; #endif - -#ifdef CONFIG_S32C1I_SELFTEST -#if XCHAL_HAVE_S32C1I - -static int __initdata rcw_word, rcw_probe_pc, rcw_exc; - -/* - * Basic atomic compare-and-swap, that records PC of S32C1I for probing. - * - * If *v == cmp, set *v = set. Return previous *v. - */ -static inline int probed_compare_swap(int *v, int cmp, int set) -{ - int tmp; - - __asm__ __volatile__( - " movi %1, 1f\n" - " s32i %1, %4, 0\n" - " wsr %2, scompare1\n" - "1: s32c1i %0, %3, 0\n" - : "=a" (set), "=&a" (tmp) - : "a" (cmp), "a" (v), "a" (&rcw_probe_pc), "0" (set) - : "memory" - ); - return set; -} - -/* Handle probed exception */ - -static void __init do_probed_exception(struct pt_regs *regs, - unsigned long exccause) -{ - if (regs->pc == rcw_probe_pc) { /* exception on s32c1i ? */ - regs->pc += 3; /* skip the s32c1i instruction */ - rcw_exc = exccause; - } else { - do_unhandled(regs, exccause); - } -} - -/* Simple test of S32C1I (soc bringup assist) */ - -static int __init check_s32c1i(void) -{ - int n, cause1, cause2; - void *handbus, *handdata, *handaddr; /* temporarily saved handlers */ - - rcw_probe_pc = 0; - handbus = trap_set_handler(EXCCAUSE_LOAD_STORE_ERROR, - do_probed_exception); - handdata = trap_set_handler(EXCCAUSE_LOAD_STORE_DATA_ERROR, - do_probed_exception); - handaddr = trap_set_handler(EXCCAUSE_LOAD_STORE_ADDR_ERROR, - do_probed_exception); - - /* First try an S32C1I that does not store: */ - rcw_exc = 0; - rcw_word = 1; - n = probed_compare_swap(&rcw_word, 0, 2); - cause1 = rcw_exc; - - /* took exception? */ - if (cause1 != 0) { - /* unclean exception? */ - if (n != 2 || rcw_word != 1) - panic("S32C1I exception error"); - } else if (rcw_word != 1 || n != 1) { - panic("S32C1I compare error"); - } - - /* Then an S32C1I that stores: */ - rcw_exc = 0; - rcw_word = 0x1234567; - n = probed_compare_swap(&rcw_word, 0x1234567, 0xabcde); - cause2 = rcw_exc; - - if (cause2 != 0) { - /* unclean exception? */ - if (n != 0xabcde || rcw_word != 0x1234567) - panic("S32C1I exception error (b)"); - } else if (rcw_word != 0xabcde || n != 0x1234567) { - panic("S32C1I store error"); - } - - /* Verify consistency of exceptions: */ - if (cause1 || cause2) { - pr_warn("S32C1I took exception %d, %d\n", cause1, cause2); - /* If emulation of S32C1I upon bus error gets implemented, - we can get rid of this panic for single core (not SMP) */ - panic("S32C1I exceptions not currently supported"); - } - if (cause1 != cause2) - panic("inconsistent S32C1I exceptions"); - - trap_set_handler(EXCCAUSE_LOAD_STORE_ERROR, handbus); - trap_set_handler(EXCCAUSE_LOAD_STORE_DATA_ERROR, handdata); - trap_set_handler(EXCCAUSE_LOAD_STORE_ADDR_ERROR, handaddr); - return 0; -} - -#else /* XCHAL_HAVE_S32C1I */ - -/* This condition should not occur with a commercially deployed processor. - Display reminder for early engr test or demo chips / FPGA bitstreams */ -static int __init check_s32c1i(void) -{ - pr_warn("Processor configuration lacks atomic compare-and-swap support!\n"); - return 0; -} - -#endif /* XCHAL_HAVE_S32C1I */ -early_initcall(check_s32c1i); -#endif /* CONFIG_S32C1I_SELFTEST */ - static inline int mem_reserve(unsigned long start, unsigned long end) { return memblock_reserve(start, end - start); @@ -455,6 +334,7 @@ void __init setup_arch(char **cmdline_p) mem_reserve(__pa(&_stext), __pa(&_end)); +#ifdef CONFIG_VECTORS_OFFSET mem_reserve(__pa(&_WindowVectors_text_start), __pa(&_WindowVectors_text_end)); @@ -491,6 +371,8 @@ void __init setup_arch(char **cmdline_p) __pa(&_Level6InterruptVector_text_end)); #endif +#endif /* CONFIG_VECTORS_OFFSET */ + #ifdef CONFIG_SMP mem_reserve(__pa(&_SecondaryResetVector_text_start), __pa(&_SecondaryResetVector_text_end)); @@ -540,7 +422,7 @@ subsys_initcall(topology_init); void cpu_reset(void) { -#if XCHAL_HAVE_PTP_MMU +#if XCHAL_HAVE_PTP_MMU && IS_ENABLED(CONFIG_MMU) local_irq_disable(); /* * We have full MMU: all autoload ways, ways 7, 8 and 9 of DTLB must diff --git a/arch/xtensa/kernel/signal.c b/arch/xtensa/kernel/signal.c index e87adaa07ff3..70a131945443 100644 --- a/arch/xtensa/kernel/signal.c +++ b/arch/xtensa/kernel/signal.c @@ -20,9 +20,10 @@ #include <linux/ptrace.h> #include <linux/personality.h> #include <linux/tracehook.h> +#include <linux/sched/task_stack.h> #include <asm/ucontext.h> -#include <asm/uaccess.h> +#include <linux/uaccess.h> #include <asm/cacheflush.h> #include <asm/coprocessor.h> #include <asm/unistd.h> diff --git a/arch/xtensa/kernel/smp.c b/arch/xtensa/kernel/smp.c index fc4ad21a5ed4..932d64689bac 100644 --- a/arch/xtensa/kernel/smp.c +++ b/arch/xtensa/kernel/smp.c @@ -21,6 +21,9 @@ #include <linux/irq.h> #include <linux/kdebug.h> #include <linux/module.h> +#include <linux/sched/mm.h> +#include <linux/sched/hotplug.h> +#include <linux/sched/task_stack.h> #include <linux/reboot.h> #include <linux/seq_file.h> #include <linux/smp.h> @@ -135,8 +138,8 @@ void secondary_start_kernel(void) /* All kernel threads share the same mm context. */ - atomic_inc(&mm->mm_users); - atomic_inc(&mm->mm_count); + mmget(mm); + mmgrab(mm); current->active_mm = mm; cpumask_set_cpu(cpu, mm_cpumask(mm)); enter_lazy_tlb(mm, current); diff --git a/arch/xtensa/kernel/stacktrace.c b/arch/xtensa/kernel/stacktrace.c index 7538d802b65a..e7d30ee0fd48 100644 --- a/arch/xtensa/kernel/stacktrace.c +++ b/arch/xtensa/kernel/stacktrace.c @@ -14,7 +14,7 @@ #include <asm/stacktrace.h> #include <asm/traps.h> -#include <asm/uaccess.h> +#include <linux/uaccess.h> #if IS_ENABLED(CONFIG_OPROFILE) || IS_ENABLED(CONFIG_PERF_EVENTS) diff --git a/arch/xtensa/kernel/syscall.c b/arch/xtensa/kernel/syscall.c index 83cf49685373..06937928cb72 100644 --- a/arch/xtensa/kernel/syscall.c +++ b/arch/xtensa/kernel/syscall.c @@ -15,7 +15,7 @@ * Kevin Chea * */ -#include <asm/uaccess.h> +#include <linux/uaccess.h> #include <asm/syscall.h> #include <asm/unistd.h> #include <linux/linkage.h> @@ -25,6 +25,7 @@ #include <linux/file.h> #include <linux/fs.h> #include <linux/mman.h> +#include <linux/sched/mm.h> #include <linux/shm.h> typedef void (*syscall_t)(void); diff --git a/arch/xtensa/kernel/time.c b/arch/xtensa/kernel/time.c index be81e69b25bc..668c1056f9e4 100644 --- a/arch/xtensa/kernel/time.c +++ b/arch/xtensa/kernel/time.c @@ -34,9 +34,9 @@ unsigned long ccount_freq; /* ccount Hz */ EXPORT_SYMBOL(ccount_freq); -static cycle_t ccount_read(struct clocksource *cs) +static u64 ccount_read(struct clocksource *cs) { - return (cycle_t)get_ccount(); + return (u64)get_ccount(); } static u64 notrace ccount_sched_clock_read(void) diff --git a/arch/xtensa/kernel/traps.c b/arch/xtensa/kernel/traps.c index ce37d5b899fe..bae697a06a98 100644 --- a/arch/xtensa/kernel/traps.c +++ b/arch/xtensa/kernel/traps.c @@ -24,7 +24,9 @@ */ #include <linux/kernel.h> -#include <linux/sched.h> +#include <linux/sched/signal.h> +#include <linux/sched/debug.h> +#include <linux/sched/task_stack.h> #include <linux/init.h> #include <linux/module.h> #include <linux/stringify.h> @@ -35,7 +37,7 @@ #include <asm/stacktrace.h> #include <asm/ptrace.h> #include <asm/timex.h> -#include <asm/uaccess.h> +#include <linux/uaccess.h> #include <asm/pgtable.h> #include <asm/processor.h> #include <asm/traps.h> @@ -481,10 +483,8 @@ void show_regs(struct pt_regs * regs) static int show_trace_cb(struct stackframe *frame, void *data) { - if (kernel_text_address(frame->pc)) { - pr_cont(" [<%08lx>]", frame->pc); - print_symbol(" %s\n", frame->pc); - } + if (kernel_text_address(frame->pc)) + pr_cont(" [<%08lx>] %pB\n", frame->pc, (void *)frame->pc); return 0; } diff --git a/arch/xtensa/kernel/vmlinux.lds.S b/arch/xtensa/kernel/vmlinux.lds.S index 31411fc82662..30d9fc21e076 100644 --- a/arch/xtensa/kernel/vmlinux.lds.S +++ b/arch/xtensa/kernel/vmlinux.lds.S @@ -59,6 +59,7 @@ jiffies = jiffies_64; * garbage.) */ +#ifdef CONFIG_VECTORS_OFFSET #define SECTION_VECTOR(sym, section, addr, max_prevsec_size, prevsec) \ section addr : AT((MIN(LOADADDR(prevsec) + max_prevsec_size, \ LOADADDR(prevsec) + SIZEOF(prevsec)) + 3) & ~ 3) \ @@ -68,6 +69,11 @@ jiffies = jiffies_64; *(section) \ sym ## _end = ABSOLUTE(.); \ } +#else +#define SECTION_VECTOR(section, addr) \ + . = addr; \ + *(section) +#endif /* * Mapping of input sections to output sections when linking. @@ -85,6 +91,37 @@ SECTIONS { /* The HEAD_TEXT section must be the first section! */ HEAD_TEXT + +#ifndef CONFIG_VECTORS_OFFSET + . = ALIGN(PAGE_SIZE); + _vecbase = .; + + SECTION_VECTOR (.WindowVectors.text, WINDOW_VECTORS_VADDR) +#if XCHAL_EXCM_LEVEL >= 2 + SECTION_VECTOR (.Level2InterruptVector.text, INTLEVEL2_VECTOR_VADDR) +#endif +#if XCHAL_EXCM_LEVEL >= 3 + SECTION_VECTOR (.Level3InterruptVector.text, INTLEVEL3_VECTOR_VADDR) +#endif +#if XCHAL_EXCM_LEVEL >= 4 + SECTION_VECTOR (.Level4InterruptVector.text, INTLEVEL4_VECTOR_VADDR) +#endif +#if XCHAL_EXCM_LEVEL >= 5 + SECTION_VECTOR (.Level5InterruptVector.text, INTLEVEL5_VECTOR_VADDR) +#endif +#if XCHAL_EXCM_LEVEL >= 6 + SECTION_VECTOR (.Level6InterruptVector.text, INTLEVEL6_VECTOR_VADDR) +#endif + SECTION_VECTOR (.DebugInterruptVector.literal, DEBUG_VECTOR_VADDR - 4) + SECTION_VECTOR (.DebugInterruptVector.text, DEBUG_VECTOR_VADDR) + SECTION_VECTOR (.KernelExceptionVector.literal, KERNEL_VECTOR_VADDR - 4) + SECTION_VECTOR (.KernelExceptionVector.text, KERNEL_VECTOR_VADDR) + SECTION_VECTOR (.UserExceptionVector.literal, USER_VECTOR_VADDR - 4) + SECTION_VECTOR (.UserExceptionVector.text, USER_VECTOR_VADDR) + SECTION_VECTOR (.DoubleExceptionVector.literal, DOUBLEEXC_VECTOR_VADDR - 48) + SECTION_VECTOR (.DoubleExceptionVector.text, DOUBLEEXC_VECTOR_VADDR) +#endif + TEXT_TEXT VMLINUX_SYMBOL(__sched_text_start) = .; *(.sched.literal .sched.text) @@ -132,6 +169,7 @@ SECTIONS . = ALIGN(16); __boot_reloc_table_start = ABSOLUTE(.); +#ifdef CONFIG_VECTORS_OFFSET RELOCATE_ENTRY(_WindowVectors_text, .WindowVectors.text); #if XCHAL_EXCM_LEVEL >= 2 @@ -164,6 +202,7 @@ SECTIONS .DoubleExceptionVector.text); RELOCATE_ENTRY(_DebugInterruptVector_text, .DebugInterruptVector.text); +#endif #if defined(CONFIG_SMP) RELOCATE_ENTRY(_SecondaryResetVector_text, .SecondaryResetVector.text); @@ -186,6 +225,7 @@ SECTIONS . = ALIGN(4); .dummy : { LONG(0) } +#ifdef CONFIG_VECTORS_OFFSET /* The vectors are relocated to the real position at startup time */ SECTION_VECTOR (_WindowVectors_text, @@ -277,6 +317,7 @@ SECTIONS . = (LOADADDR( .DoubleExceptionVector.text ) + SIZEOF( .DoubleExceptionVector.text ) + 3) & ~ 3; +#endif #if defined(CONFIG_SMP) SECTION_VECTOR (_SecondaryResetVector_text, diff --git a/arch/xtensa/kernel/xtensa_ksyms.c b/arch/xtensa/kernel/xtensa_ksyms.c index 4d2872fd9bb5..d159e9b9c018 100644 --- a/arch/xtensa/kernel/xtensa_ksyms.c +++ b/arch/xtensa/kernel/xtensa_ksyms.c @@ -19,7 +19,7 @@ #include <asm/irq.h> #include <linux/in6.h> -#include <asm/uaccess.h> +#include <linux/uaccess.h> #include <asm/cacheflush.h> #include <asm/checksum.h> #include <asm/dma.h> diff --git a/arch/xtensa/mm/fault.c b/arch/xtensa/mm/fault.c index 2725e08ef353..a14df5aa98c8 100644 --- a/arch/xtensa/mm/fault.c +++ b/arch/xtensa/mm/fault.c @@ -13,7 +13,7 @@ */ #include <linux/mm.h> -#include <linux/module.h> +#include <linux/extable.h> #include <linux/hardirq.h> #include <linux/perf_event.h> #include <linux/uaccess.h> diff --git a/arch/xtensa/mm/init.c b/arch/xtensa/mm/init.c index 80e4cfb2471a..720fe4e8b497 100644 --- a/arch/xtensa/mm/init.c +++ b/arch/xtensa/mm/init.c @@ -26,6 +26,7 @@ #include <linux/nodemask.h> #include <linux/mm.h> #include <linux/of_fdt.h> +#include <linux/dma-contiguous.h> #include <asm/bootparam.h> #include <asm/page.h> @@ -60,6 +61,7 @@ void __init bootmem_init(void) max_low_pfn = min(max_pfn, MAX_LOW_PFN); memblock_set_current_limit(PFN_PHYS(max_low_pfn)); + dma_contiguous_reserve(PFN_PHYS(max_low_pfn)); memblock_dump_all(); } diff --git a/arch/xtensa/platforms/iss/console.c b/arch/xtensa/platforms/iss/console.c index c68f1e6158aa..0140a22551c8 100644 --- a/arch/xtensa/platforms/iss/console.c +++ b/arch/xtensa/platforms/iss/console.c @@ -20,7 +20,7 @@ #include <linux/seq_file.h> #include <linux/serial.h> -#include <asm/uaccess.h> +#include <linux/uaccess.h> #include <asm/irq.h> #include <platform/simcall.h> diff --git a/arch/xtensa/platforms/iss/simdisk.c b/arch/xtensa/platforms/iss/simdisk.c index ede04cca30dd..02e94bb3ad3e 100644 --- a/arch/xtensa/platforms/iss/simdisk.c +++ b/arch/xtensa/platforms/iss/simdisk.c @@ -17,7 +17,7 @@ #include <linux/blkdev.h> #include <linux/bio.h> #include <linux/proc_fs.h> -#include <asm/uaccess.h> +#include <linux/uaccess.h> #include <platform/simcall.h> #define SIMDISK_MAJOR 240 |