diff options
Diffstat (limited to 'arch/arc')
54 files changed, 482 insertions, 258 deletions
diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig index 283099c9560a..a5459698f0ee 100644 --- a/arch/arc/Kconfig +++ b/arch/arc/Kconfig @@ -180,16 +180,12 @@ config CPU_BIG_ENDIAN config SMP bool "Symmetric Multi-Processing" default n - select ARC_HAS_COH_CACHES if ISA_ARCV2 select ARC_MCIP if ISA_ARCV2 help This enables support for systems with more than one CPU. if SMP -config ARC_HAS_COH_CACHES - def_bool n - config NR_CPUS int "Maximum number of CPUs (2-4096)" range 2 4096 @@ -219,8 +215,6 @@ config ARC_MCIP menuconfig ARC_CACHE bool "Enable Cache Support" default y - # if SMP, cache enabled ONLY if ARC implementation has cache coherency - depends on !SMP || ARC_HAS_COH_CACHES if ARC_CACHE @@ -412,16 +406,13 @@ config ARC_HAS_DIV_REM bool "Insn: div, divu, rem, remu" default y -config ARC_NUMBER_OF_INTERRUPTS - int "Number of interrupts" - range 8 240 - default 32 +config ARC_HAS_ACCL_REGS + bool "Reg Pair ACCL:ACCH (FPU and/or MPY > 6)" + default n help - This defines the number of interrupts on the ARCv2HS core. - It affects the size of vector table. - The initial 8 IRQs are fixed (Timer, ICI etc) and although configurable - in hardware, it keep things simple for Linux to assume they are always - present. + Depending on the configuration, CPU can contain accumulator reg-pair + (also referred to as r58:r59). These can also be used by gcc as GPR so + kernel needs to save/restore per process endif # ISA_ARCV2 @@ -453,6 +444,7 @@ config ARC_HAS_PAE40 bool "Support for the 40-bit Physical Address Extension" default n depends on ISA_ARCV2 + select HIGHMEM help Enable access to physical memory beyond 4G, only supported on ARC cores with 40 bit Physical Addressing support diff --git a/arch/arc/Makefile b/arch/arc/Makefile index 19cce226d1a8..44ef35d33956 100644 --- a/arch/arc/Makefile +++ b/arch/arc/Makefile @@ -123,9 +123,9 @@ libs-y += arch/arc/lib/ $(LIBGCC) boot := arch/arc/boot #default target for make without any arguments. -KBUILD_IMAGE := bootpImage +KBUILD_IMAGE := $(boot)/bootpImage -all: $(KBUILD_IMAGE) +all: bootpImage bootpImage: vmlinux boot_targets += uImage uImage.bin uImage.gz diff --git a/arch/arc/boot/dts/axc003_idu.dtsi b/arch/arc/boot/dts/axc003_idu.dtsi index 3d6cfa32bf51..695f9fa1996b 100644 --- a/arch/arc/boot/dts/axc003_idu.dtsi +++ b/arch/arc/boot/dts/axc003_idu.dtsi @@ -40,18 +40,7 @@ compatible = "snps,archs-idu-intc"; interrupt-controller; interrupt-parent = <&core_intc>; - - /* - * <hwirq distribution> - * distribution: 0=RR; 1=cpu0, 2=cpu1, 4=cpu2, 8=cpu3 - */ - #interrupt-cells = <2>; - - /* - * upstream irqs to core intc - downstream these are - * "COMMON" irq 0,1.. - */ - interrupts = <24 25>; + #interrupt-cells = <1>; }; /* @@ -73,12 +62,7 @@ interrupt-controller; #interrupt-cells = <2>; interrupt-parent = <&idu_intc>; - - /* - * cmn irq 1 -> cpu irq 25 - * Distribute to cpu0 only - */ - interrupts = <1 1>; + interrupts = <1>; }; }; @@ -119,8 +103,7 @@ reg = < 0xe0012000 0x200 >; interrupt-controller; interrupt-parent = <&idu_intc>; - interrupts = <0 1>; /* cmn irq 0 -> cpu irq 24 - distribute to cpu0 only */ + interrupts = <0>; }; memory { diff --git a/arch/arc/boot/dts/axs10x_mb.dtsi b/arch/arc/boot/dts/axs10x_mb.dtsi index d6c1bbc98ac3..41cfb29b62c1 100644 --- a/arch/arc/boot/dts/axs10x_mb.dtsi +++ b/arch/arc/boot/dts/axs10x_mb.dtsi @@ -51,7 +51,7 @@ pguclk: pguclk { #clock-cells = <0>; compatible = "fixed-clock"; - clock-frequency = <74440000>; + clock-frequency = <74250000>; }; }; @@ -149,12 +149,13 @@ interrupts = <14>; }; - i2c@0x1e000 { - compatible = "snps,designware-i2c"; + i2s: i2s@1e000 { + compatible = "snps,designware-i2s"; reg = <0x1e000 0x100>; - clock-frequency = <400000>; - clocks = <&i2cclk>; + clocks = <&i2sclk 0>; + clock-names = "i2sclk"; interrupts = <15>; + #sound-dai-cells = <0>; }; i2c@0x1f000 { @@ -174,6 +175,7 @@ adi,input-colorspace = "rgb"; adi,input-clock = "1x"; adi,clock-delay = <0x03>; + #sound-dai-cells = <0>; ports { #address-cells = <1>; @@ -295,5 +297,17 @@ }; }; }; + + sound_playback { + compatible = "simple-audio-card"; + simple-audio-card,name = "AXS10x HDMI Audio"; + simple-audio-card,format = "i2s"; + simple-audio-card,cpu { + sound-dai = <&i2s>; + }; + simple-audio-card,codec { + sound-dai = <&adv7511>; + }; + }; }; }; diff --git a/arch/arc/boot/dts/haps_hs_idu.dts b/arch/arc/boot/dts/haps_hs_idu.dts index 65204b4c0f13..215cddd0b63b 100644 --- a/arch/arc/boot/dts/haps_hs_idu.dts +++ b/arch/arc/boot/dts/haps_hs_idu.dts @@ -47,18 +47,13 @@ compatible = "snps,archs-intc"; interrupt-controller; #interrupt-cells = <1>; -/* interrupts = <16 17 18 19 20 21 22 23 24 25>; */ }; idu_intc: idu-interrupt-controller { compatible = "snps,archs-idu-intc"; interrupt-controller; interrupt-parent = <&core_intc>; - /* <hwirq distribution> - distribution: 0=RR; 1=cpu0, 2=cpu1, 4=cpu2, 8=cpu3 */ - #interrupt-cells = <2>; - interrupts = <24 25 26 27 28 29 30 31>; - + #interrupt-cells = <1>; }; uart0: serial@f0000000 { @@ -66,9 +61,7 @@ compatible = "ns16550a"; reg = <0xf0000000 0x2000>; interrupt-parent = <&idu_intc>; - /* interrupts = <0 1>; DEST=1*/ - /* interrupts = <0 2>; DEST=2*/ - interrupts = <0 0>; /* RR*/ + interrupts = <0>; clock-frequency = <50000000>; baud = <115200>; reg-shift = <2>; diff --git a/arch/arc/boot/dts/nsim_hs_idu.dts b/arch/arc/boot/dts/nsim_hs_idu.dts index 48434d7c4498..4f98ebf71fd8 100644 --- a/arch/arc/boot/dts/nsim_hs_idu.dts +++ b/arch/arc/boot/dts/nsim_hs_idu.dts @@ -46,25 +46,14 @@ compatible = "snps,archs-idu-intc"; interrupt-controller; interrupt-parent = <&core_intc>; - - /* - * <hwirq distribution> - * distribution: 0=RR; 1=cpu0, 2=cpu1, 4=cpu2, 8=cpu3 - */ - #interrupt-cells = <2>; - - /* - * upstream irqs to core intc - downstream these are - * "COMMON" irq 0,1.. - */ - interrupts = <24 25 26 27 28 29 30 31>; + #interrupt-cells = <1>; }; arcuart0: serial@c0fc1000 { compatible = "snps,arc-uart"; reg = <0xc0fc1000 0x100>; interrupt-parent = <&idu_intc>; - interrupts = <0 0>; + interrupts = <0>; clock-frequency = <80000000>; current-speed = <115200>; status = "okay"; diff --git a/arch/arc/boot/dts/nsimosci_hs_idu.dts b/arch/arc/boot/dts/nsimosci_hs_idu.dts index cbf65b6cc7c6..5052917d4a99 100644 --- a/arch/arc/boot/dts/nsimosci_hs_idu.dts +++ b/arch/arc/boot/dts/nsimosci_hs_idu.dts @@ -43,33 +43,20 @@ compatible = "snps,archs-intc"; interrupt-controller; #interrupt-cells = <1>; -/* interrupts = <16 17 18 19 20 21 22 23 24 25>; */ }; idu_intc: idu-interrupt-controller { compatible = "snps,archs-idu-intc"; interrupt-controller; interrupt-parent = <&core_intc>; - - /* - * <hwirq distribution> - * distribution: 0=RR; 1=cpu0, 2=cpu1, 4=cpu2, 8=cpu3 - */ - #interrupt-cells = <2>; - - /* - * upstream irqs to core intc - downstream these are - * "COMMON" irq 0,1.. - */ - interrupts = <24 25 26 27 28 29 30 31>; + #interrupt-cells = <1>; }; uart0: serial@f0000000 { compatible = "ns8250"; reg = <0xf0000000 0x2000>; interrupt-parent = <&idu_intc>; - interrupts = <0 0>; /* cmn irq 0 -> cpu irq 24 - RR distribute to all cpus */ + interrupts = <0>; clock-frequency = <3686400>; baud = <115200>; reg-shift = <2>; @@ -93,7 +80,7 @@ ps2: ps2@f9001000 { compatible = "snps,arc_ps2"; reg = <0xf9000400 0x14>; - interrupts = <3 0>; + interrupts = <3>; interrupt-parent = <&idu_intc>; interrupt-names = "arc_ps2_irq"; }; @@ -102,7 +89,7 @@ compatible = "ezchip,nps-mgt-enet"; reg = <0xf0003000 0x44>; interrupt-parent = <&idu_intc>; - interrupts = <1 2>; + interrupts = <1>; }; arcpct0: pct { diff --git a/arch/arc/boot/dts/skeleton.dtsi b/arch/arc/boot/dts/skeleton.dtsi index 65808fe0a290..2891cb266cf0 100644 --- a/arch/arc/boot/dts/skeleton.dtsi +++ b/arch/arc/boot/dts/skeleton.dtsi @@ -26,6 +26,7 @@ device_type = "cpu"; compatible = "snps,arc770d"; reg = <0>; + clocks = <&core_clk>; }; }; diff --git a/arch/arc/boot/dts/skeleton_hs.dtsi b/arch/arc/boot/dts/skeleton_hs.dtsi index 2dfe8037dfbb..5e944d3e5b74 100644 --- a/arch/arc/boot/dts/skeleton_hs.dtsi +++ b/arch/arc/boot/dts/skeleton_hs.dtsi @@ -21,6 +21,7 @@ device_type = "cpu"; compatible = "snps,archs38"; reg = <0>; + clocks = <&core_clk>; }; }; diff --git a/arch/arc/boot/dts/skeleton_hs_idu.dtsi b/arch/arc/boot/dts/skeleton_hs_idu.dtsi index 4c11079f3565..54b277d7dea0 100644 --- a/arch/arc/boot/dts/skeleton_hs_idu.dtsi +++ b/arch/arc/boot/dts/skeleton_hs_idu.dtsi @@ -19,8 +19,27 @@ cpu@0 { device_type = "cpu"; - compatible = "snps,archs38xN"; + compatible = "snps,archs38"; reg = <0>; + clocks = <&core_clk>; + }; + cpu@1 { + device_type = "cpu"; + compatible = "snps,archs38"; + reg = <1>; + clocks = <&core_clk>; + }; + cpu@2 { + device_type = "cpu"; + compatible = "snps,archs38"; + reg = <2>; + clocks = <&core_clk>; + }; + cpu@3 { + device_type = "cpu"; + compatible = "snps,archs38"; + reg = <3>; + clocks = <&core_clk>; }; }; diff --git a/arch/arc/boot/dts/vdk_axc003_idu.dtsi b/arch/arc/boot/dts/vdk_axc003_idu.dtsi index 82214cd7ba0c..28956f9a9f3d 100644 --- a/arch/arc/boot/dts/vdk_axc003_idu.dtsi +++ b/arch/arc/boot/dts/vdk_axc003_idu.dtsi @@ -41,14 +41,7 @@ compatible = "snps,archs-idu-intc"; interrupt-controller; interrupt-parent = <&core_intc>; - - /* - * <hwirq distribution> - * distribution: 0=RR; 1=cpu0, 2=cpu1, 4=cpu2, 8=cpu3 - */ - #interrupt-cells = <2>; - - interrupts = <24 25 26 27>; + #interrupt-cells = <1>; }; debug_uart: dw-apb-uart@0x5000 { @@ -56,7 +49,7 @@ reg = <0x5000 0x100>; clock-frequency = <2403200>; interrupt-parent = <&idu_intc>; - interrupts = <2 0>; + interrupts = <2>; baud = <115200>; reg-shift = <2>; reg-io-width = <4>; @@ -70,7 +63,7 @@ reg = < 0xe0012000 0x200 >; interrupt-controller; interrupt-parent = <&idu_intc>; - interrupts = < 0 0 >; + interrupts = <0>; }; memory { diff --git a/arch/arc/boot/dts/vdk_axs10x_mb.dtsi b/arch/arc/boot/dts/vdk_axs10x_mb.dtsi index 99498a4b4216..459fc656b759 100644 --- a/arch/arc/boot/dts/vdk_axs10x_mb.dtsi +++ b/arch/arc/boot/dts/vdk_axs10x_mb.dtsi @@ -23,6 +23,12 @@ #clock-cells = <0>; }; + mmcclk: mmcclk { + compatible = "fixed-clock"; + clock-frequency = <50000000>; + #clock-cells = <0>; + }; + pguclk: pguclk { #clock-cells = <0>; compatible = "fixed-clock"; @@ -94,5 +100,31 @@ interrupts = <5>; interrupt-names = "arc_ps2_irq"; }; + + mmc@0x15000 { + compatible = "snps,dw-mshc"; + reg = <0x15000 0x400>; + num-slots = <1>; + fifo-depth = <1024>; + card-detect-delay = <200>; + clocks = <&apbclk>, <&mmcclk>; + clock-names = "biu", "ciu"; + interrupts = <7>; + bus-width = <4>; + }; + }; + + /* + * Embedded Vision subsystem UIO mappings; only relevant for EV VDK + * + * This node is intentionally put outside of MB above becase + * it maps areas outside of MB's 0xEz-0xFz. + */ + uio_ev: uio@0xD0000000 { + compatible = "generic-uio"; + reg = <0xD0000000 0x2000 0xD1000000 0x2000 0x90000000 0x10000000 0xC0000000 0x10000000>; + reg-names = "ev_gsa", "ev_ctrl", "ev_shared_mem", "ev_code_mem"; + interrupt-parent = <&mb_intc>; + interrupts = <23>; }; }; diff --git a/arch/arc/configs/vdk_hs38_smp_defconfig b/arch/arc/configs/vdk_hs38_smp_defconfig index 573028f19de7..5c0971787acf 100644 --- a/arch/arc/configs/vdk_hs38_smp_defconfig +++ b/arch/arc/configs/vdk_hs38_smp_defconfig @@ -16,6 +16,7 @@ CONFIG_AXS103=y CONFIG_ISA_ARCV2=y CONFIG_SMP=y # CONFIG_ARC_TIMERS_64BIT is not set +# CONFIG_ARC_SMP_HALT_ON_RESET is not set CONFIG_ARC_UBOOT_SUPPORT=y CONFIG_ARC_BUILTIN_DTB_NAME="vdk_hs38_smp" CONFIG_PREEMPT=y @@ -56,7 +57,6 @@ CONFIG_NATIONAL_PHY=y CONFIG_MOUSE_PS2_TOUCHKIT=y CONFIG_SERIO_ARC_PS2=y # CONFIG_LEGACY_PTYS is not set -# CONFIG_DEVKMEM is not set CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_DW=y @@ -78,9 +78,14 @@ CONFIG_USB_OHCI_HCD=y CONFIG_USB_OHCI_HCD_PLATFORM=y CONFIG_USB_STORAGE=y CONFIG_USB_SERIAL=y +CONFIG_MMC=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_PLTFM=y +CONFIG_MMC_DW=y +CONFIG_UIO=y +CONFIG_UIO_PDRV_GENIRQ=y # CONFIG_IOMMU_SUPPORT is not set CONFIG_EXT3_FS=y -CONFIG_EXT4_FS=y CONFIG_MSDOS_FS=y CONFIG_VFAT_FS=y CONFIG_NTFS_FS=y diff --git a/arch/arc/include/asm/Kbuild b/arch/arc/include/asm/Kbuild index c332604606dd..353dae386b2f 100644 --- a/arch/arc/include/asm/Kbuild +++ b/arch/arc/include/asm/Kbuild @@ -1,52 +1,27 @@ -generic-y += auxvec.h -generic-y += bitsperlong.h generic-y += bugs.h generic-y += clkdev.h -generic-y += cputime.h generic-y += device.h generic-y += div64.h generic-y += emergency-restart.h -generic-y += errno.h +generic-y += extable.h generic-y += fb.h -generic-y += fcntl.h generic-y += ftrace.h generic-y += hardirq.h generic-y += hw_irq.h -generic-y += ioctl.h -generic-y += ioctls.h -generic-y += ipcbuf.h generic-y += irq_regs.h generic-y += irq_work.h generic-y += kmap_types.h -generic-y += kvm_para.h generic-y += local.h generic-y += local64.h generic-y += mcs_spinlock.h generic-y += mm-arch-hooks.h -generic-y += mman.h -generic-y += msgbuf.h generic-y += msi.h -generic-y += param.h generic-y += parport.h generic-y += pci.h generic-y += percpu.h -generic-y += poll.h -generic-y += posix_types.h generic-y += preempt.h -generic-y += resource.h -generic-y += sembuf.h -generic-y += shmbuf.h -generic-y += siginfo.h -generic-y += socket.h -generic-y += sockios.h -generic-y += stat.h -generic-y += statfs.h -generic-y += termbits.h -generic-y += termios.h generic-y += topology.h generic-y += trace_clock.h -generic-y += types.h -generic-y += ucontext.h generic-y += user.h generic-y += vga.h generic-y += word-at-a-time.h diff --git a/arch/arc/include/asm/arcregs.h b/arch/arc/include/asm/arcregs.h index f659942744de..ba8e802dba80 100644 --- a/arch/arc/include/asm/arcregs.h +++ b/arch/arc/include/asm/arcregs.h @@ -38,6 +38,9 @@ #define ARC_REG_CLUSTER_BCR 0xcf #define ARC_REG_AUX_ICCM 0x208 /* ICCM Base Addr (ARCv2) */ +/* Common for ARCompact and ARCv2 status register */ +#define ARC_REG_STATUS32 0x0A + /* status32 Bits Positions */ #define STATUS_AE_BIT 5 /* Exception active */ #define STATUS_DE_BIT 6 /* PC is in delay slot */ diff --git a/arch/arc/include/asm/atomic.h b/arch/arc/include/asm/atomic.h index b65930a49589..54b54da6384c 100644 --- a/arch/arc/include/asm/atomic.h +++ b/arch/arc/include/asm/atomic.h @@ -17,10 +17,11 @@ #include <asm/barrier.h> #include <asm/smp.h> +#define ATOMIC_INIT(i) { (i) } + #ifndef CONFIG_ARC_PLAT_EZNPS #define atomic_read(v) READ_ONCE((v)->counter) -#define ATOMIC_INIT(i) { (i) } #ifdef CONFIG_ARC_HAS_LLSC diff --git a/arch/arc/include/asm/cache.h b/arch/arc/include/asm/cache.h index 5008021fba98..19ebddffb279 100644 --- a/arch/arc/include/asm/cache.h +++ b/arch/arc/include/asm/cache.h @@ -62,6 +62,8 @@ extern unsigned long perip_base, perip_end; #define ARC_REG_IC_BCR 0x77 /* Build Config reg */ #define ARC_REG_IC_IVIC 0x10 #define ARC_REG_IC_CTRL 0x11 +#define ARC_REG_IC_IVIR 0x16 +#define ARC_REG_IC_ENDR 0x17 #define ARC_REG_IC_IVIL 0x19 #define ARC_REG_IC_PTAG 0x1E #define ARC_REG_IC_PTAG_HI 0x1F @@ -76,6 +78,8 @@ extern unsigned long perip_base, perip_end; #define ARC_REG_DC_IVDL 0x4A #define ARC_REG_DC_FLSH 0x4B #define ARC_REG_DC_FLDL 0x4C +#define ARC_REG_DC_STARTR 0x4D +#define ARC_REG_DC_ENDR 0x4E #define ARC_REG_DC_PTAG 0x5C #define ARC_REG_DC_PTAG_HI 0x5F @@ -83,6 +87,8 @@ extern unsigned long perip_base, perip_end; #define DC_CTRL_DIS 0x001 #define DC_CTRL_INV_MODE_FLUSH 0x040 #define DC_CTRL_FLUSH_STATUS 0x100 +#define DC_CTRL_RGN_OP_INV 0x200 +#define DC_CTRL_RGN_OP_MSK 0x200 /*System-level cache (L2 cache) related Auxiliary registers */ #define ARC_REG_SLC_CFG 0x901 diff --git a/arch/arc/include/asm/dma-mapping.h b/arch/arc/include/asm/dma-mapping.h index 266f11c9bd59..94285031c4fb 100644 --- a/arch/arc/include/asm/dma-mapping.h +++ b/arch/arc/include/asm/dma-mapping.h @@ -18,9 +18,9 @@ #include <plat/dma.h> #endif -extern struct dma_map_ops arc_dma_ops; +extern const struct dma_map_ops arc_dma_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) { return &arc_dma_ops; } diff --git a/arch/arc/include/asm/entry-arcv2.h b/arch/arc/include/asm/entry-arcv2.h index aee1a77934cf..ac85380d14a4 100644 --- a/arch/arc/include/asm/entry-arcv2.h +++ b/arch/arc/include/asm/entry-arcv2.h @@ -16,6 +16,11 @@ ; ; Now manually save: r12, sp, fp, gp, r25 +#ifdef CONFIG_ARC_HAS_ACCL_REGS + PUSH r59 + PUSH r58 +#endif + PUSH r30 PUSH r12 @@ -75,6 +80,11 @@ POP r12 POP r30 +#ifdef CONFIG_ARC_HAS_ACCL_REGS + POP r58 + POP r59 +#endif + .endm /*------------------------------------------------------------------------*/ diff --git a/arch/arc/include/asm/hugepage.h b/arch/arc/include/asm/hugepage.h index 317ff773e1ca..b18fcb606908 100644 --- a/arch/arc/include/asm/hugepage.h +++ b/arch/arc/include/asm/hugepage.h @@ -11,6 +11,7 @@ #define _ASM_ARC_HUGEPAGE_H #include <linux/types.h> +#define __ARCH_USE_5LEVEL_HACK #include <asm-generic/pgtable-nopmd.h> static inline pte_t pmd_pte(pmd_t pmd) diff --git a/arch/arc/include/asm/irq.h b/arch/arc/include/asm/irq.h index c0fa0d2de400..0618b1ce707c 100644 --- a/arch/arc/include/asm/irq.h +++ b/arch/arc/include/asm/irq.h @@ -9,13 +9,19 @@ #ifndef __ASM_ARC_IRQ_H #define __ASM_ARC_IRQ_H -#define NR_CPU_IRQS 32 /* number of interrupt lines of ARC770 CPU */ -#define NR_IRQS 128 /* allow some CPU external IRQ handling */ +/* + * ARCv2 can support 240 interrupts in the core interrupts controllers and + * 128 interrupts in IDU. Thus 512 virtual IRQs must be enough for most + * configurations of boards. + * This doesnt affect ARCompact, but we change it to same value + */ +#define NR_IRQS 512 /* Platform Independent IRQs */ #ifdef CONFIG_ISA_ARCV2 #define IPI_IRQ 19 #define SOFTIRQ_IRQ 21 +#define FIRST_EXT_IRQ 24 #endif #include <linux/interrupt.h> diff --git a/arch/arc/include/asm/kprobes.h b/arch/arc/include/asm/kprobes.h index 944dbedb38b5..2e52d18e6bc7 100644 --- a/arch/arc/include/asm/kprobes.h +++ b/arch/arc/include/asm/kprobes.h @@ -9,6 +9,8 @@ #ifndef _ARC_KPROBES_H #define _ARC_KPROBES_H +#include <asm-generic/kprobes.h> + #ifdef CONFIG_KPROBES typedef u16 kprobe_opcode_t; @@ -52,9 +54,7 @@ int kprobe_fault_handler(struct pt_regs *regs, unsigned long cause); void kretprobe_trampoline(void); void trap_is_kprobe(unsigned long address, struct pt_regs *regs); #else -static void trap_is_kprobe(unsigned long address, struct pt_regs *regs) -{ -} -#endif +#define trap_is_kprobe(address, regs) +#endif /* CONFIG_KPROBES */ -#endif +#endif /* _ARC_KPROBES_H */ diff --git a/arch/arc/include/asm/mmu.h b/arch/arc/include/asm/mmu.h index b144d7ca7d20..db7319e9b506 100644 --- a/arch/arc/include/asm/mmu.h +++ b/arch/arc/include/asm/mmu.h @@ -9,6 +9,10 @@ #ifndef _ASM_ARC_MMU_H #define _ASM_ARC_MMU_H +#ifndef __ASSEMBLY__ +#include <linux/threads.h> /* NR_CPUS */ +#endif + #if defined(CONFIG_ARC_MMU_V1) #define CONFIG_ARC_MMU_VER 1 #elif defined(CONFIG_ARC_MMU_V2) diff --git a/arch/arc/include/asm/mmu_context.h b/arch/arc/include/asm/mmu_context.h index b0b87f2447f5..64b5ebae1ae8 100644 --- a/arch/arc/include/asm/mmu_context.h +++ b/arch/arc/include/asm/mmu_context.h @@ -20,6 +20,7 @@ #include <asm/arcregs.h> #include <asm/tlb.h> +#include <linux/sched/mm.h> #include <asm-generic/mm_hooks.h> diff --git a/arch/arc/include/asm/pgtable.h b/arch/arc/include/asm/pgtable.h index e94ca72b974e..08fe33830d4b 100644 --- a/arch/arc/include/asm/pgtable.h +++ b/arch/arc/include/asm/pgtable.h @@ -35,10 +35,11 @@ #ifndef _ASM_ARC_PGTABLE_H #define _ASM_ARC_PGTABLE_H -#include <asm/page.h> -#include <asm/mmu.h> -#include <asm-generic/pgtable-nopmd.h> #include <linux/const.h> +#define __ARCH_USE_5LEVEL_HACK +#include <asm-generic/pgtable-nopmd.h> +#include <asm/page.h> +#include <asm/mmu.h> /* to propagate CONFIG_ARC_MMU_VER <n> */ /************************************************************************** * Page Table Flags diff --git a/arch/arc/include/asm/processor.h b/arch/arc/include/asm/processor.h index 6e1242da0159..4104a0839214 100644 --- a/arch/arc/include/asm/processor.h +++ b/arch/arc/include/asm/processor.h @@ -86,8 +86,6 @@ struct task_struct; #define TSK_K_BLINK(tsk) TSK_K_REG(tsk, 4) #define TSK_K_FP(tsk) TSK_K_REG(tsk, 0) -#define thread_saved_pc(tsk) TSK_K_BLINK(tsk) - extern void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long usp); diff --git a/arch/arc/include/asm/ptrace.h b/arch/arc/include/asm/ptrace.h index 47111d565a95..5297faa8a378 100644 --- a/arch/arc/include/asm/ptrace.h +++ b/arch/arc/include/asm/ptrace.h @@ -86,6 +86,10 @@ struct pt_regs { unsigned long r12, r30; +#ifdef CONFIG_ARC_HAS_ACCL_REGS + unsigned long r58, r59; /* ACCL/ACCH used by FPU / DSP MPY */ +#endif + /*------- Below list auto saved by h/w -----------*/ unsigned long r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11; diff --git a/arch/arc/include/asm/uaccess.h b/arch/arc/include/asm/uaccess.h index 41faf17cd28d..f35974ee7264 100644 --- a/arch/arc/include/asm/uaccess.h +++ b/arch/arc/include/asm/uaccess.h @@ -24,12 +24,10 @@ #ifndef _ASM_ARC_UACCESS_H #define _ASM_ARC_UACCESS_H -#include <linux/sched.h> -#include <asm/errno.h> #include <linux/string.h> /* for generic string functions */ -#define __kernel_ok (segment_eq(get_fs(), KERNEL_DS)) +#define __kernel_ok (uaccess_kernel()) /* * Algorithmically, for __user_ok() we want do: @@ -170,7 +168,7 @@ static inline unsigned long -__arc_copy_from_user(void *to, const void __user *from, unsigned long n) +raw_copy_from_user(void *to, const void __user *from, unsigned long n) { long res = 0; char val; @@ -396,11 +394,8 @@ __arc_copy_from_user(void *to, const void __user *from, unsigned long n) return res; } -extern unsigned long slowpath_copy_to_user(void __user *to, const void *from, - unsigned long n); - static inline unsigned long -__arc_copy_to_user(void __user *to, const void *from, unsigned long n) +raw_copy_to_user(void __user *to, const void *from, unsigned long n) { long res = 0; char val; @@ -726,24 +721,20 @@ static inline long __arc_strnlen_user(const char __user *s, long n) } #ifndef CONFIG_CC_OPTIMIZE_FOR_SIZE -#define __copy_from_user(t, f, n) __arc_copy_from_user(t, f, n) -#define __copy_to_user(t, f, n) __arc_copy_to_user(t, f, n) + +#define INLINE_COPY_TO_USER +#define INLINE_COPY_FROM_USER + #define __clear_user(d, n) __arc_clear_user(d, n) #define __strncpy_from_user(d, s, n) __arc_strncpy_from_user(d, s, n) #define __strnlen_user(s, n) __arc_strnlen_user(s, n) #else -extern long arc_copy_from_user_noinline(void *to, const void __user * from, - unsigned long n); -extern long arc_copy_to_user_noinline(void __user *to, const void *from, - unsigned long n); extern unsigned long arc_clear_user_noinline(void __user *to, unsigned long n); extern long arc_strncpy_from_user_noinline (char *dst, const char __user *src, long count); extern long arc_strnlen_user_noinline(const char __user *src, long n); -#define __copy_from_user(t, f, n) arc_copy_from_user_noinline(t, f, n) -#define __copy_to_user(t, f, n) arc_copy_to_user_noinline(t, f, n) #define __clear_user(d, n) arc_clear_user_noinline(d, n) #define __strncpy_from_user(d, s, n) arc_strncpy_from_user_noinline(d, s, n) #define __strnlen_user(s, n) arc_strnlen_user_noinline(s, n) @@ -752,6 +743,4 @@ extern long arc_strnlen_user_noinline(const char __user *src, long n); #include <asm-generic/uaccess.h> -extern int fixup_exception(struct pt_regs *regs); - #endif diff --git a/arch/arc/include/uapi/asm/Kbuild b/arch/arc/include/uapi/asm/Kbuild index f50d02df78d5..fa6d0ff4ff89 100644 --- a/arch/arc/include/uapi/asm/Kbuild +++ b/arch/arc/include/uapi/asm/Kbuild @@ -1,5 +1,28 @@ # UAPI Header export list include include/uapi/asm-generic/Kbuild.asm -header-y += elf.h -header-y += page.h -header-y += cachectl.h + +generic-y += auxvec.h +generic-y += bitsperlong.h +generic-y += errno.h +generic-y += fcntl.h +generic-y += ioctl.h +generic-y += ioctls.h +generic-y += ipcbuf.h +generic-y += kvm_para.h +generic-y += mman.h +generic-y += msgbuf.h +generic-y += param.h +generic-y += poll.h +generic-y += posix_types.h +generic-y += resource.h +generic-y += sembuf.h +generic-y += shmbuf.h +generic-y += siginfo.h +generic-y += socket.h +generic-y += sockios.h +generic-y += stat.h +generic-y += statfs.h +generic-y += termbits.h +generic-y += termios.h +generic-y += types.h +generic-y += ucontext.h diff --git a/arch/arc/include/uapi/asm/elf.h b/arch/arc/include/uapi/asm/elf.h index 0037a587320d..06d95e611616 100644 --- a/arch/arc/include/uapi/asm/elf.h +++ b/arch/arc/include/uapi/asm/elf.h @@ -27,6 +27,7 @@ typedef unsigned long elf_greg_t; typedef unsigned long elf_fpregset_t; #define ELF_NGREG (sizeof(struct user_regs_struct) / sizeof(elf_greg_t)) +#define ELF_ARCV2REG (sizeof(struct user_regs_arcv2) / sizeof(elf_greg_t)) typedef elf_greg_t elf_gregset_t[ELF_NGREG]; diff --git a/arch/arc/include/uapi/asm/ptrace.h b/arch/arc/include/uapi/asm/ptrace.h index 0b3ef63d4a03..dd206e6b482c 100644 --- a/arch/arc/include/uapi/asm/ptrace.h +++ b/arch/arc/include/uapi/asm/ptrace.h @@ -47,6 +47,11 @@ struct user_regs_struct { unsigned long efa; /* break pt addr, for break points in delay slots */ unsigned long stop_pc; /* give dbg stop_pc after ensuring brkpt trap */ }; + +struct user_regs_arcv2 { + unsigned long r30, r58, r59; +}; + #endif /* !__ASSEMBLY__ */ #endif /* _UAPI__ASM_ARC_PTRACE_H */ diff --git a/arch/arc/kernel/ctx_sw.c b/arch/arc/kernel/ctx_sw.c index 6f4cb0dab1b9..9e1ae9d41925 100644 --- a/arch/arc/kernel/ctx_sw.c +++ b/arch/arc/kernel/ctx_sw.c @@ -16,6 +16,7 @@ #include <asm/asm-offsets.h> #include <linux/sched.h> +#include <linux/sched/debug.h> #ifdef CONFIG_ARC_PLAT_EZNPS #include <plat/ctop.h> #endif diff --git a/arch/arc/kernel/entry-arcv2.S b/arch/arc/kernel/entry-arcv2.S index 0b6388a5f0b8..cc558a25b8fa 100644 --- a/arch/arc/kernel/entry-arcv2.S +++ b/arch/arc/kernel/entry-arcv2.S @@ -14,6 +14,11 @@ #include <asm/arcregs.h> #include <asm/irqflags.h> +; A maximum number of supported interrupts in the core interrupt controller. +; This number is not equal to the maximum interrupt number (256) because +; first 16 lines are reserved for exceptions and are not configurable. +#define NR_CPU_IRQS 240 + .cpu HS #define VECTOR .word @@ -52,7 +57,7 @@ VECTOR handle_interrupt ; unused VECTOR handle_interrupt ; (23) unused # End of fixed IRQs -.rept CONFIG_ARC_NUMBER_OF_INTERRUPTS - 8 +.rept NR_CPU_IRQS - 8 VECTOR handle_interrupt .endr @@ -95,15 +100,21 @@ END(handle_interrupt) ;################### Non TLB Exception Handling ############################# ENTRY(EV_SWI) - flag 1 + ; TODO: implement this + EXCEPTION_PROLOGUE + b ret_from_exception END(EV_SWI) ENTRY(EV_DivZero) - flag 1 + ; TODO: implement this + EXCEPTION_PROLOGUE + b ret_from_exception END(EV_DivZero) ENTRY(EV_DCError) - flag 1 + ; TODO: implement this + EXCEPTION_PROLOGUE + b ret_from_exception END(EV_DCError) ; --------------------------------------------- diff --git a/arch/arc/kernel/intc-arcv2.c b/arch/arc/kernel/intc-arcv2.c index ecef0fb0b66c..f928795fd07a 100644 --- a/arch/arc/kernel/intc-arcv2.c +++ b/arch/arc/kernel/intc-arcv2.c @@ -14,6 +14,16 @@ #include <linux/irqchip.h> #include <asm/irq.h> +#define NR_EXCEPTIONS 16 + +struct bcr_irq_arcv2 { +#ifdef CONFIG_CPU_BIG_ENDIAN + unsigned int pad:3, firq:1, prio:4, exts:8, irqs:8, ver:8; +#else + unsigned int ver:8, irqs:8, exts:8, prio:4, firq:1, pad:3; +#endif +}; + /* * Early Hardware specific Interrupt setup * -Called very early (start_kernel -> setup_arch -> setup_processor) @@ -22,15 +32,8 @@ */ void arc_init_IRQ(void) { - unsigned int tmp, irq_prio; - - struct irq_build { -#ifdef CONFIG_CPU_BIG_ENDIAN - unsigned int pad:3, firq:1, prio:4, exts:8, irqs:8, ver:8; -#else - unsigned int ver:8, irqs:8, exts:8, prio:4, firq:1, pad:3; -#endif - } irq_bcr; + unsigned int tmp, irq_prio, i; + struct bcr_irq_arcv2 irq_bcr; struct aux_irq_ctrl { #ifdef CONFIG_CPU_BIG_ENDIAN @@ -68,8 +71,18 @@ void arc_init_IRQ(void) irq_prio + 1, ARCV2_IRQ_DEF_PRIO, irq_bcr.firq ? " FIRQ (not used)":""); + /* + * Set a default priority for all available interrupts to prevent + * switching of register banks if Fast IRQ and multiple register banks + * are supported by CPU. + */ + for (i = NR_EXCEPTIONS; i < irq_bcr.irqs + NR_EXCEPTIONS; i++) { + write_aux_reg(AUX_IRQ_SELECT, i); + write_aux_reg(AUX_IRQ_PRIORITY, ARCV2_IRQ_DEF_PRIO); + } + /* setup status32, don't enable intr yet as kernel doesn't want */ - tmp = read_aux_reg(0xa); + tmp = read_aux_reg(ARC_REG_STATUS32); tmp |= STATUS_AD_MASK | (ARCV2_IRQ_DEF_PRIO << 1); tmp &= ~STATUS_IE_MASK; asm volatile("kflag %0 \n"::"r"(tmp)); @@ -115,7 +128,7 @@ static int arcv2_irq_map(struct irq_domain *d, unsigned int irq, * core intc IRQs [16, 23]: * Statically assigned always private-per-core (Timers, WDT, IPI, PCT) */ - if (hw < 24) { + if (hw < FIRST_EXT_IRQ) { /* * A subsequent request_percpu_irq() fails if percpu_devid is * not set. That in turns sets NOAUTOEN, meaning each core needs @@ -140,11 +153,16 @@ static int __init init_onchip_IRQ(struct device_node *intc, struct device_node *parent) { struct irq_domain *root_domain; + struct bcr_irq_arcv2 irq_bcr; + unsigned int nr_cpu_irqs; + + READ_BCR(ARC_REG_IRQ_BCR, irq_bcr); + nr_cpu_irqs = irq_bcr.irqs + NR_EXCEPTIONS; if (parent) panic("DeviceTree incore intc not a root irq controller\n"); - root_domain = irq_domain_add_linear(intc, NR_CPU_IRQS, &arcv2_irq_ops, NULL); + root_domain = irq_domain_add_linear(intc, nr_cpu_irqs, &arcv2_irq_ops, NULL); if (!root_domain) panic("root irq domain not avail\n"); diff --git a/arch/arc/kernel/intc-compact.c b/arch/arc/kernel/intc-compact.c index 8c1fd5c00782..7e608c6b0a01 100644 --- a/arch/arc/kernel/intc-compact.c +++ b/arch/arc/kernel/intc-compact.c @@ -14,6 +14,7 @@ #include <linux/irqchip.h> #include <asm/irq.h> +#define NR_CPU_IRQS 32 /* number of irq lines coming in */ #define TIMER0_IRQ 3 /* Fixed by ISA */ /* diff --git a/arch/arc/kernel/kgdb.c b/arch/arc/kernel/kgdb.c index ecf6a7869375..9a3c34af2ae8 100644 --- a/arch/arc/kernel/kgdb.c +++ b/arch/arc/kernel/kgdb.c @@ -10,6 +10,7 @@ #include <linux/kgdb.h> #include <linux/sched.h> +#include <linux/sched/task_stack.h> #include <asm/disasm.h> #include <asm/cacheflush.h> diff --git a/arch/arc/kernel/mcip.c b/arch/arc/kernel/mcip.c index 9f6b68fd4f3b..f61a52b01625 100644 --- a/arch/arc/kernel/mcip.c +++ b/arch/arc/kernel/mcip.c @@ -156,15 +156,20 @@ static void idu_set_mode(unsigned int cmn_irq, unsigned int lvl, __mcip_cmd_data(CMD_IDU_SET_MODE, cmn_irq, data.word); } -static void idu_irq_mask(struct irq_data *data) +static void idu_irq_mask_raw(irq_hw_number_t hwirq) { unsigned long flags; raw_spin_lock_irqsave(&mcip_lock, flags); - __mcip_cmd_data(CMD_IDU_SET_MASK, data->hwirq, 1); + __mcip_cmd_data(CMD_IDU_SET_MASK, hwirq, 1); raw_spin_unlock_irqrestore(&mcip_lock, flags); } +static void idu_irq_mask(struct irq_data *data) +{ + idu_irq_mask_raw(data->hwirq); +} + static void idu_irq_unmask(struct irq_data *data) { unsigned long flags; @@ -230,14 +235,12 @@ static struct irq_chip idu_irq_chip = { }; -static irq_hw_number_t idu_first_hwirq; - static void idu_cascade_isr(struct irq_desc *desc) { struct irq_domain *idu_domain = irq_desc_get_handler_data(desc); struct irq_chip *core_chip = irq_desc_get_chip(desc); irq_hw_number_t core_hwirq = irqd_to_hwirq(irq_desc_get_irq_data(desc)); - irq_hw_number_t idu_hwirq = core_hwirq - idu_first_hwirq; + irq_hw_number_t idu_hwirq = core_hwirq - FIRST_EXT_IRQ; chained_irq_enter(core_chip, desc); generic_handle_irq(irq_find_mapping(idu_domain, idu_hwirq)); @@ -252,23 +255,8 @@ static int idu_irq_map(struct irq_domain *d, unsigned int virq, irq_hw_number_t return 0; } -static int idu_irq_xlate(struct irq_domain *d, struct device_node *n, - const u32 *intspec, unsigned int intsize, - irq_hw_number_t *out_hwirq, unsigned int *out_type) -{ - /* - * Ignore value of interrupt distribution mode for common interrupts in - * IDU which resides in intspec[1] since setting an affinity using value - * from Device Tree is deprecated in ARC. - */ - *out_hwirq = intspec[0]; - *out_type = IRQ_TYPE_NONE; - - return 0; -} - static const struct irq_domain_ops idu_irq_ops = { - .xlate = idu_irq_xlate, + .xlate = irq_domain_xlate_onecell, .map = idu_irq_map, }; @@ -283,33 +271,37 @@ static int __init idu_of_init(struct device_node *intc, struct device_node *parent) { struct irq_domain *domain; - /* Read IDU BCR to confirm nr_irqs */ - int nr_irqs = of_irq_count(intc); + int nr_irqs; int i, virq; struct mcip_bcr mp; + struct mcip_idu_bcr idu_bcr; READ_BCR(ARC_REG_MCIP_BCR, mp); if (!mp.idu) panic("IDU not detected, but DeviceTree using it"); - pr_info("MCIP: IDU referenced from Devicetree %d irqs\n", nr_irqs); + READ_BCR(ARC_REG_MCIP_IDU_BCR, idu_bcr); + nr_irqs = mcip_idu_bcr_to_nr_irqs(idu_bcr); + + pr_info("MCIP: IDU supports %u common irqs\n", nr_irqs); domain = irq_domain_add_linear(intc, nr_irqs, &idu_irq_ops, NULL); /* Parent interrupts (core-intc) are already mapped */ for (i = 0; i < nr_irqs; i++) { + /* Mask all common interrupts by default */ + idu_irq_mask_raw(i); + /* * Return parent uplink IRQs (towards core intc) 24,25,..... * this step has been done before already * however we need it to get the parent virq and set IDU handler * as first level isr */ - virq = irq_of_parse_and_map(intc, i); - if (!i) - idu_first_hwirq = irqd_to_hwirq(irq_get_irq_data(virq)); - + virq = irq_create_mapping(NULL, i + FIRST_EXT_IRQ); + BUG_ON(!virq); irq_set_chained_handler_and_data(virq, idu_cascade_isr, domain); } diff --git a/arch/arc/kernel/process.c b/arch/arc/kernel/process.c index a41a79a4f4fe..2a018de6d6cd 100644 --- a/arch/arc/kernel/process.c +++ b/arch/arc/kernel/process.c @@ -11,6 +11,9 @@ #include <linux/errno.h> #include <linux/module.h> #include <linux/sched.h> +#include <linux/sched/task.h> +#include <linux/sched/task_stack.h> + #include <linux/mm.h> #include <linux/fs.h> #include <linux/unistd.h> diff --git a/arch/arc/kernel/ptrace.c b/arch/arc/kernel/ptrace.c index 4442204fe238..5ee4676f135d 100644 --- a/arch/arc/kernel/ptrace.c +++ b/arch/arc/kernel/ptrace.c @@ -8,6 +8,7 @@ #include <linux/ptrace.h> #include <linux/tracehook.h> +#include <linux/sched/task_stack.h> #include <linux/regset.h> #include <linux/unistd.h> #include <linux/elf.h> @@ -183,19 +184,75 @@ static int genregs_set(struct task_struct *target, return ret; } +#ifdef CONFIG_ISA_ARCV2 +static int arcv2regs_get(struct task_struct *target, + const struct user_regset *regset, + unsigned int pos, unsigned int count, + void *kbuf, void __user *ubuf) +{ + const struct pt_regs *regs = task_pt_regs(target); + int ret, copy_sz; + + if (IS_ENABLED(CONFIG_ARC_HAS_ACCL_REGS)) + copy_sz = sizeof(struct user_regs_arcv2); + else + copy_sz = 4; /* r30 only */ + + /* + * itemized copy not needed like above as layout of regs (r30,r58,r59) + * is exactly same in kernel (pt_regs) and userspace (user_regs_arcv2) + */ + ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, ®s->r30, + 0, copy_sz); + + return ret; +} + +static int arcv2regs_set(struct task_struct *target, + const struct user_regset *regset, + unsigned int pos, unsigned int count, + const void *kbuf, const void __user *ubuf) +{ + const struct pt_regs *regs = task_pt_regs(target); + int ret, copy_sz; + + if (IS_ENABLED(CONFIG_ARC_HAS_ACCL_REGS)) + copy_sz = sizeof(struct user_regs_arcv2); + else + copy_sz = 4; /* r30 only */ + + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, (void *)®s->r30, + 0, copy_sz); + + return ret; +} + +#endif + enum arc_getset { - REGSET_GENERAL, + REGSET_CMN, + REGSET_ARCV2, }; static const struct user_regset arc_regsets[] = { - [REGSET_GENERAL] = { + [REGSET_CMN] = { .core_note_type = NT_PRSTATUS, .n = ELF_NGREG, .size = sizeof(unsigned long), .align = sizeof(unsigned long), .get = genregs_get, .set = genregs_set, - } + }, +#ifdef CONFIG_ISA_ARCV2 + [REGSET_ARCV2] = { + .core_note_type = NT_ARC_V2, + .n = ELF_ARCV2REG, + .size = sizeof(unsigned long), + .align = sizeof(unsigned long), + .get = arcv2regs_get, + .set = arcv2regs_set, + }, +#endif }; static const struct user_regset_view user_arc_view = { diff --git a/arch/arc/kernel/setup.c b/arch/arc/kernel/setup.c index 3093fa898a23..666613fde91d 100644 --- a/arch/arc/kernel/setup.c +++ b/arch/arc/kernel/setup.c @@ -10,6 +10,7 @@ #include <linux/fs.h> #include <linux/delay.h> #include <linux/root_dev.h> +#include <linux/clk.h> #include <linux/clk-provider.h> #include <linux/clocksource.h> #include <linux/console.h> @@ -318,7 +319,8 @@ static char *arc_extn_mumbojumbo(int cpu_id, char *buf, int len) static void arc_chk_core_config(void) { struct cpuinfo_arc *cpu = &cpuinfo_arc700[smp_processor_id()]; - int fpu_enabled; + int saved = 0, present = 0; + char *opt_nm = NULL;; if (!cpu->extn.timer0) panic("Timer0 is not present!\n"); @@ -345,17 +347,28 @@ static void arc_chk_core_config(void) /* * FP hardware/software config sanity - * -If hardware contains DPFP, kernel needs to save/restore FPU state + * -If hardware present, kernel needs to save/restore FPU state * -If not, it will crash trying to save/restore the non-existant regs - * - * (only DPDP checked since SP has no arch visible regs) */ - fpu_enabled = IS_ENABLED(CONFIG_ARC_FPU_SAVE_RESTORE); - if (cpu->extn.fpu_dp && !fpu_enabled) - pr_warn("CONFIG_ARC_FPU_SAVE_RESTORE needed for working apps\n"); - else if (!cpu->extn.fpu_dp && fpu_enabled) - panic("FPU non-existent, disable CONFIG_ARC_FPU_SAVE_RESTORE\n"); + if (is_isa_arcompact()) { + opt_nm = "CONFIG_ARC_FPU_SAVE_RESTORE"; + saved = IS_ENABLED(CONFIG_ARC_FPU_SAVE_RESTORE); + + /* only DPDP checked since SP has no arch visible regs */ + present = cpu->extn.fpu_dp; + } else { + opt_nm = "CONFIG_ARC_HAS_ACCL_REGS"; + saved = IS_ENABLED(CONFIG_ARC_HAS_ACCL_REGS); + + /* Accumulator Low:High pair (r58:59) present if DSP MPY or FPU */ + present = cpu->extn_mpy.dsp | cpu->extn.fpu_sp | cpu->extn.fpu_dp; + } + + if (present && !saved) + pr_warn("Enable %s for working apps\n", opt_nm); + else if (!present && saved) + panic("Disable %s, hardware NOT present\n", opt_nm); } /* @@ -457,7 +470,7 @@ void __init setup_arch(char **cmdline_p) void __init time_init(void) { of_clk_init(NULL); - clocksource_probe(); + timer_probe(); } static int __init customize_machine(void) @@ -488,8 +501,9 @@ static int show_cpuinfo(struct seq_file *m, void *v) { char *str; int cpu_id = ptr_to_cpu(v); - struct device_node *core_clk = of_find_node_by_name(NULL, "core_clk"); - u32 freq = 0; + struct device *cpu_dev = get_cpu_device(cpu_id); + struct clk *cpu_clk; + unsigned long freq = 0; if (!cpu_online(cpu_id)) { seq_printf(m, "processor [%d]\t: Offline\n", cpu_id); @@ -502,9 +516,15 @@ static int show_cpuinfo(struct seq_file *m, void *v) seq_printf(m, arc_cpu_mumbojumbo(cpu_id, str, PAGE_SIZE)); - of_property_read_u32(core_clk, "clock-frequency", &freq); + cpu_clk = clk_get(cpu_dev, NULL); + if (IS_ERR(cpu_clk)) { + seq_printf(m, "CPU speed \t: Cannot get clock for processor [%d]\n", + cpu_id); + } else { + freq = clk_get_rate(cpu_clk); + } if (freq) - seq_printf(m, "CPU speed\t: %u.%02u Mhz\n", + seq_printf(m, "CPU speed\t: %lu.%02lu Mhz\n", freq / 1000000, (freq / 10000) % 100); seq_printf(m, "Bogo MIPS\t: %lu.%02lu\n", diff --git a/arch/arc/kernel/signal.c b/arch/arc/kernel/signal.c index d347bbc086fe..48685445002e 100644 --- a/arch/arc/kernel/signal.c +++ b/arch/arc/kernel/signal.c @@ -53,6 +53,8 @@ #include <linux/uaccess.h> #include <linux/syscalls.h> #include <linux/tracehook.h> +#include <linux/sched/task_stack.h> + #include <asm/ucontext.h> struct rt_sigframe { diff --git a/arch/arc/kernel/smp.c b/arch/arc/kernel/smp.c index 2afbafadb6ab..f46267153ec2 100644 --- a/arch/arc/kernel/smp.c +++ b/arch/arc/kernel/smp.c @@ -13,7 +13,7 @@ */ #include <linux/spinlock.h> -#include <linux/sched.h> +#include <linux/sched/mm.h> #include <linux/interrupt.h> #include <linux/profile.h> #include <linux/mm.h> @@ -139,8 +139,8 @@ void start_kernel_secondary(void) /* MMU, Caches, Vector Table, Interrupts etc */ setup_processor(); - 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)); diff --git a/arch/arc/kernel/stacktrace.c b/arch/arc/kernel/stacktrace.c index b9192a653b7e..74315f302971 100644 --- a/arch/arc/kernel/stacktrace.c +++ b/arch/arc/kernel/stacktrace.c @@ -28,6 +28,8 @@ #include <linux/export.h> #include <linux/stacktrace.h> #include <linux/kallsyms.h> +#include <linux/sched/debug.h> + #include <asm/arcregs.h> #include <asm/unwind.h> #include <asm/switch_to.h> diff --git a/arch/arc/kernel/traps.c b/arch/arc/kernel/traps.c index c927aa84e652..ff83e78d0cfb 100644 --- a/arch/arc/kernel/traps.c +++ b/arch/arc/kernel/traps.c @@ -13,7 +13,7 @@ * Rahul Trivedi: Codito Technologies 2004 */ -#include <linux/sched.h> +#include <linux/sched/signal.h> #include <linux/kdebug.h> #include <linux/uaccess.h> #include <linux/ptrace.h> diff --git a/arch/arc/kernel/troubleshoot.c b/arch/arc/kernel/troubleshoot.c index 82f9bc819f4a..f9caf79186d4 100644 --- a/arch/arc/kernel/troubleshoot.c +++ b/arch/arc/kernel/troubleshoot.c @@ -13,6 +13,9 @@ #include <linux/fs_struct.h> #include <linux/proc_fs.h> #include <linux/file.h> +#include <linux/sched/mm.h> +#include <linux/sched/debug.h> + #include <asm/arcregs.h> #include <asm/irqflags.h> diff --git a/arch/arc/kernel/unwind.c b/arch/arc/kernel/unwind.c index 61fd1ce63c56..333daab7def0 100644 --- a/arch/arc/kernel/unwind.c +++ b/arch/arc/kernel/unwind.c @@ -845,7 +845,7 @@ static int processCFI(const u8 *start, const u8 *end, unsigned long targetLoc, * state->dataAlign; break; case DW_CFA_def_cfa_register: - unw_debug("cfa_def_cfa_regsiter: "); + unw_debug("cfa_def_cfa_register: "); state->cfa.reg = get_uleb128(&ptr.p8, end); break; /*todo case DW_CFA_def_cfa_expression: */ @@ -1051,9 +1051,9 @@ int arc_unwind(struct unwind_frame_info *frame) ++ptr; } if (cie != NULL) { - /* get code aligment factor */ + /* get code alignment factor */ state.codeAlign = get_uleb128(&ptr, end); - /* get data aligment factor */ + /* get data alignment factor */ state.dataAlign = get_sleb128(&ptr, end); if (state.codeAlign == 0 || state.dataAlign == 0 || ptr >= end) cie = NULL; diff --git a/arch/arc/mm/cache.c b/arch/arc/mm/cache.c index d408fa21a07c..a867575a758b 100644 --- a/arch/arc/mm/cache.c +++ b/arch/arc/mm/cache.c @@ -21,6 +21,10 @@ #include <asm/cachectl.h> #include <asm/setup.h> +#ifdef CONFIG_ISA_ARCV2 +#define USE_RGN_FLSH 1 +#endif + static int l2_line_sz; static int ioc_exists; int slc_enable = 1, ioc_enable = 1; @@ -28,7 +32,7 @@ unsigned long perip_base = ARC_UNCACHED_ADDR_SPACE; /* legacy value for boot */ unsigned long perip_end = 0xFFFFFFFF; /* legacy value */ void (*_cache_line_loop_ic_fn)(phys_addr_t paddr, unsigned long vaddr, - unsigned long sz, const int cacheop); + unsigned long sz, const int op, const int full_page); void (*__dma_cache_wback_inv)(phys_addr_t start, unsigned long sz); void (*__dma_cache_inv)(phys_addr_t start, unsigned long sz); @@ -233,11 +237,10 @@ slc_chk: static inline void __cache_line_loop_v2(phys_addr_t paddr, unsigned long vaddr, - unsigned long sz, const int op) + unsigned long sz, const int op, const int full_page) { unsigned int aux_cmd; int num_lines; - const int full_page = __builtin_constant_p(sz) && sz == PAGE_SIZE; if (op == OP_INV_IC) { aux_cmd = ARC_REG_IC_IVIL; @@ -279,11 +282,10 @@ void __cache_line_loop_v2(phys_addr_t paddr, unsigned long vaddr, */ static inline void __cache_line_loop_v3(phys_addr_t paddr, unsigned long vaddr, - unsigned long sz, const int op) + unsigned long sz, const int op, const int full_page) { unsigned int aux_cmd, aux_tag; int num_lines; - const int full_page = __builtin_constant_p(sz) && sz == PAGE_SIZE; if (op == OP_INV_IC) { aux_cmd = ARC_REG_IC_IVIL; @@ -334,6 +336,8 @@ void __cache_line_loop_v3(phys_addr_t paddr, unsigned long vaddr, } } +#ifndef USE_RGN_FLSH + /* * In HS38x (MMU v4), I-cache is VIPT (can alias), D-cache is PIPT * Here's how cache ops are implemented @@ -349,17 +353,16 @@ void __cache_line_loop_v3(phys_addr_t paddr, unsigned long vaddr, */ static inline void __cache_line_loop_v4(phys_addr_t paddr, unsigned long vaddr, - unsigned long sz, const int cacheop) + unsigned long sz, const int op, const int full_page) { unsigned int aux_cmd; int num_lines; - const int full_page_op = __builtin_constant_p(sz) && sz == PAGE_SIZE; - if (cacheop == OP_INV_IC) { + if (op == OP_INV_IC) { aux_cmd = ARC_REG_IC_IVIL; } else { /* d$ cmd: INV (discard or wback-n-discard) OR FLUSH (wback) */ - aux_cmd = cacheop & OP_INV ? ARC_REG_DC_IVDL : ARC_REG_DC_FLDL; + aux_cmd = op & OP_INV ? ARC_REG_DC_IVDL : ARC_REG_DC_FLDL; } /* Ensure we properly floor/ceil the non-line aligned/sized requests @@ -368,7 +371,7 @@ void __cache_line_loop_v4(phys_addr_t paddr, unsigned long vaddr, * -@paddr will be cache-line aligned already (being page aligned) * -@sz will be integral multiple of line size (being page sized). */ - if (!full_page_op) { + if (!full_page) { sz += paddr & ~CACHE_LINE_MASK; paddr &= CACHE_LINE_MASK; } @@ -381,7 +384,7 @@ void __cache_line_loop_v4(phys_addr_t paddr, unsigned long vaddr, * - (and needs to be written before the lower 32 bits) */ if (is_pae40_enabled()) { - if (cacheop == OP_INV_IC) + if (op == OP_INV_IC) /* * Non aliasing I-cache in HS38, * aliasing I-cache handled in __cache_line_loop_v3() @@ -397,6 +400,55 @@ void __cache_line_loop_v4(phys_addr_t paddr, unsigned long vaddr, } } +#else + +/* + * optimized flush operation which takes a region as opposed to iterating per line + */ +static inline +void __cache_line_loop_v4(phys_addr_t paddr, unsigned long vaddr, + unsigned long sz, const int op, const int full_page) +{ + unsigned int s, e; + + /* Only for Non aliasing I-cache in HS38 */ + if (op == OP_INV_IC) { + s = ARC_REG_IC_IVIR; + e = ARC_REG_IC_ENDR; + } else { + s = ARC_REG_DC_STARTR; + e = ARC_REG_DC_ENDR; + } + + if (!full_page) { + /* for any leading gap between @paddr and start of cache line */ + sz += paddr & ~CACHE_LINE_MASK; + paddr &= CACHE_LINE_MASK; + + /* + * account for any trailing gap to end of cache line + * this is equivalent to DIV_ROUND_UP() in line ops above + */ + sz += L1_CACHE_BYTES - 1; + } + + if (is_pae40_enabled()) { + /* TBD: check if crossing 4TB boundary */ + if (op == OP_INV_IC) + write_aux_reg(ARC_REG_IC_PTAG_HI, (u64)paddr >> 32); + else + write_aux_reg(ARC_REG_DC_PTAG_HI, (u64)paddr >> 32); + } + + /* ENDR needs to be set ahead of START */ + write_aux_reg(e, paddr + sz); /* ENDR is exclusive */ + write_aux_reg(s, paddr); + + /* caller waits on DC_CTRL.FS */ +} + +#endif + #if (CONFIG_ARC_MMU_VER < 3) #define __cache_line_loop __cache_line_loop_v2 #elif (CONFIG_ARC_MMU_VER == 3) @@ -411,6 +463,11 @@ void __cache_line_loop_v4(phys_addr_t paddr, unsigned long vaddr, * Machine specific helpers for Entire D-Cache or Per Line ops */ +#ifndef USE_RGN_FLSH +/* + * this version avoids extra read/write of DC_CTRL for flush or invalid ops + * in the non region flush regime (such as for ARCompact) + */ static inline void __before_dc_op(const int op) { if (op == OP_FLUSH_N_INV) { @@ -424,6 +481,32 @@ static inline void __before_dc_op(const int op) } } +#else + +static inline void __before_dc_op(const int op) +{ + const unsigned int ctl = ARC_REG_DC_CTRL; + unsigned int val = read_aux_reg(ctl); + + if (op == OP_FLUSH_N_INV) { + val |= DC_CTRL_INV_MODE_FLUSH; + } + + if (op != OP_INV_IC) { + /* + * Flush / Invalidate is provided by DC_CTRL.RNG_OP 0 or 1 + * combined Flush-n-invalidate uses DC_CTRL.IM = 1 set above + */ + val &= ~DC_CTRL_RGN_OP_MSK; + if (op & OP_INV) + val |= DC_CTRL_RGN_OP_INV; + } + write_aux_reg(ctl, val); +} + +#endif + + static inline void __after_dc_op(const int op) { if (op & OP_FLUSH) { @@ -486,13 +569,14 @@ static void __dc_enable(void) static inline void __dc_line_op(phys_addr_t paddr, unsigned long vaddr, unsigned long sz, const int op) { + const int full_page = __builtin_constant_p(sz) && sz == PAGE_SIZE; unsigned long flags; local_irq_save(flags); __before_dc_op(op); - __cache_line_loop(paddr, vaddr, sz, op); + __cache_line_loop(paddr, vaddr, sz, op, full_page); __after_dc_op(op); @@ -521,10 +605,11 @@ static inline void __ic_line_inv_vaddr_local(phys_addr_t paddr, unsigned long vaddr, unsigned long sz) { + const int full_page = __builtin_constant_p(sz) && sz == PAGE_SIZE; unsigned long flags; local_irq_save(flags); - (*_cache_line_loop_ic_fn)(paddr, vaddr, sz, OP_INV_IC); + (*_cache_line_loop_ic_fn)(paddr, vaddr, sz, OP_INV_IC, full_page); local_irq_restore(flags); } @@ -633,6 +718,9 @@ noinline static void slc_entire_op(const int op) write_aux_reg(ARC_REG_SLC_INVALIDATE, 1); + /* Make sure "busy" bit reports correct stataus, see STAR 9001165532 */ + read_aux_reg(r); + /* Important to wait for flush to complete */ while (read_aux_reg(r) & SLC_CTRL_BUSY); } diff --git a/arch/arc/mm/dma.c b/arch/arc/mm/dma.c index 08450a1a5b5f..2a07e6ecafbd 100644 --- a/arch/arc/mm/dma.c +++ b/arch/arc/mm/dma.c @@ -218,7 +218,7 @@ static int arc_dma_supported(struct device *dev, u64 dma_mask) return dma_mask == DMA_BIT_MASK(32); } -struct dma_map_ops arc_dma_ops = { +const struct dma_map_ops arc_dma_ops = { .alloc = arc_dma_alloc, .free = arc_dma_free, .mmap = arc_dma_mmap, diff --git a/arch/arc/mm/extable.c b/arch/arc/mm/extable.c index aa652e281324..72125a34e780 100644 --- a/arch/arc/mm/extable.c +++ b/arch/arc/mm/extable.c @@ -8,7 +8,8 @@ * Borrowed heavily from MIPS */ -#include <linux/module.h> +#include <linux/export.h> +#include <linux/extable.h> #include <linux/uaccess.h> int fixup_exception(struct pt_regs *regs) @@ -27,20 +28,6 @@ int fixup_exception(struct pt_regs *regs) #ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE -long arc_copy_from_user_noinline(void *to, const void __user *from, - unsigned long n) -{ - return __arc_copy_from_user(to, from, n); -} -EXPORT_SYMBOL(arc_copy_from_user_noinline); - -long arc_copy_to_user_noinline(void __user *to, const void *from, - unsigned long n) -{ - return __arc_copy_to_user(to, from, n); -} -EXPORT_SYMBOL(arc_copy_to_user_noinline); - unsigned long arc_clear_user_noinline(void __user *to, unsigned long n) { diff --git a/arch/arc/mm/fault.c b/arch/arc/mm/fault.c index e94e5aa33985..162c97528872 100644 --- a/arch/arc/mm/fault.c +++ b/arch/arc/mm/fault.c @@ -9,7 +9,7 @@ #include <linux/signal.h> #include <linux/interrupt.h> -#include <linux/sched.h> +#include <linux/sched/signal.h> #include <linux/errno.h> #include <linux/ptrace.h> #include <linux/uaccess.h> diff --git a/arch/arc/mm/mmap.c b/arch/arc/mm/mmap.c index 2e06d56e987b..2e13683dfb24 100644 --- a/arch/arc/mm/mmap.c +++ b/arch/arc/mm/mmap.c @@ -13,7 +13,8 @@ #include <linux/fs.h> #include <linux/mm.h> #include <linux/mman.h> -#include <linux/sched.h> +#include <linux/sched/mm.h> + #include <asm/cacheflush.h> #define COLOUR_ALIGN(addr, pgoff) \ @@ -64,7 +65,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr, vma = find_vma(mm, addr); if (TASK_SIZE - len >= addr && - (!vma || addr + len <= vma->vm_start)) + (!vma || addr + len <= vm_start_gap(vma))) return addr; } diff --git a/arch/arc/mm/tlb.c b/arch/arc/mm/tlb.c index bdb295e09160..d0126fdfe2d8 100644 --- a/arch/arc/mm/tlb.c +++ b/arch/arc/mm/tlb.c @@ -53,6 +53,8 @@ #include <linux/module.h> #include <linux/bug.h> +#include <linux/mm_types.h> + #include <asm/arcregs.h> #include <asm/setup.h> #include <asm/mmu_context.h> diff --git a/arch/arc/plat-eznps/Kconfig b/arch/arc/plat-eznps/Kconfig index 1d175cc6ad6d..1595a38e50cd 100644 --- a/arch/arc/plat-eznps/Kconfig +++ b/arch/arc/plat-eznps/Kconfig @@ -5,7 +5,6 @@ menuconfig ARC_PLAT_EZNPS bool "\"EZchip\" ARC dev platform" - select ARC_HAS_COH_CACHES if SMP select CPU_BIG_ENDIAN select CLKSRC_NPS select EZNPS_GIC diff --git a/arch/arc/plat-sim/Kconfig b/arch/arc/plat-sim/Kconfig index 18e39fcc488a..ac6af96a82f3 100644 --- a/arch/arc/plat-sim/Kconfig +++ b/arch/arc/plat-sim/Kconfig @@ -8,7 +8,6 @@ menuconfig ARC_PLAT_SIM bool "ARC nSIM based simulation virtual platforms" - select ARC_HAS_COH_CACHES if SMP help Support for nSIM based ARC simulation platforms This includes the standalone nSIM (uart only) vs. System C OSCI VP |