diff options
Diffstat (limited to 'arch')
141 files changed, 1550 insertions, 823 deletions
diff --git a/arch/Kconfig b/arch/Kconfig index 467dfa35bf96..76c0b54443b1 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -538,16 +538,10 @@ config HAVE_CC_STACKPROTECTOR - its compiler supports the -fstack-protector option - it has implemented a stack canary (e.g. __stack_chk_guard) -config CC_STACKPROTECTOR - def_bool n - help - Set when a stack-protector mode is enabled, so that the build - can enable kernel-side support for the GCC feature. - choice prompt "Stack Protector buffer overflow detection" depends on HAVE_CC_STACKPROTECTOR - default CC_STACKPROTECTOR_NONE + default CC_STACKPROTECTOR_AUTO help This option turns on the "stack-protector" GCC feature. This feature puts, at the beginning of functions, a canary value on @@ -564,7 +558,6 @@ config CC_STACKPROTECTOR_NONE config CC_STACKPROTECTOR_REGULAR bool "Regular" - select CC_STACKPROTECTOR help Functions will have the stack-protector canary logic added if they have an 8-byte or larger character array on the stack. @@ -578,7 +571,6 @@ config CC_STACKPROTECTOR_REGULAR config CC_STACKPROTECTOR_STRONG bool "Strong" - select CC_STACKPROTECTOR help Functions will have the stack-protector canary logic added in any of the following conditions: @@ -596,6 +588,12 @@ config CC_STACKPROTECTOR_STRONG about 20% of all kernel functions, which increases the kernel code size by about 2%. +config CC_STACKPROTECTOR_AUTO + bool "Automatic" + help + If the compiler supports it, the best available stack-protector + option will be chosen. + endchoice config THIN_ARCHIVES diff --git a/arch/alpha/kernel/console.c b/arch/alpha/kernel/console.c index 8e9a41966881..5476279329a6 100644 --- a/arch/alpha/kernel/console.c +++ b/arch/alpha/kernel/console.c @@ -21,6 +21,7 @@ struct pci_controller *pci_vga_hose; static struct resource alpha_vga = { .name = "alpha-vga+", + .flags = IORESOURCE_IO, .start = 0x3C0, .end = 0x3DF }; diff --git a/arch/arm/boot/dts/omap3-n900.dts b/arch/arm/boot/dts/omap3-n900.dts index 72c765a3b354..ab930581fc7a 100644 --- a/arch/arm/boot/dts/omap3-n900.dts +++ b/arch/arm/boot/dts/omap3-n900.dts @@ -780,6 +780,8 @@ reset-gpio = <&gpio4 6 GPIO_ACTIVE_HIGH>; /* 102 */ + lens-focus = <&ad5820>; + port { csi_cam1: endpoint { bus-type = <3>; /* CCP2 */ diff --git a/arch/arm/include/asm/bitops.h b/arch/arm/include/asm/bitops.h index ce5ee762ed66..4cab9bb823fb 100644 --- a/arch/arm/include/asm/bitops.h +++ b/arch/arm/include/asm/bitops.h @@ -338,6 +338,7 @@ static inline int find_next_bit_le(const void *p, int size, int offset) #endif +#include <asm-generic/bitops/find.h> #include <asm-generic/bitops/le.h> /* diff --git a/arch/arm/include/asm/pci.h b/arch/arm/include/asm/pci.h index 960d9dc4f380..1f0de808d111 100644 --- a/arch/arm/include/asm/pci.h +++ b/arch/arm/include/asm/pci.h @@ -10,10 +10,7 @@ extern unsigned long pcibios_min_io; extern unsigned long pcibios_min_mem; #define PCIBIOS_MIN_MEM pcibios_min_mem -static inline int pcibios_assign_all_busses(void) -{ - return pci_has_flag(PCI_REASSIGN_ALL_RSRC); -} +#define pcibios_assign_all_busses() pci_has_flag(PCI_REASSIGN_ALL_BUS) #ifdef CONFIG_PCI_DOMAINS static inline int pci_proc_domain(struct pci_bus *bus) diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c index 0cd0aefb3a8f..ed46ca69813d 100644 --- a/arch/arm/kernel/bios32.c +++ b/arch/arm/kernel/bios32.c @@ -527,7 +527,7 @@ void pci_common_init_dev(struct device *parent, struct hw_pci *hw) struct pci_sys_data *sys; LIST_HEAD(head); - pci_add_flags(PCI_REASSIGN_ALL_RSRC); + pci_add_flags(PCI_REASSIGN_ALL_BUS); if (hw->preinit) hw->preinit(); pcibios_init_hw(parent, hw, &head); diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig index 9b49867154bf..6b32dc527edc 100644 --- a/arch/arm/mach-mvebu/Kconfig +++ b/arch/arm/mach-mvebu/Kconfig @@ -10,7 +10,6 @@ menuconfig ARCH_MVEBU select ZONE_DMA if ARM_LPAE select GPIOLIB select PCI_QUIRKS if PCI - select OF_ADDRESS_PCI if ARCH_MVEBU diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 53612879fe56..7381eeb7ef8e 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -16,6 +16,7 @@ config ARM64 select ARCH_HAS_GCOV_PROFILE_ALL select ARCH_HAS_GIGANTIC_PAGE if (MEMORY_ISOLATION && COMPACTION) || CMA select ARCH_HAS_KCOV + select ARCH_HAS_MEMBARRIER_SYNC_CORE select ARCH_HAS_SET_MEMORY select ARCH_HAS_SG_CHAIN select ARCH_HAS_STRICT_KERNEL_RWX diff --git a/arch/arm64/include/asm/kasan.h b/arch/arm64/include/asm/kasan.h index e266f80e45b7..8758bb008436 100644 --- a/arch/arm64/include/asm/kasan.h +++ b/arch/arm64/include/asm/kasan.h @@ -12,7 +12,8 @@ /* * KASAN_SHADOW_START: beginning of the kernel virtual addresses. - * KASAN_SHADOW_END: KASAN_SHADOW_START + 1/8 of kernel virtual addresses. + * KASAN_SHADOW_END: KASAN_SHADOW_START + 1/N of kernel virtual addresses, + * where N = (1 << KASAN_SHADOW_SCALE_SHIFT). */ #define KASAN_SHADOW_START (VA_START) #define KASAN_SHADOW_END (KASAN_SHADOW_START + KASAN_SHADOW_SIZE) @@ -20,14 +21,16 @@ /* * This value is used to map an address to the corresponding shadow * address by the following formula: - * shadow_addr = (address >> 3) + KASAN_SHADOW_OFFSET; + * shadow_addr = (address >> KASAN_SHADOW_SCALE_SHIFT) + KASAN_SHADOW_OFFSET * - * (1 << 61) shadow addresses - [KASAN_SHADOW_OFFSET,KASAN_SHADOW_END] - * cover all 64-bits of virtual addresses. So KASAN_SHADOW_OFFSET - * should satisfy the following equation: - * KASAN_SHADOW_OFFSET = KASAN_SHADOW_END - (1ULL << 61) + * (1 << (64 - KASAN_SHADOW_SCALE_SHIFT)) shadow addresses that lie in range + * [KASAN_SHADOW_OFFSET, KASAN_SHADOW_END) cover all 64-bits of virtual + * addresses. So KASAN_SHADOW_OFFSET should satisfy the following equation: + * KASAN_SHADOW_OFFSET = KASAN_SHADOW_END - + * (1ULL << (64 - KASAN_SHADOW_SCALE_SHIFT)) */ -#define KASAN_SHADOW_OFFSET (KASAN_SHADOW_END - (1ULL << (64 - 3))) +#define KASAN_SHADOW_OFFSET (KASAN_SHADOW_END - (1ULL << \ + (64 - KASAN_SHADOW_SCALE_SHIFT))) void kasan_init(void); void kasan_copy_shadow(pgd_t *pgdir); diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h index d4bae7d6e0d8..50fa96a49792 100644 --- a/arch/arm64/include/asm/memory.h +++ b/arch/arm64/include/asm/memory.h @@ -85,7 +85,8 @@ * stack size when KASAN is in use. */ #ifdef CONFIG_KASAN -#define KASAN_SHADOW_SIZE (UL(1) << (VA_BITS - 3)) +#define KASAN_SHADOW_SCALE_SHIFT 3 +#define KASAN_SHADOW_SIZE (UL(1) << (VA_BITS - KASAN_SHADOW_SCALE_SHIFT)) #define KASAN_THREAD_SHIFT 1 #else #define KASAN_SHADOW_SIZE (0) diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S index b34e717d7597..cccd2788e631 100644 --- a/arch/arm64/kernel/entry.S +++ b/arch/arm64/kernel/entry.S @@ -324,6 +324,10 @@ alternative_else_nop_endif ldp x28, x29, [sp, #16 * 14] ldr lr, [sp, #S_LR] add sp, sp, #S_FRAME_SIZE // restore sp + /* + * ARCH_HAS_MEMBARRIER_SYNC_CORE rely on eret context synchronization + * when returning from IPI handler, and when returning to user-space. + */ .if \el == 0 alternative_insn eret, nop, ARM64_UNMAP_KERNEL_AT_EL0 diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c index 3affca3dd96a..75b220ba73a3 100644 --- a/arch/arm64/kernel/perf_event.c +++ b/arch/arm64/kernel/perf_event.c @@ -925,9 +925,8 @@ static void __armv8pmu_probe_pmu(void *info) pmceid[0] = read_sysreg(pmceid0_el0); pmceid[1] = read_sysreg(pmceid1_el0); - bitmap_from_u32array(cpu_pmu->pmceid_bitmap, - ARMV8_PMUV3_MAX_COMMON_EVENTS, pmceid, - ARRAY_SIZE(pmceid)); + bitmap_from_arr32(cpu_pmu->pmceid_bitmap, + pmceid, ARMV8_PMUV3_MAX_COMMON_EVENTS); } static int armv8pmu_probe_pmu(struct arm_pmu *cpu_pmu) diff --git a/arch/arm64/mm/kasan_init.c b/arch/arm64/mm/kasan_init.c index acba49fb5aac..6e02e6fb4c7b 100644 --- a/arch/arm64/mm/kasan_init.c +++ b/arch/arm64/mm/kasan_init.c @@ -135,7 +135,8 @@ static void __init kasan_pgd_populate(unsigned long addr, unsigned long end, /* The early shadow maps everything to a single page of zeroes */ asmlinkage void __init kasan_early_init(void) { - BUILD_BUG_ON(KASAN_SHADOW_OFFSET != KASAN_SHADOW_END - (1UL << 61)); + BUILD_BUG_ON(KASAN_SHADOW_OFFSET != + KASAN_SHADOW_END - (1UL << (64 - KASAN_SHADOW_SCALE_SHIFT))); BUILD_BUG_ON(!IS_ALIGNED(KASAN_SHADOW_START, PGDIR_SIZE)); BUILD_BUG_ON(!IS_ALIGNED(KASAN_SHADOW_END, PGDIR_SIZE)); kasan_pgd_populate(KASAN_SHADOW_START, KASAN_SHADOW_END, NUMA_NO_NODE, diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c index b44992ec9643..4e369dfb83b1 100644 --- a/arch/arm64/mm/mmu.c +++ b/arch/arm64/mm/mmu.c @@ -685,12 +685,14 @@ int kern_addr_valid(unsigned long addr) } #ifdef CONFIG_SPARSEMEM_VMEMMAP #if !ARM64_SWAPPER_USES_SECTION_MAPS -int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node) +int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node, + struct vmem_altmap *altmap) { return vmemmap_populate_basepages(start, end, node); } #else /* !ARM64_SWAPPER_USES_SECTION_MAPS */ -int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node) +int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node, + struct vmem_altmap *altmap) { unsigned long addr = start; unsigned long next; @@ -725,7 +727,8 @@ int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node) return 0; } #endif /* CONFIG_ARM64_64K_PAGES */ -void vmemmap_free(unsigned long start, unsigned long end) +void vmemmap_free(unsigned long start, unsigned long end, + struct vmem_altmap *altmap) { } #endif /* CONFIG_SPARSEMEM_VMEMMAP */ diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c index c44f002e8f6b..858602494096 100644 --- a/arch/ia64/kernel/perfmon.c +++ b/arch/ia64/kernel/perfmon.c @@ -2610,17 +2610,10 @@ pfm_get_task(pfm_context_t *ctx, pid_t pid, struct task_struct **task) if (pid < 2) return -EPERM; if (pid != task_pid_vnr(current)) { - - read_lock(&tasklist_lock); - - p = find_task_by_vpid(pid); - /* make sure task cannot go away while we operate on it */ - if (p) get_task_struct(p); - - read_unlock(&tasklist_lock); - - if (p == NULL) return -ESRCH; + p = find_get_task_by_vpid(pid); + if (!p) + return -ESRCH; } ret = pfm_task_incompatible(ctx, p); diff --git a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c index ac46f0d60b66..7d9bd20319ff 100644 --- a/arch/ia64/mm/discontig.c +++ b/arch/ia64/mm/discontig.c @@ -754,12 +754,14 @@ void arch_refresh_nodedata(int update_node, pg_data_t *update_pgdat) #endif #ifdef CONFIG_SPARSEMEM_VMEMMAP -int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node) +int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node, + struct vmem_altmap *altmap) { return vmemmap_populate_basepages(start, end, node); } -void vmemmap_free(unsigned long start, unsigned long end) +void vmemmap_free(unsigned long start, unsigned long end, + struct vmem_altmap *altmap) { } #endif diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c index 7af4e05bb61e..18278b448530 100644 --- a/arch/ia64/mm/init.c +++ b/arch/ia64/mm/init.c @@ -501,7 +501,7 @@ virtual_memmap_init(u64 start, u64 end, void *arg) if (map_start < map_end) memmap_init_zone((unsigned long)(map_end - map_start), args->nid, args->zone, page_to_pfn(map_start), - MEMMAP_EARLY); + MEMMAP_EARLY, NULL); return 0; } @@ -509,9 +509,10 @@ void __meminit memmap_init (unsigned long size, int nid, unsigned long zone, unsigned long start_pfn) { - if (!vmem_map) - memmap_init_zone(size, nid, zone, start_pfn, MEMMAP_EARLY); - else { + if (!vmem_map) { + memmap_init_zone(size, nid, zone, start_pfn, MEMMAP_EARLY, + NULL); + } else { struct page *start; struct memmap_init_callback_data args; @@ -647,13 +648,14 @@ mem_init (void) } #ifdef CONFIG_MEMORY_HOTPLUG -int arch_add_memory(int nid, u64 start, u64 size, bool want_memblock) +int arch_add_memory(int nid, u64 start, u64 size, struct vmem_altmap *altmap, + bool want_memblock) { unsigned long start_pfn = start >> PAGE_SHIFT; unsigned long nr_pages = size >> PAGE_SHIFT; int ret; - ret = __add_pages(nid, start_pfn, nr_pages, want_memblock); + ret = __add_pages(nid, start_pfn, nr_pages, altmap, want_memblock); if (ret) printk("%s: Problem encountered in __add_pages() as ret=%d\n", __func__, ret); @@ -662,7 +664,7 @@ int arch_add_memory(int nid, u64 start, u64 size, bool want_memblock) } #ifdef CONFIG_MEMORY_HOTREMOVE -int arch_remove_memory(u64 start, u64 size) +int arch_remove_memory(u64 start, u64 size, struct vmem_altmap *altmap) { unsigned long start_pfn = start >> PAGE_SHIFT; unsigned long nr_pages = size >> PAGE_SHIFT; @@ -670,7 +672,7 @@ int arch_remove_memory(u64 start, u64 size) int ret; zone = page_zone(pfn_to_page(start_pfn)); - ret = __remove_pages(zone, start_pfn, nr_pages); + ret = __remove_pages(zone, start_pfn, nr_pages, altmap); if (ret) pr_warn("%s: Problem encountered in __remove_pages() as" " ret=%d\n", __func__, ret); diff --git a/arch/m68k/include/asm/bitops.h b/arch/m68k/include/asm/bitops.h index dda58cfe8c22..93b47b1f6fb4 100644 --- a/arch/m68k/include/asm/bitops.h +++ b/arch/m68k/include/asm/bitops.h @@ -311,7 +311,6 @@ static inline int bfchg_mem_test_and_change_bit(int nr, * functions. */ #if defined(CONFIG_CPU_HAS_NO_BITFIELDS) -#include <asm-generic/bitops/find.h> #include <asm-generic/bitops/ffz.h> #else @@ -441,6 +440,8 @@ static inline unsigned long ffz(unsigned long word) #endif +#include <asm-generic/bitops/find.h> + #ifdef __KERNEL__ #if defined(CONFIG_CPU_HAS_NO_BITFIELDS) diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index ab98569994f0..449397c60b56 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -7,8 +7,6 @@ config MIPS select ARCH_DISCARD_MEMBLOCK select ARCH_HAS_ELF_RANDOMIZE select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST - select ARCH_MIGHT_HAVE_PC_PARPORT - select ARCH_MIGHT_HAVE_PC_SERIO select ARCH_SUPPORTS_UPROBES select ARCH_USE_BUILTIN_BSWAP select ARCH_USE_CMPXCHG_LOCKREF if 64BIT @@ -119,12 +117,12 @@ config MIPS_GENERIC select SYS_SUPPORTS_MULTITHREADING select SYS_SUPPORTS_RELOCATABLE select SYS_SUPPORTS_SMARTMIPS - select USB_EHCI_BIG_ENDIAN_DESC if BIG_ENDIAN - select USB_EHCI_BIG_ENDIAN_MMIO if BIG_ENDIAN - select USB_OHCI_BIG_ENDIAN_DESC if BIG_ENDIAN - select USB_OHCI_BIG_ENDIAN_MMIO if BIG_ENDIAN - select USB_UHCI_BIG_ENDIAN_DESC if BIG_ENDIAN - select USB_UHCI_BIG_ENDIAN_MMIO if BIG_ENDIAN + select USB_EHCI_BIG_ENDIAN_DESC if CPU_BIG_ENDIAN + select USB_EHCI_BIG_ENDIAN_MMIO if CPU_BIG_ENDIAN + select USB_OHCI_BIG_ENDIAN_DESC if CPU_BIG_ENDIAN + select USB_OHCI_BIG_ENDIAN_MMIO if CPU_BIG_ENDIAN + select USB_UHCI_BIG_ENDIAN_DESC if CPU_BIG_ENDIAN + select USB_UHCI_BIG_ENDIAN_MMIO if CPU_BIG_ENDIAN select USE_OF help Select this to build a kernel which aims to support multiple boards, @@ -253,6 +251,7 @@ config BCM47XX select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_LITTLE_ENDIAN select SYS_SUPPORTS_MIPS16 + select SYS_SUPPORTS_ZBOOT select SYS_HAS_EARLY_PRINTK select USE_GENERIC_EARLY_PRINTK_8250 select GPIOLIB @@ -341,6 +340,8 @@ config MACH_DECSTATION config MACH_JAZZ bool "Jazz family of machines" + select ARCH_MIGHT_HAVE_PC_PARPORT + select ARCH_MIGHT_HAVE_PC_SERIO select FW_ARC select FW_ARC32 select ARCH_MAY_HAVE_PC_FDC @@ -476,6 +477,8 @@ config MACH_PISTACHIO config MIPS_MALTA bool "MIPS Malta board" select ARCH_MAY_HAVE_PC_FDC + select ARCH_MIGHT_HAVE_PC_PARPORT + select ARCH_MIGHT_HAVE_PC_SERIO select BOOT_ELF32 select BOOT_RAW select BUILTIN_DTB @@ -613,6 +616,7 @@ config SGI_IP22 bool "SGI IP22 (Indy/Indigo2)" select FW_ARC select FW_ARC32 + select ARCH_MIGHT_HAVE_PC_SERIO select BOOT_ELF32 select CEVT_R4K select CSRC_R4K @@ -675,6 +679,7 @@ config SGI_IP28 bool "SGI IP28 (Indigo2 R10k)" select FW_ARC select FW_ARC64 + select ARCH_MIGHT_HAVE_PC_SERIO select BOOT_ELF64 select CEVT_R4K select CSRC_R4K @@ -824,6 +829,8 @@ config SNI_RM select FW_ARC32 if CPU_LITTLE_ENDIAN select FW_SNIPROM if CPU_BIG_ENDIAN select ARCH_MAY_HAVE_PC_FDC + select ARCH_MIGHT_HAVE_PC_PARPORT + select ARCH_MIGHT_HAVE_PC_SERIO select BOOT_ELF32 select CEVT_R4K select CSRC_R4K diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 9f6a26d72f9f..d1ca839c3981 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -216,6 +216,12 @@ cflags-$(toolchain-msa) += -DTOOLCHAIN_SUPPORTS_MSA endif toolchain-virt := $(call cc-option-yn,$(mips-cflags) -mvirt) cflags-$(toolchain-virt) += -DTOOLCHAIN_SUPPORTS_VIRT +# For -mmicromips, use -Wa,-fatal-warnings to catch unsupported -mxpa which +# only warns +xpa-cflags-y := $(mips-cflags) +xpa-cflags-$(micromips-ase) += -mmicromips -Wa$(comma)-fatal-warnings +toolchain-xpa := $(call cc-option-yn,$(xpa-cflags-y) -mxpa) +cflags-$(toolchain-xpa) += -DTOOLCHAIN_SUPPORTS_XPA # # Firmware support @@ -228,7 +234,7 @@ libs-y += arch/mips/fw/lib/ # # Kernel compression # -ifdef SYS_SUPPORTS_ZBOOT +ifdef CONFIG_SYS_SUPPORTS_ZBOOT COMPRESSION_FNAME = vmlinuz else COMPRESSION_FNAME = vmlinux diff --git a/arch/mips/bcm47xx/Platform b/arch/mips/bcm47xx/Platform index 874b7ca4cd11..70783b75fd9d 100644 --- a/arch/mips/bcm47xx/Platform +++ b/arch/mips/bcm47xx/Platform @@ -5,3 +5,4 @@ platform-$(CONFIG_BCM47XX) += bcm47xx/ cflags-$(CONFIG_BCM47XX) += \ -I$(srctree)/arch/mips/include/asm/mach-bcm47xx load-$(CONFIG_BCM47XX) := 0xffffffff80001000 +zload-$(CONFIG_BCM47XX) += 0xffffffff80400000 diff --git a/arch/mips/boot/compressed/Makefile b/arch/mips/boot/compressed/Makefile index c675eece389a..adce180f3ee4 100644 --- a/arch/mips/boot/compressed/Makefile +++ b/arch/mips/boot/compressed/Makefile @@ -133,4 +133,8 @@ vmlinuz.srec: vmlinuz uzImage.bin: vmlinuz.bin FORCE $(call if_changed,uimage,none) -clean-files := $(objtree)/vmlinuz $(objtree)/vmlinuz.{32,ecoff,bin,srec} +clean-files += $(objtree)/vmlinuz +clean-files += $(objtree)/vmlinuz.32 +clean-files += $(objtree)/vmlinuz.ecoff +clean-files += $(objtree)/vmlinuz.bin +clean-files += $(objtree)/vmlinuz.srec diff --git a/arch/mips/boot/dts/ingenic/Makefile b/arch/mips/boot/dts/ingenic/Makefile index 6a31759839b4..5b1361a89e02 100644 --- a/arch/mips/boot/dts/ingenic/Makefile +++ b/arch/mips/boot/dts/ingenic/Makefile @@ -1,5 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 dtb-$(CONFIG_JZ4740_QI_LB60) += qi_lb60.dtb +dtb-$(CONFIG_JZ4770_GCW0) += gcw0.dtb dtb-$(CONFIG_JZ4780_CI20) += ci20.dtb obj-y += $(patsubst %.dtb, %.dtb.o, $(dtb-y)) diff --git a/arch/mips/boot/dts/ingenic/gcw0.dts b/arch/mips/boot/dts/ingenic/gcw0.dts new file mode 100644 index 000000000000..35f0291e8d38 --- /dev/null +++ b/arch/mips/boot/dts/ingenic/gcw0.dts @@ -0,0 +1,62 @@ +// SPDX-License-Identifier: GPL-2.0 +/dts-v1/; + +#include "jz4770.dtsi" + +/ { + compatible = "gcw,zero", "ingenic,jz4770"; + model = "GCW Zero"; + + aliases { + serial0 = &uart0; + serial1 = &uart1; + serial2 = &uart2; + serial3 = &uart3; + }; + + chosen { + stdout-path = "serial2:57600n8"; + }; + + board { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + otg_phy: otg-phy { + compatible = "usb-nop-xceiv"; + clocks = <&cgu JZ4770_CLK_OTG_PHY>; + clock-names = "main_clk"; + }; + }; +}; + +&ext { + clock-frequency = <12000000>; +}; + +&uart2 { + status = "okay"; +}; + +&cgu { + /* Put high-speed peripherals under PLL1, such that we can change the + * PLL0 frequency on demand without having to suspend peripherals. + * We use a rate of 432 MHz, which is the least common multiple of + * 27 MHz (required by TV encoder) and 48 MHz (required by USB host). + */ + assigned-clocks = + <&cgu JZ4770_CLK_PLL1>, + <&cgu JZ4770_CLK_UHC>; + assigned-clock-parents = + <0>, + <&cgu JZ4770_CLK_PLL1>; + assigned-clock-rates = + <432000000>; +}; + +&uhc { + /* The WiFi module is connected to the UHC. */ + status = "okay"; +}; diff --git a/arch/mips/boot/dts/ingenic/jz4770.dtsi b/arch/mips/boot/dts/ingenic/jz4770.dtsi new file mode 100644 index 000000000000..7c2804f3f5f1 --- /dev/null +++ b/arch/mips/boot/dts/ingenic/jz4770.dtsi @@ -0,0 +1,212 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include <dt-bindings/clock/jz4770-cgu.h> + +/ { + #address-cells = <1>; + #size-cells = <1>; + compatible = "ingenic,jz4770"; + + cpuintc: interrupt-controller { + #address-cells = <0>; + #interrupt-cells = <1>; + interrupt-controller; + compatible = "mti,cpu-interrupt-controller"; + }; + + intc: interrupt-controller@10001000 { + compatible = "ingenic,jz4770-intc"; + reg = <0x10001000 0x40>; + + interrupt-controller; + #interrupt-cells = <1>; + + interrupt-parent = <&cpuintc>; + interrupts = <2>; + }; + + ext: ext { + compatible = "fixed-clock"; + #clock-cells = <0>; + }; + + osc32k: osc32k { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <32768>; + }; + + cgu: jz4770-cgu@10000000 { + compatible = "ingenic,jz4770-cgu"; + reg = <0x10000000 0x100>; + + clocks = <&ext>, <&osc32k>; + clock-names = "ext", "osc32k"; + + #clock-cells = <1>; + }; + + pinctrl: pin-controller@10010000 { + compatible = "ingenic,jz4770-pinctrl"; + reg = <0x10010000 0x600>; + + #address-cells = <1>; + #size-cells = <0>; + + gpa: gpio@0 { + compatible = "ingenic,jz4770-gpio"; + reg = <0>; + + gpio-controller; + gpio-ranges = <&pinctrl 0 0 32>; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + + interrupt-parent = <&intc>; + interrupts = <17>; + }; + + gpb: gpio@1 { + compatible = "ingenic,jz4770-gpio"; + reg = <1>; + + gpio-controller; + gpio-ranges = <&pinctrl 0 32 32>; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + + interrupt-parent = <&intc>; + interrupts = <16>; + }; + + gpc: gpio@2 { + compatible = "ingenic,jz4770-gpio"; + reg = <2>; + + gpio-controller; + gpio-ranges = <&pinctrl 0 64 32>; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + + interrupt-parent = <&intc>; + interrupts = <15>; + }; + + gpd: gpio@3 { + compatible = "ingenic,jz4770-gpio"; + reg = <3>; + + gpio-controller; + gpio-ranges = <&pinctrl 0 96 32>; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + + interrupt-parent = <&intc>; + interrupts = <14>; + }; + + gpe: gpio@4 { + compatible = "ingenic,jz4770-gpio"; + reg = <4>; + + gpio-controller; + gpio-ranges = <&pinctrl 0 128 32>; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + + interrupt-parent = <&intc>; + interrupts = <13>; + }; + + gpf: gpio@5 { + compatible = "ingenic,jz4770-gpio"; + reg = <5>; + + gpio-controller; + gpio-ranges = <&pinctrl 0 160 32>; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + + interrupt-parent = <&intc>; + interrupts = <12>; + }; + }; + + uart0: serial@10030000 { + compatible = "ingenic,jz4770-uart"; + reg = <0x10030000 0x100>; + + clocks = <&ext>, <&cgu JZ4770_CLK_UART0>; + clock-names = "baud", "module"; + + interrupt-parent = <&intc>; + interrupts = <5>; + + status = "disabled"; + }; + + uart1: serial@10031000 { + compatible = "ingenic,jz4770-uart"; + reg = <0x10031000 0x100>; + + clocks = <&ext>, <&cgu JZ4770_CLK_UART1>; + clock-names = "baud", "module"; + + interrupt-parent = <&intc>; + interrupts = <4>; + + status = "disabled"; + }; + + uart2: serial@10032000 { + compatible = "ingenic,jz4770-uart"; + reg = <0x10032000 0x100>; + + clocks = <&ext>, <&cgu JZ4770_CLK_UART2>; + clock-names = "baud", "module"; + + interrupt-parent = <&intc>; + interrupts = <3>; + + status = "disabled"; + }; + + uart3: serial@10033000 { + compatible = "ingenic,jz4770-uart"; + reg = <0x10033000 0x100>; + + clocks = <&ext>, <&cgu JZ4770_CLK_UART3>; + clock-names = "baud", "module"; + + interrupt-parent = <&intc>; + interrupts = <2>; + + status = "disabled"; + }; + + uhc: uhc@13430000 { + compatible = "generic-ohci"; + reg = <0x13430000 0x1000>; + + clocks = <&cgu JZ4770_CLK_UHC>, <&cgu JZ4770_CLK_UHC_PHY>; + assigned-clocks = <&cgu JZ4770_CLK_UHC>; + assigned-clock-rates = <48000000>; + + interrupt-parent = <&intc>; + interrupts = <20>; + + status = "disabled"; + }; +}; diff --git a/arch/mips/configs/bigsur_defconfig b/arch/mips/configs/bigsur_defconfig index a55009edbb29..5e73fe755be6 100644 --- a/arch/mips/configs/bigsur_defconfig +++ b/arch/mips/configs/bigsur_defconfig @@ -153,7 +153,6 @@ CONFIG_SLIP_COMPRESSED=y CONFIG_SLIP_SMART=y CONFIG_SLIP_MODE_SLIP6=y # CONFIG_INPUT is not set -# CONFIG_SERIO_I8042 is not set CONFIG_SERIO_RAW=m # CONFIG_VT is not set CONFIG_SERIAL_NONSTANDARD=y diff --git a/arch/mips/configs/gcw0_defconfig b/arch/mips/configs/gcw0_defconfig new file mode 100644 index 000000000000..99ac1fa3b35f --- /dev/null +++ b/arch/mips/configs/gcw0_defconfig @@ -0,0 +1,27 @@ +CONFIG_MACH_INGENIC=y +CONFIG_JZ4770_GCW0=y +CONFIG_HIGHMEM=y +# CONFIG_BOUNCE is not set +CONFIG_PREEMPT_VOLUNTARY=y +# CONFIG_SECCOMP is not set +CONFIG_NO_HZ_IDLE=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_EMBEDDED=y +# CONFIG_BLK_DEV_BSG is not set +# CONFIG_SUSPEND is not set +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_NETDEVICES=y +CONFIG_SERIAL_8250=y +# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_INGENIC=y +CONFIG_USB=y +CONFIG_USB_OHCI_HCD=y +CONFIG_USB_OHCI_HCD_PLATFORM=y +CONFIG_NOP_USB_XCEIV=y +CONFIG_TMPFS=y diff --git a/arch/mips/configs/generic/board-ranchu.config b/arch/mips/configs/generic/board-ranchu.config new file mode 100644 index 000000000000..fee9ad4c5598 --- /dev/null +++ b/arch/mips/configs/generic/board-ranchu.config @@ -0,0 +1,30 @@ +CONFIG_VIRT_BOARD_RANCHU=y + +CONFIG_BATTERY_GOLDFISH=y +CONFIG_FB=y +CONFIG_FB_GOLDFISH=y +CONFIG_GOLDFISH=y +CONFIG_STAGING=y +CONFIG_GOLDFISH_AUDIO=y +CONFIG_GOLDFISH_PIC=y +CONFIG_GOLDFISH_PIPE=y +CONFIG_GOLDFISH_TTY=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_GOLDFISH=y + +CONFIG_INPUT_EVDEV=y +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_GOLDFISH_EVENTS=y + +CONFIG_MAGIC_SYSRQ=y +CONFIG_POWER_SUPPLY=y +CONFIG_POWER_RESET=y +CONFIG_POWER_RESET_SYSCON=y +CONFIG_POWER_RESET_SYSCON_POWEROFF=y + +CONFIG_VIRTIO_BLK=y +CONFIG_VIRTIO_CONSOLE=y +CONFIG_VIRTIO_MMIO=y +CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y +CONFIG_NETDEVICES=y +CONFIG_VIRTIO_NET=y diff --git a/arch/mips/configs/ip27_defconfig b/arch/mips/configs/ip27_defconfig index a0d593248668..91a9c13e2c82 100644 --- a/arch/mips/configs/ip27_defconfig +++ b/arch/mips/configs/ip27_defconfig @@ -252,7 +252,6 @@ CONFIG_RT2800PCI=m CONFIG_WL12XX=m CONFIG_WL1251=m # CONFIG_INPUT is not set -# CONFIG_SERIO_I8042 is not set CONFIG_SERIO_LIBPS2=m CONFIG_SERIO_RAW=m CONFIG_SERIO_ALTERA_PS2=m diff --git a/arch/mips/configs/ip32_defconfig b/arch/mips/configs/ip32_defconfig index 1e26e58b9dc3..ebff297328ae 100644 --- a/arch/mips/configs/ip32_defconfig +++ b/arch/mips/configs/ip32_defconfig @@ -75,7 +75,6 @@ CONFIG_DE2104X=m CONFIG_TULIP=m CONFIG_TULIP_MMIO=y CONFIG_INPUT_EVDEV=m -# CONFIG_SERIO_I8042 is not set CONFIG_SERIO_MACEPS2=y CONFIG_SERIO_RAW=y # CONFIG_CONSOLE_TRANSLATIONS is not set diff --git a/arch/mips/configs/malta_defconfig b/arch/mips/configs/malta_defconfig index 396408404487..df8a9a15ca83 100644 --- a/arch/mips/configs/malta_defconfig +++ b/arch/mips/configs/malta_defconfig @@ -312,9 +312,8 @@ CONFIG_HOSTAP_PCI=m CONFIG_IPW2100=m CONFIG_IPW2100_MONITOR=y CONFIG_LIBERTAS=m -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -# CONFIG_SERIO_I8042 is not set +CONFIG_INPUT_MOUSEDEV=y +CONFIG_MOUSE_PS2_ELANTECH=y CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_POWER_RESET=y diff --git a/arch/mips/configs/malta_kvm_defconfig b/arch/mips/configs/malta_kvm_defconfig index 5691673a3327..14df9ef15d40 100644 --- a/arch/mips/configs/malta_kvm_defconfig +++ b/arch/mips/configs/malta_kvm_defconfig @@ -324,9 +324,7 @@ CONFIG_HOSTAP_PCI=m CONFIG_IPW2100=m CONFIG_IPW2100_MONITOR=y CONFIG_LIBERTAS=m -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -# CONFIG_SERIO_I8042 is not set +CONFIG_INPUT_MOUSEDEV=y CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_POWER_RESET=y diff --git a/arch/mips/configs/malta_kvm_guest_defconfig b/arch/mips/configs/malta_kvm_guest_defconfig index e9cadb37d684..25092e344574 100644 --- a/arch/mips/configs/malta_kvm_guest_defconfig +++ b/arch/mips/configs/malta_kvm_guest_defconfig @@ -326,9 +326,7 @@ CONFIG_HOSTAP_PCI=m CONFIG_IPW2100=m CONFIG_IPW2100_MONITOR=y CONFIG_LIBERTAS=m -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -# CONFIG_SERIO_I8042 is not set +CONFIG_INPUT_MOUSEDEV=y CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_POWER_RESET=y diff --git a/arch/mips/configs/malta_qemu_32r6_defconfig b/arch/mips/configs/malta_qemu_32r6_defconfig index 77145ecaa23b..210bf609f785 100644 --- a/arch/mips/configs/malta_qemu_32r6_defconfig +++ b/arch/mips/configs/malta_qemu_32r6_defconfig @@ -126,6 +126,7 @@ CONFIG_PCNET32=y # CONFIG_NET_VENDOR_VIA is not set # CONFIG_NET_VENDOR_WIZNET is not set # CONFIG_WLAN is not set +CONFIG_INPUT_MOUSEDEV=y # CONFIG_VT is not set CONFIG_LEGACY_PTY_COUNT=4 CONFIG_SERIAL_8250=y diff --git a/arch/mips/configs/maltaaprp_defconfig b/arch/mips/configs/maltaaprp_defconfig index cc2687cfdc13..e5934aa98397 100644 --- a/arch/mips/configs/maltaaprp_defconfig +++ b/arch/mips/configs/maltaaprp_defconfig @@ -126,6 +126,7 @@ CONFIG_PCNET32=y # CONFIG_NET_VENDOR_TOSHIBA is not set # CONFIG_NET_VENDOR_VIA is not set # CONFIG_WLAN is not set +CONFIG_INPUT_MOUSEDEV=y # CONFIG_VT is not set CONFIG_LEGACY_PTY_COUNT=16 CONFIG_SERIAL_8250=y diff --git a/arch/mips/configs/maltasmvp_defconfig b/arch/mips/configs/maltasmvp_defconfig index d8c8f5fb8918..cb2ca11c1789 100644 --- a/arch/mips/configs/maltasmvp_defconfig +++ b/arch/mips/configs/maltasmvp_defconfig @@ -127,6 +127,7 @@ CONFIG_PCNET32=y # CONFIG_NET_VENDOR_VIA is not set # CONFIG_NET_VENDOR_WIZNET is not set # CONFIG_WLAN is not set +CONFIG_INPUT_MOUSEDEV=y # CONFIG_VT is not set CONFIG_LEGACY_PTY_COUNT=4 CONFIG_SERIAL_8250=y diff --git a/arch/mips/configs/maltasmvp_eva_defconfig b/arch/mips/configs/maltasmvp_eva_defconfig index 04827bc9f87f..be29fcec69fc 100644 --- a/arch/mips/configs/maltasmvp_eva_defconfig +++ b/arch/mips/configs/maltasmvp_eva_defconfig @@ -130,6 +130,7 @@ CONFIG_PCNET32=y # CONFIG_NET_VENDOR_VIA is not set # CONFIG_NET_VENDOR_WIZNET is not set # CONFIG_WLAN is not set +CONFIG_INPUT_MOUSEDEV=y # CONFIG_VT is not set CONFIG_LEGACY_PTY_COUNT=4 CONFIG_SERIAL_8250=y diff --git a/arch/mips/configs/maltaup_defconfig b/arch/mips/configs/maltaup_defconfig index 7ea7c0ba2666..40462d4c90a0 100644 --- a/arch/mips/configs/maltaup_defconfig +++ b/arch/mips/configs/maltaup_defconfig @@ -125,6 +125,7 @@ CONFIG_PCNET32=y # CONFIG_NET_VENDOR_TOSHIBA is not set # CONFIG_NET_VENDOR_VIA is not set # CONFIG_WLAN is not set +CONFIG_INPUT_MOUSEDEV=y # CONFIG_VT is not set CONFIG_LEGACY_PTY_COUNT=16 CONFIG_SERIAL_8250=y diff --git a/arch/mips/configs/maltaup_xpa_defconfig b/arch/mips/configs/maltaup_xpa_defconfig index 2942610e4082..4e50176cb3df 100644 --- a/arch/mips/configs/maltaup_xpa_defconfig +++ b/arch/mips/configs/maltaup_xpa_defconfig @@ -321,9 +321,8 @@ CONFIG_HOSTAP_PCI=m CONFIG_IPW2100=m CONFIG_IPW2100_MONITOR=y CONFIG_LIBERTAS=m -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -# CONFIG_SERIO_I8042 is not set +CONFIG_INPUT_MOUSEDEV=y +CONFIG_MOUSE_PS2_ELANTECH=y CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_POWER_RESET=y diff --git a/arch/mips/configs/nlm_xlp_defconfig b/arch/mips/configs/nlm_xlp_defconfig index 7357248b3d7a..e8e1dd8e0e99 100644 --- a/arch/mips/configs/nlm_xlp_defconfig +++ b/arch/mips/configs/nlm_xlp_defconfig @@ -399,7 +399,6 @@ CONFIG_INPUT_EVDEV=y CONFIG_INPUT_EVBUG=m # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set -# CONFIG_SERIO_I8042 is not set CONFIG_SERIO_SERPORT=m CONFIG_SERIO_LIBPS2=y CONFIG_SERIO_RAW=m diff --git a/arch/mips/configs/nlm_xlr_defconfig b/arch/mips/configs/nlm_xlr_defconfig index 1e18fd7de209..c4477a4d40c1 100644 --- a/arch/mips/configs/nlm_xlr_defconfig +++ b/arch/mips/configs/nlm_xlr_defconfig @@ -332,7 +332,6 @@ CONFIG_INPUT_EVDEV=y CONFIG_INPUT_EVBUG=m # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set -# CONFIG_SERIO_I8042 is not set CONFIG_SERIO_SERPORT=m CONFIG_SERIO_LIBPS2=y CONFIG_SERIO_RAW=m diff --git a/arch/mips/configs/pnx8335_stb225_defconfig b/arch/mips/configs/pnx8335_stb225_defconfig index 81b5eb89446c..e73cdb08fc6e 100644 --- a/arch/mips/configs/pnx8335_stb225_defconfig +++ b/arch/mips/configs/pnx8335_stb225_defconfig @@ -49,7 +49,6 @@ CONFIG_INPUT_EVDEV=m CONFIG_INPUT_EVBUG=m # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set -# CONFIG_SERIO_I8042 is not set # CONFIG_VT_CONSOLE is not set CONFIG_SERIAL_PNX8XXX=y CONFIG_SERIAL_PNX8XXX_CONSOLE=y diff --git a/arch/mips/configs/sb1250_swarm_defconfig b/arch/mips/configs/sb1250_swarm_defconfig index c724bdd6a7e6..1edd8430ad61 100644 --- a/arch/mips/configs/sb1250_swarm_defconfig +++ b/arch/mips/configs/sb1250_swarm_defconfig @@ -65,7 +65,6 @@ CONFIG_NET_ETHERNET=y CONFIG_MII=y CONFIG_SB1250_MAC=y # CONFIG_INPUT is not set -# CONFIG_SERIO_I8042 is not set CONFIG_SERIO_RAW=m # CONFIG_VT is not set # CONFIG_HW_RANDOM is not set diff --git a/arch/mips/generic/Kconfig b/arch/mips/generic/Kconfig index 52e0286a1612..2ff3b17bfab1 100644 --- a/arch/mips/generic/Kconfig +++ b/arch/mips/generic/Kconfig @@ -49,4 +49,14 @@ config FIT_IMAGE_FDT_XILFPGA Enable this to include the FDT for the MIPSfpga platform from Imagination Technologies in the FIT kernel image. +config VIRT_BOARD_RANCHU + bool "Support Ranchu platform for Android emulator" + help + This enables support for the platform used by Android emulator. + + Ranchu platform consists of a set of virtual devices. This platform + enables emulation of variety of virtual configurations while using + Android emulator. Android emulator is based on Qemu, and contains + the support for the same set of virtual devices. + endif diff --git a/arch/mips/generic/Makefile b/arch/mips/generic/Makefile index 874967363dbb..5c31e0c4697d 100644 --- a/arch/mips/generic/Makefile +++ b/arch/mips/generic/Makefile @@ -15,3 +15,4 @@ obj-y += proc.o obj-$(CONFIG_YAMON_DT_SHIM) += yamon-dt.o obj-$(CONFIG_LEGACY_BOARD_SEAD3) += board-sead3.o obj-$(CONFIG_KEXEC) += kexec.o +obj-$(CONFIG_VIRT_BOARD_RANCHU) += board-ranchu.o diff --git a/arch/mips/generic/board-ranchu.c b/arch/mips/generic/board-ranchu.c new file mode 100644 index 000000000000..59a8c18fa2cc --- /dev/null +++ b/arch/mips/generic/board-ranchu.c @@ -0,0 +1,93 @@ +/* + * Support code for virtual Ranchu board for MIPS. + * + * Author: Miodrag Dinic <miodrag.dinic@mips.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include <linux/of_address.h> +#include <linux/types.h> + +#include <asm/machine.h> +#include <asm/mipsregs.h> +#include <asm/time.h> + +#define GOLDFISH_TIMER_LOW 0x00 +#define GOLDFISH_TIMER_HIGH 0x04 + +static __init u64 read_rtc_time(void __iomem *base) +{ + u32 time_low; + u32 time_high; + + /* + * Reading the low address latches the high value + * as well so there is no fear that we may read + * inaccurate high value. + */ + time_low = readl(base + GOLDFISH_TIMER_LOW); + time_high = readl(base + GOLDFISH_TIMER_HIGH); + + return ((u64)time_high << 32) | time_low; +} + +static __init unsigned int ranchu_measure_hpt_freq(void) +{ + u64 rtc_start, rtc_current, rtc_delta; + unsigned int start, count; + struct device_node *np; + void __iomem *rtc_base; + + np = of_find_compatible_node(NULL, NULL, "google,goldfish-rtc"); + if (!np) + panic("%s(): Failed to find 'google,goldfish-rtc' dt node!", + __func__); + + rtc_base = of_iomap(np, 0); + if (!rtc_base) + panic("%s(): Failed to ioremap Goldfish RTC base!", __func__); + + /* + * Poll the nanosecond resolution RTC for one + * second to calibrate the CPU frequency. + */ + rtc_start = read_rtc_time(rtc_base); + start = read_c0_count(); + + do { + rtc_current = read_rtc_time(rtc_base); + rtc_delta = rtc_current - rtc_start; + } while (rtc_delta < NSEC_PER_SEC); + + count = read_c0_count() - start; + + /* + * Make sure the frequency will be a round number. + * Without this correction, the returned value may vary + * between subsequent emulation executions. + * + * TODO: Set this value using device tree. + */ + count += 5000; + count -= count % 10000; + + iounmap(rtc_base); + + return count; +} + +static const struct of_device_id ranchu_of_match[] __initconst = { + { + .compatible = "mti,ranchu", + }, + {} +}; + +MIPS_MACHINE(ranchu) = { + .matches = ranchu_of_match, + .measure_hpt_freq = ranchu_measure_hpt_freq, +}; diff --git a/arch/mips/generic/irq.c b/arch/mips/generic/irq.c index 394f8161e462..cb7fdaeef426 100644 --- a/arch/mips/generic/irq.c +++ b/arch/mips/generic/irq.c @@ -22,10 +22,10 @@ int get_c0_fdc_int(void) { int mips_cpu_fdc_irq; - if (cpu_has_veic) - panic("Unimplemented!"); - else if (mips_gic_present()) + if (mips_gic_present()) mips_cpu_fdc_irq = gic_get_c0_fdc_int(); + else if (cpu_has_veic) + panic("Unimplemented!"); else if (cp0_fdc_irq >= 0) mips_cpu_fdc_irq = MIPS_CPU_IRQ_BASE + cp0_fdc_irq; else @@ -38,10 +38,10 @@ int get_c0_perfcount_int(void) { int mips_cpu_perf_irq; - if (cpu_has_veic) - panic("Unimplemented!"); - else if (mips_gic_present()) + if (mips_gic_present()) mips_cpu_perf_irq = gic_get_c0_perfcount_int(); + else if (cpu_has_veic) + panic("Unimplemented!"); else if (cp0_perfcount_irq >= 0) mips_cpu_perf_irq = MIPS_CPU_IRQ_BASE + cp0_perfcount_irq; else @@ -54,10 +54,10 @@ unsigned int get_c0_compare_int(void) { int mips_cpu_timer_irq; - if (cpu_has_veic) - panic("Unimplemented!"); - else if (mips_gic_present()) + if (mips_gic_present()) mips_cpu_timer_irq = gic_get_c0_compare_int(); + else if (cpu_has_veic) + panic("Unimplemented!"); else mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq; diff --git a/arch/mips/include/asm/bootinfo.h b/arch/mips/include/asm/bootinfo.h index e26a093bb17a..a301a8f4bc66 100644 --- a/arch/mips/include/asm/bootinfo.h +++ b/arch/mips/include/asm/bootinfo.h @@ -79,6 +79,8 @@ enum loongson_machine_type { */ #define MACH_INGENIC_JZ4730 0 /* JZ4730 SOC */ #define MACH_INGENIC_JZ4740 1 /* JZ4740 SOC */ +#define MACH_INGENIC_JZ4770 2 /* JZ4770 SOC */ +#define MACH_INGENIC_JZ4780 3 /* JZ4780 SOC */ extern char *system_type; const char *get_system_type(void); diff --git a/arch/mips/include/asm/checksum.h b/arch/mips/include/asm/checksum.h index 77cad232a1c6..e8161e4dfde7 100644 --- a/arch/mips/include/asm/checksum.h +++ b/arch/mips/include/asm/checksum.h @@ -110,7 +110,7 @@ __wsum csum_partial_copy_nocheck(const void *src, void *dst, */ static inline __sum16 csum_fold(__wsum csum) { - u32 sum = (__force u32)csum;; + u32 sum = (__force u32)csum; sum += (sum << 16); csum = (sum < csum); diff --git a/arch/mips/include/asm/mach-loongson64/boot_param.h b/arch/mips/include/asm/mach-loongson64/boot_param.h index 4f69f08717f6..8c286bedff3e 100644 --- a/arch/mips/include/asm/mach-loongson64/boot_param.h +++ b/arch/mips/include/asm/mach-loongson64/boot_param.h @@ -4,7 +4,7 @@ #define SYSTEM_RAM_LOW 1 #define SYSTEM_RAM_HIGH 2 -#define MEM_RESERVED 3 +#define SYSTEM_RAM_RESERVED 3 #define PCI_IO 4 #define PCI_MEM 5 #define LOONGSON_CFG_REG 6 diff --git a/arch/mips/include/asm/machine.h b/arch/mips/include/asm/machine.h index e0d9b373d415..f83879dadd1e 100644 --- a/arch/mips/include/asm/machine.h +++ b/arch/mips/include/asm/machine.h @@ -52,7 +52,7 @@ mips_machine_is_compatible(const struct mips_machine *mach, const void *fdt) if (!mach->matches) return NULL; - for (match = mach->matches; match->compatible; match++) { + for (match = mach->matches; match->compatible[0]; match++) { if (fdt_node_check_compatible(fdt, 0, match->compatible) == 0) return match; } diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h index 6b1f1ad0542c..858752dac337 100644 --- a/arch/mips/include/asm/mipsregs.h +++ b/arch/mips/include/asm/mipsregs.h @@ -1181,6 +1181,89 @@ static inline int mm_insn_16bit(u16 insn) #endif /* + * parse_r var, r - Helper assembler macro for parsing register names. + * + * This converts the register name in $n form provided in \r to the + * corresponding register number, which is assigned to the variable \var. It is + * needed to allow explicit encoding of instructions in inline assembly where + * registers are chosen by the compiler in $n form, allowing us to avoid using + * fixed register numbers. + * + * It also allows newer instructions (not implemented by the assembler) to be + * transparently implemented using assembler macros, instead of needing separate + * cases depending on toolchain support. + * + * Simple usage example: + * __asm__ __volatile__("parse_r __rt, %0\n\t" + * ".insn\n\t" + * "# di %0\n\t" + * ".word (0x41606000 | (__rt << 16))" + * : "=r" (status); + */ + +/* Match an individual register number and assign to \var */ +#define _IFC_REG(n) \ + ".ifc \\r, $" #n "\n\t" \ + "\\var = " #n "\n\t" \ + ".endif\n\t" + +__asm__(".macro parse_r var r\n\t" + "\\var = -1\n\t" + _IFC_REG(0) _IFC_REG(1) _IFC_REG(2) _IFC_REG(3) + _IFC_REG(4) _IFC_REG(5) _IFC_REG(6) _IFC_REG(7) + _IFC_REG(8) _IFC_REG(9) _IFC_REG(10) _IFC_REG(11) + _IFC_REG(12) _IFC_REG(13) _IFC_REG(14) _IFC_REG(15) + _IFC_REG(16) _IFC_REG(17) _IFC_REG(18) _IFC_REG(19) + _IFC_REG(20) _IFC_REG(21) _IFC_REG(22) _IFC_REG(23) + _IFC_REG(24) _IFC_REG(25) _IFC_REG(26) _IFC_REG(27) + _IFC_REG(28) _IFC_REG(29) _IFC_REG(30) _IFC_REG(31) + ".iflt \\var\n\t" + ".error \"Unable to parse register name \\r\"\n\t" + ".endif\n\t" + ".endm"); + +#undef _IFC_REG + +/* + * C macros for generating assembler macros for common instruction formats. + * + * The names of the operands can be chosen by the caller, and the encoding of + * register operand \<Rn> is assigned to __<Rn> where it can be accessed from + * the ENC encodings. + */ + +/* Instructions with no operands */ +#define _ASM_MACRO_0(OP, ENC) \ + __asm__(".macro " #OP "\n\t" \ + ENC \ + ".endm") + +/* Instructions with 2 register operands */ +#define _ASM_MACRO_2R(OP, R1, R2, ENC) \ + __asm__(".macro " #OP " " #R1 ", " #R2 "\n\t" \ + "parse_r __" #R1 ", \\" #R1 "\n\t" \ + "parse_r __" #R2 ", \\" #R2 "\n\t" \ + ENC \ + ".endm") + +/* Instructions with 3 register operands */ +#define _ASM_MACRO_3R(OP, R1, R2, R3, ENC) \ + __asm__(".macro " #OP " " #R1 ", " #R2 ", " #R3 "\n\t" \ + "parse_r __" #R1 ", \\" #R1 "\n\t" \ + "parse_r __" #R2 ", \\" #R2 "\n\t" \ + "parse_r __" #R3 ", \\" #R3 "\n\t" \ + ENC \ + ".endm") + +/* Instructions with 2 register operands and 1 optional select operand */ +#define _ASM_MACRO_2R_1S(OP, R1, R2, SEL3, ENC) \ + __asm__(".macro " #OP " " #R1 ", " #R2 ", " #SEL3 " = 0\n\t" \ + "parse_r __" #R1 ", \\" #R1 "\n\t" \ + "parse_r __" #R2 ", \\" #R2 "\n\t" \ + ENC \ + ".endm") + +/* * TLB Invalidate Flush */ static inline void tlbinvf(void) @@ -1245,14 +1328,14 @@ do { \ * Macros to access the system control coprocessor */ -#define __read_32bit_c0_register(source, sel) \ +#define ___read_32bit_c0_register(source, sel, vol) \ ({ unsigned int __res; \ if (sel == 0) \ - __asm__ __volatile__( \ + __asm__ vol( \ "mfc0\t%0, " #source "\n\t" \ : "=r" (__res)); \ else \ - __asm__ __volatile__( \ + __asm__ vol( \ ".set\tmips32\n\t" \ "mfc0\t%0, " #source ", " #sel "\n\t" \ ".set\tmips0\n\t" \ @@ -1260,18 +1343,18 @@ do { \ __res; \ }) -#define __read_64bit_c0_register(source, sel) \ +#define ___read_64bit_c0_register(source, sel, vol) \ ({ unsigned long long __res; \ if (sizeof(unsigned long) == 4) \ - __res = __read_64bit_c0_split(source, sel); \ + __res = __read_64bit_c0_split(source, sel, vol); \ else if (sel == 0) \ - __asm__ __volatile__( \ + __asm__ vol( \ ".set\tmips3\n\t" \ "dmfc0\t%0, " #source "\n\t" \ ".set\tmips0" \ : "=r" (__res)); \ else \ - __asm__ __volatile__( \ + __asm__ vol( \ ".set\tmips64\n\t" \ "dmfc0\t%0, " #source ", " #sel "\n\t" \ ".set\tmips0" \ @@ -1279,6 +1362,18 @@ do { \ __res; \ }) +#define __read_32bit_c0_register(source, sel) \ + ___read_32bit_c0_register(source, sel, __volatile__) + +#define __read_const_32bit_c0_register(source, sel) \ + ___read_32bit_c0_register(source, sel,) + +#define __read_64bit_c0_register(source, sel) \ + ___read_64bit_c0_register(source, sel, __volatile__) + +#define __read_const_64bit_c0_register(source, sel) \ + ___read_64bit_c0_register(source, sel,) + #define __write_32bit_c0_register(register, sel, value) \ do { \ if (sel == 0) \ @@ -1316,6 +1411,11 @@ do { \ (unsigned long) __read_32bit_c0_register(reg, sel) : \ (unsigned long) __read_64bit_c0_register(reg, sel)) +#define __read_const_ulong_c0_register(reg, sel) \ + ((sizeof(unsigned long) == 4) ? \ + (unsigned long) __read_const_32bit_c0_register(reg, sel) : \ + (unsigned long) __read_const_64bit_c0_register(reg, sel)) + #define __write_ulong_c0_register(reg, sel, val) \ do { \ if (sizeof(unsigned long) == 4) \ @@ -1346,14 +1446,14 @@ do { \ * These versions are only needed for systems with more than 38 bits of * physical address space running the 32-bit kernel. That's none atm :-) */ -#define __read_64bit_c0_split(source, sel) \ +#define __read_64bit_c0_split(source, sel, vol) \ ({ \ unsigned long long __val; \ unsigned long __flags; \ \ local_irq_save(__flags); \ if (sel == 0) \ - __asm__ __volatile__( \ + __asm__ vol( \ ".set\tmips64\n\t" \ "dmfc0\t%L0, " #source "\n\t" \ "dsra\t%M0, %L0, 32\n\t" \ @@ -1361,7 +1461,7 @@ do { \ ".set\tmips0" \ : "=r" (__val)); \ else \ - __asm__ __volatile__( \ + __asm__ vol( \ ".set\tmips64\n\t" \ "dmfc0\t%L0, " #source ", " #sel "\n\t" \ "dsra\t%M0, %L0, 32\n\t" \ @@ -1404,37 +1504,43 @@ do { \ local_irq_restore(__flags); \ } while (0) -#define __readx_32bit_c0_register(source) \ +#ifndef TOOLCHAIN_SUPPORTS_XPA +_ASM_MACRO_2R_1S(mfhc0, rt, rs, sel, + _ASM_INSN_IF_MIPS(0x40400000 | __rt << 16 | __rs << 11 | \\sel) + _ASM_INSN32_IF_MM(0x000000f4 | __rt << 21 | __rs << 16 | \\sel << 11)); +_ASM_MACRO_2R_1S(mthc0, rt, rd, sel, + _ASM_INSN_IF_MIPS(0x40c00000 | __rt << 16 | __rd << 11 | \\sel) + _ASM_INSN32_IF_MM(0x000002f4 | __rt << 21 | __rd << 16 | \\sel << 11)); +#define _ASM_SET_XPA "" +#else /* !TOOLCHAIN_SUPPORTS_XPA */ +#define _ASM_SET_XPA ".set\txpa\n\t" +#endif + +#define __readx_32bit_c0_register(source, sel) \ ({ \ unsigned int __res; \ \ __asm__ __volatile__( \ " .set push \n" \ - " .set noat \n" \ " .set mips32r2 \n" \ - " # mfhc0 $1, %1 \n" \ - _ASM_INSN_IF_MIPS(0x40410000 | ((%1 & 0x1f) << 11)) \ - _ASM_INSN32_IF_MM(0x002000f4 | ((%1 & 0x1f) << 16)) \ - " move %0, $1 \n" \ + _ASM_SET_XPA \ + " mfhc0 %0, " #source ", %1 \n" \ " .set pop \n" \ : "=r" (__res) \ - : "i" (source)); \ + : "i" (sel)); \ __res; \ }) -#define __writex_32bit_c0_register(register, value) \ +#define __writex_32bit_c0_register(register, sel, value) \ do { \ __asm__ __volatile__( \ " .set push \n" \ - " .set noat \n" \ " .set mips32r2 \n" \ - " move $1, %0 \n" \ - " # mthc0 $1, %1 \n" \ - _ASM_INSN_IF_MIPS(0x40c10000 | ((%1 & 0x1f) << 11)) \ - _ASM_INSN32_IF_MM(0x002002f4 | ((%1 & 0x1f) << 16)) \ + _ASM_SET_XPA \ + " mthc0 %z0, " #register ", %1 \n" \ " .set pop \n" \ : \ - : "r" (value), "i" (register)); \ + : "Jr" (value), "i" (sel)); \ } while (0) #define read_c0_index() __read_32bit_c0_register($0, 0) @@ -1446,14 +1552,14 @@ do { \ #define read_c0_entrylo0() __read_ulong_c0_register($2, 0) #define write_c0_entrylo0(val) __write_ulong_c0_register($2, 0, val) -#define readx_c0_entrylo0() __readx_32bit_c0_register(2) -#define writex_c0_entrylo0(val) __writex_32bit_c0_register(2, val) +#define readx_c0_entrylo0() __readx_32bit_c0_register($2, 0) +#define writex_c0_entrylo0(val) __writex_32bit_c0_register($2, 0, val) #define read_c0_entrylo1() __read_ulong_c0_register($3, 0) #define write_c0_entrylo1(val) __write_ulong_c0_register($3, 0, val) -#define readx_c0_entrylo1() __readx_32bit_c0_register(3) -#define writex_c0_entrylo1(val) __writex_32bit_c0_register(3, val) +#define readx_c0_entrylo1() __readx_32bit_c0_register($3, 0) +#define writex_c0_entrylo1(val) __writex_32bit_c0_register($3, 0, val) #define read_c0_conf() __read_32bit_c0_register($3, 0) #define write_c0_conf(val) __write_32bit_c0_register($3, 0, val) @@ -1541,7 +1647,7 @@ do { \ #define read_c0_epc() __read_ulong_c0_register($14, 0) #define write_c0_epc(val) __write_ulong_c0_register($14, 0, val) -#define read_c0_prid() __read_32bit_c0_register($15, 0) +#define read_c0_prid() __read_const_32bit_c0_register($15, 0) #define read_c0_cmgcrbase() __read_ulong_c0_register($15, 3) @@ -1830,18 +1936,44 @@ do { \ * Macros to access the guest system control coprocessor */ -#ifdef TOOLCHAIN_SUPPORTS_VIRT +#ifndef TOOLCHAIN_SUPPORTS_VIRT +_ASM_MACRO_2R_1S(mfgc0, rt, rs, sel, + _ASM_INSN_IF_MIPS(0x40600000 | __rt << 16 | __rs << 11 | \\sel) + _ASM_INSN32_IF_MM(0x000004fc | __rt << 21 | __rs << 16 | \\sel << 11)); +_ASM_MACRO_2R_1S(dmfgc0, rt, rs, sel, + _ASM_INSN_IF_MIPS(0x40600100 | __rt << 16 | __rs << 11 | \\sel) + _ASM_INSN32_IF_MM(0x580004fc | __rt << 21 | __rs << 16 | \\sel << 11)); +_ASM_MACRO_2R_1S(mtgc0, rt, rd, sel, + _ASM_INSN_IF_MIPS(0x40600200 | __rt << 16 | __rd << 11 | \\sel) + _ASM_INSN32_IF_MM(0x000006fc | __rt << 21 | __rd << 16 | \\sel << 11)); +_ASM_MACRO_2R_1S(dmtgc0, rt, rd, sel, + _ASM_INSN_IF_MIPS(0x40600300 | __rt << 16 | __rd << 11 | \\sel) + _ASM_INSN32_IF_MM(0x580006fc | __rt << 21 | __rd << 16 | \\sel << 11)); +_ASM_MACRO_0(tlbgp, _ASM_INSN_IF_MIPS(0x42000010) + _ASM_INSN32_IF_MM(0x0000017c)); +_ASM_MACRO_0(tlbgr, _ASM_INSN_IF_MIPS(0x42000009) + _ASM_INSN32_IF_MM(0x0000117c)); +_ASM_MACRO_0(tlbgwi, _ASM_INSN_IF_MIPS(0x4200000a) + _ASM_INSN32_IF_MM(0x0000217c)); +_ASM_MACRO_0(tlbgwr, _ASM_INSN_IF_MIPS(0x4200000e) + _ASM_INSN32_IF_MM(0x0000317c)); +_ASM_MACRO_0(tlbginvf, _ASM_INSN_IF_MIPS(0x4200000c) + _ASM_INSN32_IF_MM(0x0000517c)); +#define _ASM_SET_VIRT "" +#else /* !TOOLCHAIN_SUPPORTS_VIRT */ +#define _ASM_SET_VIRT ".set\tvirt\n\t" +#endif #define __read_32bit_gc0_register(source, sel) \ ({ int __res; \ __asm__ __volatile__( \ ".set\tpush\n\t" \ ".set\tmips32r2\n\t" \ - ".set\tvirt\n\t" \ - "mfgc0\t%0, $%1, %2\n\t" \ + _ASM_SET_VIRT \ + "mfgc0\t%0, " #source ", %1\n\t" \ ".set\tpop" \ : "=r" (__res) \ - : "i" (source), "i" (sel)); \ + : "i" (sel)); \ __res; \ }) @@ -1850,11 +1982,11 @@ do { \ __asm__ __volatile__( \ ".set\tpush\n\t" \ ".set\tmips64r2\n\t" \ - ".set\tvirt\n\t" \ - "dmfgc0\t%0, $%1, %2\n\t" \ + _ASM_SET_VIRT \ + "dmfgc0\t%0, " #source ", %1\n\t" \ ".set\tpop" \ : "=r" (__res) \ - : "i" (source), "i" (sel)); \ + : "i" (sel)); \ __res; \ }) @@ -1863,11 +1995,11 @@ do { \ __asm__ __volatile__( \ ".set\tpush\n\t" \ ".set\tmips32r2\n\t" \ - ".set\tvirt\n\t" \ - "mtgc0\t%z0, $%1, %2\n\t" \ + _ASM_SET_VIRT \ + "mtgc0\t%z0, " #register ", %1\n\t" \ ".set\tpop" \ : : "Jr" ((unsigned int)(value)), \ - "i" (register), "i" (sel)); \ + "i" (sel)); \ } while (0) #define __write_64bit_gc0_register(register, sel, value) \ @@ -1875,75 +2007,13 @@ do { \ __asm__ __volatile__( \ ".set\tpush\n\t" \ ".set\tmips64r2\n\t" \ - ".set\tvirt\n\t" \ - "dmtgc0\t%z0, $%1, %2\n\t" \ + _ASM_SET_VIRT \ + "dmtgc0\t%z0, " #register ", %1\n\t" \ ".set\tpop" \ : : "Jr" (value), \ - "i" (register), "i" (sel)); \ + "i" (sel)); \ } while (0) -#else /* TOOLCHAIN_SUPPORTS_VIRT */ - -#define __read_32bit_gc0_register(source, sel) \ -({ int __res; \ - __asm__ __volatile__( \ - ".set\tpush\n\t" \ - ".set\tnoat\n\t" \ - "# mfgc0\t$1, $%1, %2\n\t" \ - _ASM_INSN_IF_MIPS(0x40610000 | %1 << 11 | %2) \ - _ASM_INSN32_IF_MM(0x002004fc | %1 << 16 | %2 << 11) \ - "move\t%0, $1\n\t" \ - ".set\tpop" \ - : "=r" (__res) \ - : "i" (source), "i" (sel)); \ - __res; \ -}) - -#define __read_64bit_gc0_register(source, sel) \ -({ unsigned long long __res; \ - __asm__ __volatile__( \ - ".set\tpush\n\t" \ - ".set\tnoat\n\t" \ - "# dmfgc0\t$1, $%1, %2\n\t" \ - _ASM_INSN_IF_MIPS(0x40610100 | %1 << 11 | %2) \ - _ASM_INSN32_IF_MM(0x582004fc | %1 << 16 | %2 << 11) \ - "move\t%0, $1\n\t" \ - ".set\tpop" \ - : "=r" (__res) \ - : "i" (source), "i" (sel)); \ - __res; \ -}) - -#define __write_32bit_gc0_register(register, sel, value) \ -do { \ - __asm__ __volatile__( \ - ".set\tpush\n\t" \ - ".set\tnoat\n\t" \ - "move\t$1, %z0\n\t" \ - "# mtgc0\t$1, $%1, %2\n\t" \ - _ASM_INSN_IF_MIPS(0x40610200 | %1 << 11 | %2) \ - _ASM_INSN32_IF_MM(0x002006fc | %1 << 16 | %2 << 11) \ - ".set\tpop" \ - : : "Jr" ((unsigned int)(value)), \ - "i" (register), "i" (sel)); \ -} while (0) - -#define __write_64bit_gc0_register(register, sel, value) \ -do { \ - __asm__ __volatile__( \ - ".set\tpush\n\t" \ - ".set\tnoat\n\t" \ - "move\t$1, %z0\n\t" \ - "# dmtgc0\t$1, $%1, %2\n\t" \ - _ASM_INSN_IF_MIPS(0x40610300 | %1 << 11 | %2) \ - _ASM_INSN32_IF_MM(0x582006fc | %1 << 16 | %2 << 11) \ - ".set\tpop" \ - : : "Jr" (value), \ - "i" (register), "i" (sel)); \ -} while (0) - -#endif /* !TOOLCHAIN_SUPPORTS_VIRT */ - #define __read_ulong_gc0_register(reg, sel) \ ((sizeof(unsigned long) == 4) ? \ (unsigned long) __read_32bit_gc0_register(reg, sel) : \ @@ -1957,207 +2027,207 @@ do { \ __write_64bit_gc0_register(reg, sel, val); \ } while (0) -#define read_gc0_index() __read_32bit_gc0_register(0, 0) -#define write_gc0_index(val) __write_32bit_gc0_register(0, 0, val) +#define read_gc0_index() __read_32bit_gc0_register($0, 0) +#define write_gc0_index(val) __write_32bit_gc0_register($0, 0, val) -#define read_gc0_entrylo0() __read_ulong_gc0_register(2, 0) -#define write_gc0_entrylo0(val) __write_ulong_gc0_register(2, 0, val) +#define read_gc0_entrylo0() __read_ulong_gc0_register($2, 0) +#define write_gc0_entrylo0(val) __write_ulong_gc0_register($2, 0, val) -#define read_gc0_entrylo1() __read_ulong_gc0_register(3, 0) -#define write_gc0_entrylo1(val) __write_ulong_gc0_register(3, 0, val) +#define read_gc0_entrylo1() __read_ulong_gc0_register($3, 0) +#define write_gc0_entrylo1(val) __write_ulong_gc0_register($3, 0, val) -#define read_gc0_context() __read_ulong_gc0_register(4, 0) -#define write_gc0_context(val) __write_ulong_gc0_register(4, 0, val) +#define read_gc0_context() __read_ulong_gc0_register($4, 0) +#define write_gc0_context(val) __write_ulong_gc0_register($4, 0, val) -#define read_gc0_contextconfig() __read_32bit_gc0_register(4, 1) -#define write_gc0_contextconfig(val) __write_32bit_gc0_register(4, 1, val) +#define read_gc0_contextconfig() __read_32bit_gc0_register($4, 1) +#define write_gc0_contextconfig(val) __write_32bit_gc0_register($4, 1, val) -#define read_gc0_userlocal() __read_ulong_gc0_register(4, 2) -#define write_gc0_userlocal(val) __write_ulong_gc0_register(4, 2, val) +#define read_gc0_userlocal() __read_ulong_gc0_register($4, 2) +#define write_gc0_userlocal(val) __write_ulong_gc0_register($4, 2, val) -#define read_gc0_xcontextconfig() __read_ulong_gc0_register(4, 3) -#define write_gc0_xcontextconfig(val) __write_ulong_gc0_register(4, 3, val) +#define read_gc0_xcontextconfig() __read_ulong_gc0_register($4, 3) +#define write_gc0_xcontextconfig(val) __write_ulong_gc0_register($4, 3, val) -#define read_gc0_pagemask() __read_32bit_gc0_register(5, 0) -#define write_gc0_pagemask(val) __write_32bit_gc0_register(5, 0, val) +#define read_gc0_pagemask() __read_32bit_gc0_register($5, 0) +#define write_gc0_pagemask(val) __write_32bit_gc0_register($5, 0, val) -#define read_gc0_pagegrain() __read_32bit_gc0_register(5, 1) -#define write_gc0_pagegrain(val) __write_32bit_gc0_register(5, 1, val) +#define read_gc0_pagegrain() __read_32bit_gc0_register($5, 1) +#define write_gc0_pagegrain(val) __write_32bit_gc0_register($5, 1, val) -#define read_gc0_segctl0() __read_ulong_gc0_register(5, 2) -#define write_gc0_segctl0(val) __write_ulong_gc0_register(5, 2, val) +#define read_gc0_segctl0() __read_ulong_gc0_register($5, 2) +#define write_gc0_segctl0(val) __write_ulong_gc0_register($5, 2, val) -#define read_gc0_segctl1() __read_ulong_gc0_register(5, 3) -#define write_gc0_segctl1(val) __write_ulong_gc0_register(5, 3, val) +#define read_gc0_segctl1() __read_ulong_gc0_register($5, 3) +#define write_gc0_segctl1(val) __write_ulong_gc0_register($5, 3, val) -#define read_gc0_segctl2() __read_ulong_gc0_register(5, 4) -#define write_gc0_segctl2(val) __write_ulong_gc0_register(5, 4, val) +#define read_gc0_segctl2() __read_ulong_gc0_register($5, 4) +#define write_gc0_segctl2(val) __write_ulong_gc0_register($5, 4, val) -#define read_gc0_pwbase() __read_ulong_gc0_register(5, 5) -#define write_gc0_pwbase(val) __write_ulong_gc0_register(5, 5, val) +#define read_gc0_pwbase() __read_ulong_gc0_register($5, 5) +#define write_gc0_pwbase(val) __write_ulong_gc0_register($5, 5, val) -#define read_gc0_pwfield() __read_ulong_gc0_register(5, 6) -#define write_gc0_pwfield(val) __write_ulong_gc0_register(5, 6, val) +#define read_gc0_pwfield() __read_ulong_gc0_register($5, 6) +#define write_gc0_pwfield(val) __write_ulong_gc0_register($5, 6, val) -#define read_gc0_pwsize() __read_ulong_gc0_register(5, 7) -#define write_gc0_pwsize(val) __write_ulong_gc0_register(5, 7, val) +#define read_gc0_pwsize() __read_ulong_gc0_register($5, 7) +#define write_gc0_pwsize(val) __write_ulong_gc0_register($5, 7, val) -#define read_gc0_wired() __read_32bit_gc0_register(6, 0) -#define write_gc0_wired(val) __write_32bit_gc0_register(6, 0, val) +#define read_gc0_wired() __read_32bit_gc0_register($6, 0) +#define write_gc0_wired(val) __write_32bit_gc0_register($6, 0, val) -#define read_gc0_pwctl() __read_32bit_gc0_register(6, 6) -#define write_gc0_pwctl(val) __write_32bit_gc0_register(6, 6, val) - -#define read_gc0_hwrena() __read_32bit_gc0_register(7, 0) -#define write_gc0_hwrena(val) __write_32bit_gc0_register(7, 0, val) - -#define read_gc0_badvaddr() __read_ulong_gc0_register(8, 0) -#define write_gc0_badvaddr(val) __write_ulong_gc0_register(8, 0, val) - -#define read_gc0_badinstr() __read_32bit_gc0_register(8, 1) -#define write_gc0_badinstr(val) __write_32bit_gc0_register(8, 1, val) - -#define read_gc0_badinstrp() __read_32bit_gc0_register(8, 2) -#define write_gc0_badinstrp(val) __write_32bit_gc0_register(8, 2, val) - -#define read_gc0_count() __read_32bit_gc0_register(9, 0) - -#define read_gc0_entryhi() __read_ulong_gc0_register(10, 0) -#define write_gc0_entryhi(val) __write_ulong_gc0_register(10, 0, val) - -#define read_gc0_compare() __read_32bit_gc0_register(11, 0) -#define write_gc0_compare(val) __write_32bit_gc0_register(11, 0, val) - -#define read_gc0_status() __read_32bit_gc0_register(12, 0) -#define write_gc0_status(val) __write_32bit_gc0_register(12, 0, val) - -#define read_gc0_intctl() __read_32bit_gc0_register(12, 1) -#define write_gc0_intctl(val) __write_32bit_gc0_register(12, 1, val) - -#define read_gc0_cause() __read_32bit_gc0_register(13, 0) -#define write_gc0_cause(val) __write_32bit_gc0_register(13, 0, val) - -#define read_gc0_epc() __read_ulong_gc0_register(14, 0) -#define write_gc0_epc(val) __write_ulong_gc0_register(14, 0, val) - -#define read_gc0_prid() __read_32bit_gc0_register(15, 0) - -#define read_gc0_ebase() __read_32bit_gc0_register(15, 1) -#define write_gc0_ebase(val) __write_32bit_gc0_register(15, 1, val) - -#define read_gc0_ebase_64() __read_64bit_gc0_register(15, 1) -#define write_gc0_ebase_64(val) __write_64bit_gc0_register(15, 1, val) - -#define read_gc0_config() __read_32bit_gc0_register(16, 0) -#define read_gc0_config1() __read_32bit_gc0_register(16, 1) -#define read_gc0_config2() __read_32bit_gc0_register(16, 2) -#define read_gc0_config3() __read_32bit_gc0_register(16, 3) -#define read_gc0_config4() __read_32bit_gc0_register(16, 4) -#define read_gc0_config5() __read_32bit_gc0_register(16, 5) -#define read_gc0_config6() __read_32bit_gc0_register(16, 6) -#define read_gc0_config7() __read_32bit_gc0_register(16, 7) -#define write_gc0_config(val) __write_32bit_gc0_register(16, 0, val) -#define write_gc0_config1(val) __write_32bit_gc0_register(16, 1, val) -#define write_gc0_config2(val) __write_32bit_gc0_register(16, 2, val) -#define write_gc0_config3(val) __write_32bit_gc0_register(16, 3, val) -#define write_gc0_config4(val) __write_32bit_gc0_register(16, 4, val) -#define write_gc0_config5(val) __write_32bit_gc0_register(16, 5, val) -#define write_gc0_config6(val) __write_32bit_gc0_register(16, 6, val) -#define write_gc0_config7(val) __write_32bit_gc0_register(16, 7, val) - -#define read_gc0_lladdr() __read_ulong_gc0_register(17, 0) -#define write_gc0_lladdr(val) __write_ulong_gc0_register(17, 0, val) - -#define read_gc0_watchlo0() __read_ulong_gc0_register(18, 0) -#define read_gc0_watchlo1() __read_ulong_gc0_register(18, 1) -#define read_gc0_watchlo2() __read_ulong_gc0_register(18, 2) -#define read_gc0_watchlo3() __read_ulong_gc0_register(18, 3) -#define read_gc0_watchlo4() __read_ulong_gc0_register(18, 4) -#define read_gc0_watchlo5() __read_ulong_gc0_register(18, 5) -#define read_gc0_watchlo6() __read_ulong_gc0_register(18, 6) -#define read_gc0_watchlo7() __read_ulong_gc0_register(18, 7) -#define write_gc0_watchlo0(val) __write_ulong_gc0_register(18, 0, val) -#define write_gc0_watchlo1(val) __write_ulong_gc0_register(18, 1, val) -#define write_gc0_watchlo2(val) __write_ulong_gc0_register(18, 2, val) -#define write_gc0_watchlo3(val) __write_ulong_gc0_register(18, 3, val) -#define write_gc0_watchlo4(val) __write_ulong_gc0_register(18, 4, val) -#define write_gc0_watchlo5(val) __write_ulong_gc0_register(18, 5, val) -#define write_gc0_watchlo6(val) __write_ulong_gc0_register(18, 6, val) -#define write_gc0_watchlo7(val) __write_ulong_gc0_register(18, 7, val) - -#define read_gc0_watchhi0() __read_32bit_gc0_register(19, 0) -#define read_gc0_watchhi1() __read_32bit_gc0_register(19, 1) -#define read_gc0_watchhi2() __read_32bit_gc0_register(19, 2) -#define read_gc0_watchhi3() __read_32bit_gc0_register(19, 3) -#define read_gc0_watchhi4() __read_32bit_gc0_register(19, 4) -#define read_gc0_watchhi5() __read_32bit_gc0_register(19, 5) -#define read_gc0_watchhi6() __read_32bit_gc0_register(19, 6) -#define read_gc0_watchhi7() __read_32bit_gc0_register(19, 7) -#define write_gc0_watchhi0(val) __write_32bit_gc0_register(19, 0, val) -#define write_gc0_watchhi1(val) __write_32bit_gc0_register(19, 1, val) -#define write_gc0_watchhi2(val) __write_32bit_gc0_register(19, 2, val) -#define write_gc0_watchhi3(val) __write_32bit_gc0_register(19, 3, val) -#define write_gc0_watchhi4(val) __write_32bit_gc0_register(19, 4, val) -#define write_gc0_watchhi5(val) __write_32bit_gc0_register(19, 5, val) -#define write_gc0_watchhi6(val) __write_32bit_gc0_register(19, 6, val) -#define write_gc0_watchhi7(val) __write_32bit_gc0_register(19, 7, val) - -#define read_gc0_xcontext() __read_ulong_gc0_register(20, 0) -#define write_gc0_xcontext(val) __write_ulong_gc0_register(20, 0, val) - -#define read_gc0_perfctrl0() __read_32bit_gc0_register(25, 0) -#define write_gc0_perfctrl0(val) __write_32bit_gc0_register(25, 0, val) -#define read_gc0_perfcntr0() __read_32bit_gc0_register(25, 1) -#define write_gc0_perfcntr0(val) __write_32bit_gc0_register(25, 1, val) -#define read_gc0_perfcntr0_64() __read_64bit_gc0_register(25, 1) -#define write_gc0_perfcntr0_64(val) __write_64bit_gc0_register(25, 1, val) -#define read_gc0_perfctrl1() __read_32bit_gc0_register(25, 2) -#define write_gc0_perfctrl1(val) __write_32bit_gc0_register(25, 2, val) -#define read_gc0_perfcntr1() __read_32bit_gc0_register(25, 3) -#define write_gc0_perfcntr1(val) __write_32bit_gc0_register(25, 3, val) -#define read_gc0_perfcntr1_64() __read_64bit_gc0_register(25, 3) -#define write_gc0_perfcntr1_64(val) __write_64bit_gc0_register(25, 3, val) -#define read_gc0_perfctrl2() __read_32bit_gc0_register(25, 4) -#define write_gc0_perfctrl2(val) __write_32bit_gc0_register(25, 4, val) -#define read_gc0_perfcntr2() __read_32bit_gc0_register(25, 5) -#define write_gc0_perfcntr2(val) __write_32bit_gc0_register(25, 5, val) -#define read_gc0_perfcntr2_64() __read_64bit_gc0_register(25, 5) -#define write_gc0_perfcntr2_64(val) __write_64bit_gc0_register(25, 5, val) -#define read_gc0_perfctrl3() __read_32bit_gc0_register(25, 6) -#define write_gc0_perfctrl3(val) __write_32bit_gc0_register(25, 6, val) -#define read_gc0_perfcntr3() __read_32bit_gc0_register(25, 7) -#define write_gc0_perfcntr3(val) __write_32bit_gc0_register(25, 7, val) -#define read_gc0_perfcntr3_64() __read_64bit_gc0_register(25, 7) -#define write_gc0_perfcntr3_64(val) __write_64bit_gc0_register(25, 7, val) - -#define read_gc0_errorepc() __read_ulong_gc0_register(30, 0) -#define write_gc0_errorepc(val) __write_ulong_gc0_register(30, 0, val) - -#define read_gc0_kscratch1() __read_ulong_gc0_register(31, 2) -#define read_gc0_kscratch2() __read_ulong_gc0_register(31, 3) -#define read_gc0_kscratch3() __read_ulong_gc0_register(31, 4) -#define read_gc0_kscratch4() __read_ulong_gc0_register(31, 5) -#define read_gc0_kscratch5() __read_ulong_gc0_register(31, 6) -#define read_gc0_kscratch6() __read_ulong_gc0_register(31, 7) -#define write_gc0_kscratch1(val) __write_ulong_gc0_register(31, 2, val) -#define write_gc0_kscratch2(val) __write_ulong_gc0_register(31, 3, val) -#define write_gc0_kscratch3(val) __write_ulong_gc0_register(31, 4, val) -#define write_gc0_kscratch4(val) __write_ulong_gc0_register(31, 5, val) -#define write_gc0_kscratch5(val) __write_ulong_gc0_register(31, 6, val) -#define write_gc0_kscratch6(val) __write_ulong_gc0_register(31, 7, val) +#define read_gc0_pwctl() __read_32bit_gc0_register($6, 6) +#define write_gc0_pwctl(val) __write_32bit_gc0_register($6, 6, val) + +#define read_gc0_hwrena() __read_32bit_gc0_register($7, 0) +#define write_gc0_hwrena(val) __write_32bit_gc0_register($7, 0, val) + +#define read_gc0_badvaddr() __read_ulong_gc0_register($8, 0) +#define write_gc0_badvaddr(val) __write_ulong_gc0_register($8, 0, val) + +#define read_gc0_badinstr() __read_32bit_gc0_register($8, 1) +#define write_gc0_badinstr(val) __write_32bit_gc0_register($8, 1, val) + +#define read_gc0_badinstrp() __read_32bit_gc0_register($8, 2) +#define write_gc0_badinstrp(val) __write_32bit_gc0_register($8, 2, val) + +#define read_gc0_count() __read_32bit_gc0_register($9, 0) + +#define read_gc0_entryhi() __read_ulong_gc0_register($10, 0) +#define write_gc0_entryhi(val) __write_ulong_gc0_register($10, 0, val) + +#define read_gc0_compare() __read_32bit_gc0_register($11, 0) +#define write_gc0_compare(val) __write_32bit_gc0_register($11, 0, val) + +#define read_gc0_status() __read_32bit_gc0_register($12, 0) +#define write_gc0_status(val) __write_32bit_gc0_register($12, 0, val) + +#define read_gc0_intctl() __read_32bit_gc0_register($12, 1) +#define write_gc0_intctl(val) __write_32bit_gc0_register($12, 1, val) + +#define read_gc0_cause() __read_32bit_gc0_register($13, 0) +#define write_gc0_cause(val) __write_32bit_gc0_register($13, 0, val) + +#define read_gc0_epc() __read_ulong_gc0_register($14, 0) +#define write_gc0_epc(val) __write_ulong_gc0_register($14, 0, val) + +#define read_gc0_prid() __read_32bit_gc0_register($15, 0) + +#define read_gc0_ebase() __read_32bit_gc0_register($15, 1) +#define write_gc0_ebase(val) __write_32bit_gc0_register($15, 1, val) + +#define read_gc0_ebase_64() __read_64bit_gc0_register($15, 1) +#define write_gc0_ebase_64(val) __write_64bit_gc0_register($15, 1, val) + +#define read_gc0_config() __read_32bit_gc0_register($16, 0) +#define read_gc0_config1() __read_32bit_gc0_register($16, 1) +#define read_gc0_config2() __read_32bit_gc0_register($16, 2) +#define read_gc0_config3() __read_32bit_gc0_register($16, 3) +#define read_gc0_config4() __read_32bit_gc0_register($16, 4) +#define read_gc0_config5() __read_32bit_gc0_register($16, 5) +#define read_gc0_config6() __read_32bit_gc0_register($16, 6) +#define read_gc0_config7() __read_32bit_gc0_register($16, 7) +#define write_gc0_config(val) __write_32bit_gc0_register($16, 0, val) +#define write_gc0_config1(val) __write_32bit_gc0_register($16, 1, val) +#define write_gc0_config2(val) __write_32bit_gc0_register($16, 2, val) +#define write_gc0_config3(val) __write_32bit_gc0_register($16, 3, val) +#define write_gc0_config4(val) __write_32bit_gc0_register($16, 4, val) +#define write_gc0_config5(val) __write_32bit_gc0_register($16, 5, val) +#define write_gc0_config6(val) __write_32bit_gc0_register($16, 6, val) +#define write_gc0_config7(val) __write_32bit_gc0_register($16, 7, val) + +#define read_gc0_lladdr() __read_ulong_gc0_register($17, 0) +#define write_gc0_lladdr(val) __write_ulong_gc0_register($17, 0, val) + +#define read_gc0_watchlo0() __read_ulong_gc0_register($18, 0) +#define read_gc0_watchlo1() __read_ulong_gc0_register($18, 1) +#define read_gc0_watchlo2() __read_ulong_gc0_register($18, 2) +#define read_gc0_watchlo3() __read_ulong_gc0_register($18, 3) +#define read_gc0_watchlo4() __read_ulong_gc0_register($18, 4) +#define read_gc0_watchlo5() __read_ulong_gc0_register($18, 5) +#define read_gc0_watchlo6() __read_ulong_gc0_register($18, 6) +#define read_gc0_watchlo7() __read_ulong_gc0_register($18, 7) +#define write_gc0_watchlo0(val) __write_ulong_gc0_register($18, 0, val) +#define write_gc0_watchlo1(val) __write_ulong_gc0_register($18, 1, val) +#define write_gc0_watchlo2(val) __write_ulong_gc0_register($18, 2, val) +#define write_gc0_watchlo3(val) __write_ulong_gc0_register($18, 3, val) +#define write_gc0_watchlo4(val) __write_ulong_gc0_register($18, 4, val) +#define write_gc0_watchlo5(val) __write_ulong_gc0_register($18, 5, val) +#define write_gc0_watchlo6(val) __write_ulong_gc0_register($18, 6, val) +#define write_gc0_watchlo7(val) __write_ulong_gc0_register($18, 7, val) + +#define read_gc0_watchhi0() __read_32bit_gc0_register($19, 0) +#define read_gc0_watchhi1() __read_32bit_gc0_register($19, 1) +#define read_gc0_watchhi2() __read_32bit_gc0_register($19, 2) +#define read_gc0_watchhi3() __read_32bit_gc0_register($19, 3) +#define read_gc0_watchhi4() __read_32bit_gc0_register($19, 4) +#define read_gc0_watchhi5() __read_32bit_gc0_register($19, 5) +#define read_gc0_watchhi6() __read_32bit_gc0_register($19, 6) +#define read_gc0_watchhi7() __read_32bit_gc0_register($19, 7) +#define write_gc0_watchhi0(val) __write_32bit_gc0_register($19, 0, val) +#define write_gc0_watchhi1(val) __write_32bit_gc0_register($19, 1, val) +#define write_gc0_watchhi2(val) __write_32bit_gc0_register($19, 2, val) +#define write_gc0_watchhi3(val) __write_32bit_gc0_register($19, 3, val) +#define write_gc0_watchhi4(val) __write_32bit_gc0_register($19, 4, val) +#define write_gc0_watchhi5(val) __write_32bit_gc0_register($19, 5, val) +#define write_gc0_watchhi6(val) __write_32bit_gc0_register($19, 6, val) +#define write_gc0_watchhi7(val) __write_32bit_gc0_register($19, 7, val) + +#define read_gc0_xcontext() __read_ulong_gc0_register($20, 0) +#define write_gc0_xcontext(val) __write_ulong_gc0_register($20, 0, val) + +#define read_gc0_perfctrl0() __read_32bit_gc0_register($25, 0) +#define write_gc0_perfctrl0(val) __write_32bit_gc0_register($25, 0, val) +#define read_gc0_perfcntr0() __read_32bit_gc0_register($25, 1) +#define write_gc0_perfcntr0(val) __write_32bit_gc0_register($25, 1, val) +#define read_gc0_perfcntr0_64() __read_64bit_gc0_register($25, 1) +#define write_gc0_perfcntr0_64(val) __write_64bit_gc0_register($25, 1, val) +#define read_gc0_perfctrl1() __read_32bit_gc0_register($25, 2) +#define write_gc0_perfctrl1(val) __write_32bit_gc0_register($25, 2, val) +#define read_gc0_perfcntr1() __read_32bit_gc0_register($25, 3) +#define write_gc0_perfcntr1(val) __write_32bit_gc0_register($25, 3, val) +#define read_gc0_perfcntr1_64() __read_64bit_gc0_register($25, 3) +#define write_gc0_perfcntr1_64(val) __write_64bit_gc0_register($25, 3, val) +#define read_gc0_perfctrl2() __read_32bit_gc0_register($25, 4) +#define write_gc0_perfctrl2(val) __write_32bit_gc0_register($25, 4, val) +#define read_gc0_perfcntr2() __read_32bit_gc0_register($25, 5) +#define write_gc0_perfcntr2(val) __write_32bit_gc0_register($25, 5, val) +#define read_gc0_perfcntr2_64() __read_64bit_gc0_register($25, 5) +#define write_gc0_perfcntr2_64(val) __write_64bit_gc0_register($25, 5, val) +#define read_gc0_perfctrl3() __read_32bit_gc0_register($25, 6) +#define write_gc0_perfctrl3(val) __write_32bit_gc0_register($25, 6, val) +#define read_gc0_perfcntr3() __read_32bit_gc0_register($25, 7) +#define write_gc0_perfcntr3(val) __write_32bit_gc0_register($25, 7, val) +#define read_gc0_perfcntr3_64() __read_64bit_gc0_register($25, 7) +#define write_gc0_perfcntr3_64(val) __write_64bit_gc0_register($25, 7, val) + +#define read_gc0_errorepc() __read_ulong_gc0_register($30, 0) +#define write_gc0_errorepc(val) __write_ulong_gc0_register($30, 0, val) + +#define read_gc0_kscratch1() __read_ulong_gc0_register($31, 2) +#define read_gc0_kscratch2() __read_ulong_gc0_register($31, 3) +#define read_gc0_kscratch3() __read_ulong_gc0_register($31, 4) +#define read_gc0_kscratch4() __read_ulong_gc0_register($31, 5) +#define read_gc0_kscratch5() __read_ulong_gc0_register($31, 6) +#define read_gc0_kscratch6() __read_ulong_gc0_register($31, 7) +#define write_gc0_kscratch1(val) __write_ulong_gc0_register($31, 2, val) +#define write_gc0_kscratch2(val) __write_ulong_gc0_register($31, 3, val) +#define write_gc0_kscratch3(val) __write_ulong_gc0_register($31, 4, val) +#define write_gc0_kscratch4(val) __write_ulong_gc0_register($31, 5, val) +#define write_gc0_kscratch5(val) __write_ulong_gc0_register($31, 6, val) +#define write_gc0_kscratch6(val) __write_ulong_gc0_register($31, 7, val) /* Cavium OCTEON (cnMIPS) */ -#define read_gc0_cvmcount() __read_ulong_gc0_register(9, 6) -#define write_gc0_cvmcount(val) __write_ulong_gc0_register(9, 6, val) +#define read_gc0_cvmcount() __read_ulong_gc0_register($9, 6) +#define write_gc0_cvmcount(val) __write_ulong_gc0_register($9, 6, val) -#define read_gc0_cvmctl() __read_64bit_gc0_register(9, 7) -#define write_gc0_cvmctl(val) __write_64bit_gc0_register(9, 7, val) +#define read_gc0_cvmctl() __read_64bit_gc0_register($9, 7) +#define write_gc0_cvmctl(val) __write_64bit_gc0_register($9, 7, val) -#define read_gc0_cvmmemctl() __read_64bit_gc0_register(11, 7) -#define write_gc0_cvmmemctl(val) __write_64bit_gc0_register(11, 7, val) +#define read_gc0_cvmmemctl() __read_64bit_gc0_register($11, 7) +#define write_gc0_cvmmemctl(val) __write_64bit_gc0_register($11, 7, val) -#define read_gc0_cvmmemctl2() __read_64bit_gc0_register(16, 6) -#define write_gc0_cvmmemctl2(val) __write_64bit_gc0_register(16, 6, val) +#define read_gc0_cvmmemctl2() __read_64bit_gc0_register($16, 6) +#define write_gc0_cvmmemctl2(val) __write_64bit_gc0_register($16, 6, val) /* * Macros to access the floating point coprocessor control registers @@ -2581,8 +2651,6 @@ static inline void tlb_write_random(void) ".set reorder"); } -#ifdef TOOLCHAIN_SUPPORTS_VIRT - /* * Guest TLB operations. * @@ -2593,7 +2661,7 @@ static inline void guest_tlb_probe(void) __asm__ __volatile__( ".set push\n\t" ".set noreorder\n\t" - ".set virt\n\t" + _ASM_SET_VIRT "tlbgp\n\t" ".set pop"); } @@ -2603,7 +2671,7 @@ static inline void guest_tlb_read(void) __asm__ __volatile__( ".set push\n\t" ".set noreorder\n\t" - ".set virt\n\t" + _ASM_SET_VIRT "tlbgr\n\t" ".set pop"); } @@ -2613,7 +2681,7 @@ static inline void guest_tlb_write_indexed(void) __asm__ __volatile__( ".set push\n\t" ".set noreorder\n\t" - ".set virt\n\t" + _ASM_SET_VIRT "tlbgwi\n\t" ".set pop"); } @@ -2623,7 +2691,7 @@ static inline void guest_tlb_write_random(void) __asm__ __volatile__( ".set push\n\t" ".set noreorder\n\t" - ".set virt\n\t" + _ASM_SET_VIRT "tlbgwr\n\t" ".set pop"); } @@ -2636,63 +2704,11 @@ static inline void guest_tlbinvf(void) __asm__ __volatile__( ".set push\n\t" ".set noreorder\n\t" - ".set virt\n\t" + _ASM_SET_VIRT "tlbginvf\n\t" ".set pop"); } -#else /* TOOLCHAIN_SUPPORTS_VIRT */ - -/* - * Guest TLB operations. - * - * It is responsibility of the caller to take care of any TLB hazards. - */ -static inline void guest_tlb_probe(void) -{ - __asm__ __volatile__( - "# tlbgp\n\t" - _ASM_INSN_IF_MIPS(0x42000010) - _ASM_INSN32_IF_MM(0x0000017c)); -} - -static inline void guest_tlb_read(void) -{ - __asm__ __volatile__( - "# tlbgr\n\t" - _ASM_INSN_IF_MIPS(0x42000009) - _ASM_INSN32_IF_MM(0x0000117c)); -} - -static inline void guest_tlb_write_indexed(void) -{ - __asm__ __volatile__( - "# tlbgwi\n\t" - _ASM_INSN_IF_MIPS(0x4200000a) - _ASM_INSN32_IF_MM(0x0000217c)); -} - -static inline void guest_tlb_write_random(void) -{ - __asm__ __volatile__( - "# tlbgwr\n\t" - _ASM_INSN_IF_MIPS(0x4200000e) - _ASM_INSN32_IF_MM(0x0000317c)); -} - -/* - * Guest TLB Invalidate Flush - */ -static inline void guest_tlbinvf(void) -{ - __asm__ __volatile__( - "# tlbginvf\n\t" - _ASM_INSN_IF_MIPS(0x4200000c) - _ASM_INSN32_IF_MM(0x0000517c)); -} - -#endif /* !TOOLCHAIN_SUPPORTS_VIRT */ - /* * Manipulate bits in a register. */ diff --git a/arch/mips/include/asm/msa.h b/arch/mips/include/asm/msa.h index b1845102f8f9..b4f9577ed96a 100644 --- a/arch/mips/include/asm/msa.h +++ b/arch/mips/include/asm/msa.h @@ -160,7 +160,23 @@ static inline void init_msa_upper(void) _init_msa_upper(); } -#ifdef TOOLCHAIN_SUPPORTS_MSA +#ifndef TOOLCHAIN_SUPPORTS_MSA +/* + * Define assembler macros using .word for the c[ft]cmsa instructions in order + * to allow compilation with toolchains that do not support MSA. Once all + * toolchains in use support MSA these can be removed. + */ +_ASM_MACRO_2R(cfcmsa, rd, cs, + _ASM_INSN_IF_MIPS(0x787e0019 | __cs << 11 | __rd << 6) + _ASM_INSN32_IF_MM(0x587e0016 | __cs << 11 | __rd << 6)); +_ASM_MACRO_2R(ctcmsa, cd, rs, + _ASM_INSN_IF_MIPS(0x783e0019 | __rs << 11 | __cd << 6) + _ASM_INSN32_IF_MM(0x583e0016 | __rs << 11 | __cd << 6)); +#define _ASM_SET_MSA "" +#else /* TOOLCHAIN_SUPPORTS_MSA */ +#define _ASM_SET_MSA ".set\tfp=64\n\t" \ + ".set\tmsa\n\t" +#endif #define __BUILD_MSA_CTL_REG(name, cs) \ static inline unsigned int read_msa_##name(void) \ @@ -168,8 +184,7 @@ static inline unsigned int read_msa_##name(void) \ unsigned int reg; \ __asm__ __volatile__( \ " .set push\n" \ - " .set fp=64\n" \ - " .set msa\n" \ + _ASM_SET_MSA \ " cfcmsa %0, $" #cs "\n" \ " .set pop\n" \ : "=r"(reg)); \ @@ -180,52 +195,12 @@ static inline void write_msa_##name(unsigned int val) \ { \ __asm__ __volatile__( \ " .set push\n" \ - " .set fp=64\n" \ - " .set msa\n" \ + _ASM_SET_MSA \ " ctcmsa $" #cs ", %0\n" \ " .set pop\n" \ : : "r"(val)); \ } -#else /* !TOOLCHAIN_SUPPORTS_MSA */ - -/* - * Define functions using .word for the c[ft]cmsa instructions in order to - * allow compilation with toolchains that do not support MSA. Once all - * toolchains in use support MSA these can be removed. - */ - -#define __BUILD_MSA_CTL_REG(name, cs) \ -static inline unsigned int read_msa_##name(void) \ -{ \ - unsigned int reg; \ - __asm__ __volatile__( \ - " .set push\n" \ - " .set noat\n" \ - " # cfcmsa $1, $%1\n" \ - _ASM_INSN_IF_MIPS(0x787e0059 | %1 << 11) \ - _ASM_INSN32_IF_MM(0x587e0056 | %1 << 11) \ - " move %0, $1\n" \ - " .set pop\n" \ - : "=r"(reg) : "i"(cs)); \ - return reg; \ -} \ - \ -static inline void write_msa_##name(unsigned int val) \ -{ \ - __asm__ __volatile__( \ - " .set push\n" \ - " .set noat\n" \ - " move $1, %0\n" \ - " # ctcmsa $%1, $1\n" \ - _ASM_INSN_IF_MIPS(0x783e0819 | %1 << 6) \ - _ASM_INSN32_IF_MM(0x583e0816 | %1 << 6) \ - " .set pop\n" \ - : : "r"(val), "i"(cs)); \ -} - -#endif /* !TOOLCHAIN_SUPPORTS_MSA */ - __BUILD_MSA_CTL_REG(ir, 0) __BUILD_MSA_CTL_REG(csr, 1) __BUILD_MSA_CTL_REG(access, 2) diff --git a/arch/mips/jazz/setup.c b/arch/mips/jazz/setup.c index e4374a5651ce..448fd41792e4 100644 --- a/arch/mips/jazz/setup.c +++ b/arch/mips/jazz/setup.c @@ -32,22 +32,22 @@ static struct resource jazz_io_resources[] = { .start = 0x00, .end = 0x1f, .name = "dma1", - .flags = IORESOURCE_BUSY + .flags = IORESOURCE_IO | IORESOURCE_BUSY }, { .start = 0x40, .end = 0x5f, .name = "timer", - .flags = IORESOURCE_BUSY + .flags = IORESOURCE_IO | IORESOURCE_BUSY }, { .start = 0x80, .end = 0x8f, .name = "dma page reg", - .flags = IORESOURCE_BUSY + .flags = IORESOURCE_IO | IORESOURCE_BUSY }, { .start = 0xc0, .end = 0xdf, .name = "dma2", - .flags = IORESOURCE_BUSY + .flags = IORESOURCE_IO | IORESOURCE_BUSY } }; diff --git a/arch/mips/jz4740/Kconfig b/arch/mips/jz4740/Kconfig index 643af2012e14..4dd0c446ecec 100644 --- a/arch/mips/jz4740/Kconfig +++ b/arch/mips/jz4740/Kconfig @@ -8,6 +8,10 @@ config JZ4740_QI_LB60 bool "Qi Hardware Ben NanoNote" select MACH_JZ4740 +config JZ4770_GCW0 + bool "Game Consoles Worldwide GCW Zero" + select MACH_JZ4770 + config JZ4780_CI20 bool "MIPS Creator CI20" select MACH_JZ4780 @@ -18,6 +22,12 @@ config MACH_JZ4740 bool select SYS_HAS_CPU_MIPS32_R1 +config MACH_JZ4770 + bool + select MIPS_CPU_SCACHE + select SYS_HAS_CPU_MIPS32_R2 + select SYS_SUPPORTS_HIGHMEM + config MACH_JZ4780 bool select MIPS_CPU_SCACHE diff --git a/arch/mips/jz4740/prom.c b/arch/mips/jz4740/prom.c index 47e857194ce6..eb9f2f97bedb 100644 --- a/arch/mips/jz4740/prom.c +++ b/arch/mips/jz4740/prom.c @@ -20,33 +20,12 @@ #include <linux/serial_reg.h> #include <asm/bootinfo.h> +#include <asm/fw/fw.h> #include <asm/mach-jz4740/base.h> -static __init void jz4740_init_cmdline(int argc, char *argv[]) -{ - unsigned int count = COMMAND_LINE_SIZE - 1; - int i; - char *dst = &(arcs_cmdline[0]); - char *src; - - for (i = 1; i < argc && count; ++i) { - src = argv[i]; - while (*src && count) { - *dst++ = *src++; - --count; - } - *dst++ = ' '; - } - if (i > 1) - --dst; - - *dst = 0; -} - void __init prom_init(void) { - jz4740_init_cmdline((int)fw_arg0, (char **)fw_arg1); - mips_machtype = MACH_INGENIC_JZ4740; + fw_init_cmdline(); } void __init prom_free_prom_memory(void) diff --git a/arch/mips/jz4740/setup.c b/arch/mips/jz4740/setup.c index 6d0152321819..afb40f8bce96 100644 --- a/arch/mips/jz4740/setup.c +++ b/arch/mips/jz4740/setup.c @@ -53,6 +53,16 @@ static void __init jz4740_detect_mem(void) add_memory_region(0, size, BOOT_MEM_RAM); } +static unsigned long __init get_board_mach_type(const void *fdt) +{ + if (!fdt_node_check_compatible(fdt, 0, "ingenic,jz4780")) + return MACH_INGENIC_JZ4780; + if (!fdt_node_check_compatible(fdt, 0, "ingenic,jz4770")) + return MACH_INGENIC_JZ4770; + + return MACH_INGENIC_JZ4740; +} + void __init plat_mem_setup(void) { int offset; @@ -63,6 +73,8 @@ void __init plat_mem_setup(void) offset = fdt_path_offset(__dtb_start, "/memory"); if (offset < 0) jz4740_detect_mem(); + + mips_machtype = get_board_mach_type(__dtb_start); } void __init device_tree_init(void) @@ -75,10 +87,14 @@ void __init device_tree_init(void) const char *get_system_type(void) { - if (IS_ENABLED(CONFIG_MACH_JZ4780)) + switch (mips_machtype) { + case MACH_INGENIC_JZ4780: return "JZ4780"; - - return "JZ4740"; + case MACH_INGENIC_JZ4770: + return "JZ4770"; + default: + return "JZ4740"; + } } void __init arch_init_irq(void) diff --git a/arch/mips/jz4740/time.c b/arch/mips/jz4740/time.c index bb1ad5119da4..2ca9160f642a 100644 --- a/arch/mips/jz4740/time.c +++ b/arch/mips/jz4740/time.c @@ -113,7 +113,7 @@ static struct clock_event_device jz4740_clockevent = { #ifdef CONFIG_MACH_JZ4740 .irq = JZ4740_IRQ_TCU0, #endif -#ifdef CONFIG_MACH_JZ4780 +#if defined(CONFIG_MACH_JZ4770) || defined(CONFIG_MACH_JZ4780) .irq = JZ4780_IRQ_TCU2, #endif }; diff --git a/arch/mips/kernel/branch.c b/arch/mips/kernel/branch.c index b79ed9af9886..e48f6c0a9e4a 100644 --- a/arch/mips/kernel/branch.c +++ b/arch/mips/kernel/branch.c @@ -399,7 +399,7 @@ int __MIPS16e_compute_return_epc(struct pt_regs *regs) * * @regs: Pointer to pt_regs * @insn: branch instruction to decode - * @returns: -EFAULT on error and forces SIGILL, and on success + * Return: -EFAULT on error and forces SIGILL, and on success * returns 0 or BRANCH_LIKELY_TAKEN as appropriate after * evaluating the branch. * diff --git a/arch/mips/kernel/cps-vec.S b/arch/mips/kernel/cps-vec.S index e68e6e04063a..1025f937ab0e 100644 --- a/arch/mips/kernel/cps-vec.S +++ b/arch/mips/kernel/cps-vec.S @@ -388,15 +388,16 @@ LEAF(mips_cps_boot_vpes) #elif defined(CONFIG_MIPS_MT) - .set push - .set MIPS_ISA_LEVEL_RAW - .set mt - /* If the core doesn't support MT then return */ has_mt t0, 5f /* Enter VPE configuration state */ + .set push + .set MIPS_ISA_LEVEL_RAW + .set mt dvpe + .set pop + PTR_LA t1, 1f jr.hb t1 nop @@ -422,6 +423,10 @@ LEAF(mips_cps_boot_vpes) mtc0 t0, CP0_VPECONTROL ehb + .set push + .set MIPS_ISA_LEVEL_RAW + .set mt + /* Skip the VPE if its TC is not halted */ mftc0 t0, CP0_TCHALT beqz t0, 2f @@ -495,6 +500,8 @@ LEAF(mips_cps_boot_vpes) ehb evpe + .set pop + /* Check whether this VPE is meant to be running */ li t0, 1 sll t0, t0, a1 @@ -509,7 +516,7 @@ LEAF(mips_cps_boot_vpes) 1: jr.hb t0 nop -2: .set pop +2: #endif /* CONFIG_MIPS_MT_SMP */ diff --git a/arch/mips/kernel/ftrace.c b/arch/mips/kernel/ftrace.c index 99285be0e088..7f3dfdbc3657 100644 --- a/arch/mips/kernel/ftrace.c +++ b/arch/mips/kernel/ftrace.c @@ -361,7 +361,7 @@ void prepare_ftrace_return(unsigned long *parent_ra_addr, unsigned long self_ra, * If fails when getting the stack address of the non-leaf function's * ra, stop function graph tracer and return */ - if (parent_ra_addr == 0) + if (parent_ra_addr == NULL) goto out; #endif /* *parent_ra_addr = return_hooker; */ diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index 702c678de116..85bc601e9a0d 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c @@ -826,25 +826,6 @@ static void __init arch_mem_init(char **cmdline_p) struct memblock_region *reg; extern void plat_mem_setup(void); - /* call board setup routine */ - plat_mem_setup(); - - /* - * Make sure all kernel memory is in the maps. The "UP" and - * "DOWN" are opposite for initdata since if it crosses over - * into another memory section you don't want that to be - * freed when the initdata is freed. - */ - arch_mem_addpart(PFN_DOWN(__pa_symbol(&_text)) << PAGE_SHIFT, - PFN_UP(__pa_symbol(&_edata)) << PAGE_SHIFT, - BOOT_MEM_RAM); - arch_mem_addpart(PFN_UP(__pa_symbol(&__init_begin)) << PAGE_SHIFT, - PFN_DOWN(__pa_symbol(&__init_end)) << PAGE_SHIFT, - BOOT_MEM_INIT_RAM); - - pr_info("Determined physical RAM map:\n"); - print_memory_map(); - #if defined(CONFIG_CMDLINE_BOOL) && defined(CONFIG_CMDLINE_OVERRIDE) strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE); #else @@ -872,6 +853,26 @@ static void __init arch_mem_init(char **cmdline_p) } #endif #endif + + /* call board setup routine */ + plat_mem_setup(); + + /* + * Make sure all kernel memory is in the maps. The "UP" and + * "DOWN" are opposite for initdata since if it crosses over + * into another memory section you don't want that to be + * freed when the initdata is freed. + */ + arch_mem_addpart(PFN_DOWN(__pa_symbol(&_text)) << PAGE_SHIFT, + PFN_UP(__pa_symbol(&_edata)) << PAGE_SHIFT, + BOOT_MEM_RAM); + arch_mem_addpart(PFN_UP(__pa_symbol(&__init_begin)) << PAGE_SHIFT, + PFN_DOWN(__pa_symbol(&__init_end)) << PAGE_SHIFT, + BOOT_MEM_INIT_RAM); + + pr_info("Determined physical RAM map:\n"); + print_memory_map(); + strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE); *cmdline_p = command_line; diff --git a/arch/mips/kernel/smp-cps.c b/arch/mips/kernel/smp-cps.c index ecc1a853f48d..03f1026ad148 100644 --- a/arch/mips/kernel/smp-cps.c +++ b/arch/mips/kernel/smp-cps.c @@ -439,8 +439,6 @@ void play_dead(void) pr_debug("CPU%d going offline\n", cpu); if (cpu_has_mipsmt || cpu_has_vp) { - core = cpu_core(&cpu_data[cpu]); - /* Look for another online VPE within the core */ for_each_online_cpu(cpu_death_sibling) { if (!cpus_are_siblings(cpu, cpu_death_sibling)) diff --git a/arch/mips/kernel/watch.c b/arch/mips/kernel/watch.c index 19fcab7348b1..0e61a5b7647f 100644 --- a/arch/mips/kernel/watch.c +++ b/arch/mips/kernel/watch.c @@ -18,27 +18,24 @@ void mips_install_watch_registers(struct task_struct *t) { struct mips3264_watch_reg_state *watches = &t->thread.watch.mips3264; + unsigned int watchhi = MIPS_WATCHHI_G | /* Trap all ASIDs */ + MIPS_WATCHHI_IRW; /* Clear result bits */ + switch (current_cpu_data.watch_reg_use_cnt) { default: BUG(); case 4: write_c0_watchlo3(watches->watchlo[3]); - /* Write 1 to the I, R, and W bits to clear them, and - 1 to G so all ASIDs are trapped. */ - write_c0_watchhi3(MIPS_WATCHHI_G | MIPS_WATCHHI_IRW | - watches->watchhi[3]); + write_c0_watchhi3(watchhi | watches->watchhi[3]); case 3: write_c0_watchlo2(watches->watchlo[2]); - write_c0_watchhi2(MIPS_WATCHHI_G | MIPS_WATCHHI_IRW | - watches->watchhi[2]); + write_c0_watchhi2(watchhi | watches->watchhi[2]); case 2: write_c0_watchlo1(watches->watchlo[1]); - write_c0_watchhi1(MIPS_WATCHHI_G | MIPS_WATCHHI_IRW | - watches->watchhi[1]); + write_c0_watchhi1(watchhi | watches->watchhi[1]); case 1: write_c0_watchlo0(watches->watchlo[0]); - write_c0_watchhi0(MIPS_WATCHHI_G | MIPS_WATCHHI_IRW | - watches->watchhi[0]); + write_c0_watchhi0(watchhi | watches->watchhi[0]); } } @@ -51,21 +48,19 @@ void mips_read_watch_registers(void) { struct mips3264_watch_reg_state *watches = ¤t->thread.watch.mips3264; + unsigned int watchhi_mask = MIPS_WATCHHI_MASK | MIPS_WATCHHI_IRW; + switch (current_cpu_data.watch_reg_use_cnt) { default: BUG(); case 4: - watches->watchhi[3] = (read_c0_watchhi3() & - (MIPS_WATCHHI_MASK | MIPS_WATCHHI_IRW)); + watches->watchhi[3] = (read_c0_watchhi3() & watchhi_mask); case 3: - watches->watchhi[2] = (read_c0_watchhi2() & - (MIPS_WATCHHI_MASK | MIPS_WATCHHI_IRW)); + watches->watchhi[2] = (read_c0_watchhi2() & watchhi_mask); case 2: - watches->watchhi[1] = (read_c0_watchhi1() & - (MIPS_WATCHHI_MASK | MIPS_WATCHHI_IRW)); + watches->watchhi[1] = (read_c0_watchhi1() & watchhi_mask); case 1: - watches->watchhi[0] = (read_c0_watchhi0() & - (MIPS_WATCHHI_MASK | MIPS_WATCHHI_IRW)); + watches->watchhi[0] = (read_c0_watchhi0() & watchhi_mask); } if (current_cpu_data.watch_reg_use_cnt == 1 && (watches->watchhi[0] & MIPS_WATCHHI_IRW) == 0) { diff --git a/arch/mips/loongson64/Kconfig b/arch/mips/loongson64/Kconfig index 6f109bb54cdb..bc2fdbfa8223 100644 --- a/arch/mips/loongson64/Kconfig +++ b/arch/mips/loongson64/Kconfig @@ -17,7 +17,6 @@ config LEMOTE_FULOONG2E select I8259 select ISA select IRQ_MIPS_CPU - select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_64BIT_KERNEL select SYS_SUPPORTS_LITTLE_ENDIAN select SYS_SUPPORTS_HIGHMEM @@ -49,7 +48,6 @@ config LEMOTE_MACH2F select ISA select SYS_HAS_CPU_LOONGSON2F select SYS_HAS_EARLY_PRINTK - select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_64BIT_KERNEL select SYS_SUPPORTS_HIGHMEM select SYS_SUPPORTS_LITTLE_ENDIAN diff --git a/arch/mips/loongson64/common/mem.c b/arch/mips/loongson64/common/mem.c index b01d52473da8..c549e525fc11 100644 --- a/arch/mips/loongson64/common/mem.c +++ b/arch/mips/loongson64/common/mem.c @@ -79,7 +79,7 @@ void __init prom_init_memory(void) (u64)loongson_memmap->map[i].mem_size << 20, BOOT_MEM_RAM); break; - case MEM_RESERVED: + case SYSTEM_RAM_RESERVED: add_memory_region(loongson_memmap->map[i].mem_start, (u64)loongson_memmap->map[i].mem_size << 20, BOOT_MEM_RESERVED); diff --git a/arch/mips/loongson64/loongson-3/numa.c b/arch/mips/loongson64/loongson-3/numa.c index f17ef520799a..9717106de4a5 100644 --- a/arch/mips/loongson64/loongson-3/numa.c +++ b/arch/mips/loongson64/loongson-3/numa.c @@ -166,7 +166,7 @@ static void __init szmem(unsigned int node) memblock_add_node(PFN_PHYS(start_pfn), PFN_PHYS(end_pfn - start_pfn), node); break; - case MEM_RESERVED: + case SYSTEM_RAM_RESERVED: pr_info("Node%d: mem_type:%d, mem_start:0x%llx, mem_size:0x%llx MB\n", (u32)node_id, mem_type, mem_start, mem_size); add_memory_region((node_id << 44) + mem_start, diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c index da6c1c0c30c1..62deb025970b 100644 --- a/arch/mips/math-emu/cp1emu.c +++ b/arch/mips/math-emu/cp1emu.c @@ -451,7 +451,7 @@ int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn, regs->cp0_epc + dec_insn.pc_inc + dec_insn.next_pc_inc; } - /* Fall through */ + /* fall through */ case jr_op: /* For R6, JR already emulated in jalr_op */ if (NO_R6EMU && insn.r_format.func == jr_op) @@ -471,10 +471,11 @@ int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn, regs->regs[31] = regs->cp0_epc + dec_insn.pc_inc + dec_insn.next_pc_inc; - /* Fall through */ + /* fall through */ case bltzl_op: if (NO_R6EMU) break; + /* fall through */ case bltz_op: if ((long)regs->regs[insn.i_format.rs] < 0) *contpc = regs->cp0_epc + @@ -494,10 +495,11 @@ int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn, regs->regs[31] = regs->cp0_epc + dec_insn.pc_inc + dec_insn.next_pc_inc; - /* Fall through */ + /* fall through */ case bgezl_op: if (NO_R6EMU) break; + /* fall through */ case bgez_op: if ((long)regs->regs[insn.i_format.rs] >= 0) *contpc = regs->cp0_epc + @@ -512,11 +514,12 @@ int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn, break; case jalx_op: set_isa16_mode(bit); + /* fall through */ case jal_op: regs->regs[31] = regs->cp0_epc + dec_insn.pc_inc + dec_insn.next_pc_inc; - /* Fall through */ + /* fall through */ case j_op: *contpc = regs->cp0_epc + dec_insn.pc_inc; *contpc >>= 28; @@ -528,6 +531,7 @@ int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn, case beql_op: if (NO_R6EMU) break; + /* fall through */ case beq_op: if (regs->regs[insn.i_format.rs] == regs->regs[insn.i_format.rt]) @@ -542,6 +546,7 @@ int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn, case bnel_op: if (NO_R6EMU) break; + /* fall through */ case bne_op: if (regs->regs[insn.i_format.rs] != regs->regs[insn.i_format.rt]) @@ -556,6 +561,7 @@ int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn, case blezl_op: if (!insn.i_format.rt && NO_R6EMU) break; + /* fall through */ case blez_op: /* @@ -593,6 +599,7 @@ int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn, case bgtzl_op: if (!insn.i_format.rt && NO_R6EMU) break; + /* fall through */ case bgtz_op: /* * Compact branches for R6 for the @@ -729,7 +736,8 @@ int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn, return 1; } - /* R2/R6 compatible cop1 instruction. Fall through */ + /* R2/R6 compatible cop1 instruction */ + /* fall through */ case cop2_op: case cop1x_op: if (insn.i_format.rs == bc_op) { @@ -1190,7 +1198,8 @@ emul: if (!cpu_has_mips_r6 || delay_slot(xcp)) return SIGILL; - cond = likely = 0; + likely = 0; + cond = 0; fpr = ¤t->thread.fpu.fpr[MIPSInst_RT(ir)]; bit0 = get_fpr32(fpr, 0) & 0x1; switch (MIPSInst_RS(ir)) { @@ -1220,14 +1229,14 @@ emul: case bcfl_op: if (cpu_has_mips_2_3_4_5_r) likely = 1; - /* Fall through */ + /* fall through */ case bcf_op: cond = !cond; break; case bctl_op: if (cpu_has_mips_2_3_4_5_r) likely = 1; - /* Fall through */ + /* fall through */ case bct_op: break; } @@ -1353,7 +1362,8 @@ branch_common: return SIGILL; /* a real fpu computation instruction */ - if ((sig = fpu_emu(xcp, ctx, ir))) + sig = fpu_emu(xcp, ctx, ir); + if (sig) return sig; } break; diff --git a/arch/mips/math-emu/dp_add.c b/arch/mips/math-emu/dp_add.c index 8954ef031f84..678de20e4cb1 100644 --- a/arch/mips/math-emu/dp_add.c +++ b/arch/mips/math-emu/dp_add.c @@ -104,8 +104,7 @@ union ieee754dp ieee754dp_add(union ieee754dp x, union ieee754dp y) case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): DPDNORMX; - - /* FALL THROUGH */ + /* fall through */ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): DPDNORMY; diff --git a/arch/mips/math-emu/dp_div.c b/arch/mips/math-emu/dp_div.c index f4746f7c5f63..3063ae3ab3b9 100644 --- a/arch/mips/math-emu/dp_div.c +++ b/arch/mips/math-emu/dp_div.c @@ -103,6 +103,7 @@ union ieee754dp ieee754dp_div(union ieee754dp x, union ieee754dp y) case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): DPDNORMX; + /* fall through */ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): DPDNORMY; diff --git a/arch/mips/math-emu/dp_fmax.c b/arch/mips/math-emu/dp_fmax.c index 5bec64f2884e..d1f984b40344 100644 --- a/arch/mips/math-emu/dp_fmax.c +++ b/arch/mips/math-emu/dp_fmax.c @@ -96,6 +96,7 @@ union ieee754dp ieee754dp_fmax(union ieee754dp x, union ieee754dp y) case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): DPDNORMX; + /* fall through */ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): DPDNORMY; @@ -224,6 +225,7 @@ union ieee754dp ieee754dp_fmaxa(union ieee754dp x, union ieee754dp y) case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): DPDNORMX; + /* fall through */ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): DPDNORMY; diff --git a/arch/mips/math-emu/dp_fmin.c b/arch/mips/math-emu/dp_fmin.c index a287b23818d8..f98b96135c8d 100644 --- a/arch/mips/math-emu/dp_fmin.c +++ b/arch/mips/math-emu/dp_fmin.c @@ -96,6 +96,7 @@ union ieee754dp ieee754dp_fmin(union ieee754dp x, union ieee754dp y) case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): DPDNORMX; + /* fall through */ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): DPDNORMY; @@ -224,6 +225,7 @@ union ieee754dp ieee754dp_fmina(union ieee754dp x, union ieee754dp y) case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): DPDNORMX; + /* fall through */ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): DPDNORMY; diff --git a/arch/mips/math-emu/dp_maddf.c b/arch/mips/math-emu/dp_maddf.c index 7ad79ed411f5..7ea2f8222026 100644 --- a/arch/mips/math-emu/dp_maddf.c +++ b/arch/mips/math-emu/dp_maddf.c @@ -16,7 +16,7 @@ /* 128 bits shift right logical with rounding. */ -void srl128(u64 *hptr, u64 *lptr, int count) +static void srl128(u64 *hptr, u64 *lptr, int count) { u64 low; @@ -157,6 +157,7 @@ static union ieee754dp _dp_maddf(union ieee754dp z, union ieee754dp x, case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): DPDNORMX; + /* fall through */ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): if (zc == IEEE754_CLASS_INF) @@ -173,7 +174,7 @@ static union ieee754dp _dp_maddf(union ieee754dp z, union ieee754dp x, case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM): if (zc == IEEE754_CLASS_INF) return ieee754dp_inf(zs); - /* fall through to real computations */ + /* continue to real computations */ } /* Finally get to do some computation */ @@ -201,9 +202,6 @@ static union ieee754dp _dp_maddf(union ieee754dp z, union ieee754dp x, * Multiply 64 bits xm and ym to give 128 bits result in hrm:lrm. */ - /* 32 * 32 => 64 */ -#define DPXMULT(x, y) ((u64)(x) * (u64)y) - lxm = xm; hxm = xm >> 32; lym = ym; diff --git a/arch/mips/math-emu/dp_mul.c b/arch/mips/math-emu/dp_mul.c index 60c8bfe40947..c34a6cdf1b25 100644 --- a/arch/mips/math-emu/dp_mul.c +++ b/arch/mips/math-emu/dp_mul.c @@ -101,6 +101,7 @@ union ieee754dp ieee754dp_mul(union ieee754dp x, union ieee754dp y) case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): DPDNORMX; + /* fall through */ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): DPDNORMY; @@ -128,9 +129,6 @@ union ieee754dp ieee754dp_mul(union ieee754dp x, union ieee754dp y) * Multiply 64 bits xm, ym to give high 64 bits rm with stickness. */ - /* 32 * 32 => 64 */ -#define DPXMULT(x, y) ((u64)(x) * (u64)y) - lxm = xm; hxm = xm >> 32; lym = ym; diff --git a/arch/mips/math-emu/dp_sqrt.c b/arch/mips/math-emu/dp_sqrt.c index cea907b83146..1d26c92e5295 100644 --- a/arch/mips/math-emu/dp_sqrt.c +++ b/arch/mips/math-emu/dp_sqrt.c @@ -91,7 +91,8 @@ union ieee754dp ieee754dp_sqrt(union ieee754dp x) scalx -= 256; } - y = x = builddp(0, xe + DP_EBIAS, xm & ~DP_HIDDEN_BIT); + x = builddp(0, xe + DP_EBIAS, xm & ~DP_HIDDEN_BIT); + y = x; /* magic initial approximation to almost 8 sig. bits */ yh = y.bits >> 32; @@ -108,7 +109,8 @@ union ieee754dp ieee754dp_sqrt(union ieee754dp x) /* triple to almost 56 sig. bits: y ~= sqrt(x) to within 1 ulp */ /* t=y*y; z=t; pt[n0]+=0x00100000; t+=z; z=(x-z)*y; */ - z = t = ieee754dp_mul(y, y); + t = ieee754dp_mul(y, y); + z = t; t.bexp += 0x001; t = ieee754dp_add(t, z); z = ieee754dp_mul(ieee754dp_sub(x, z), y); @@ -140,7 +142,7 @@ union ieee754dp ieee754dp_sqrt(union ieee754dp x) switch (oldcsr.rm) { case FPU_CSR_RU: y.bits += 1; - /* drop through */ + /* fall through */ case FPU_CSR_RN: t.bits += 1; break; diff --git a/arch/mips/math-emu/dp_sub.c b/arch/mips/math-emu/dp_sub.c index fc17a781b9ae..3cc48b86519b 100644 --- a/arch/mips/math-emu/dp_sub.c +++ b/arch/mips/math-emu/dp_sub.c @@ -106,7 +106,7 @@ union ieee754dp ieee754dp_sub(union ieee754dp x, union ieee754dp y) case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): DPDNORMX; - /* FALL THROUGH */ + /* fall through */ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): /* normalize ym,ye */ diff --git a/arch/mips/math-emu/ieee754dp.h b/arch/mips/math-emu/ieee754dp.h index 9ba023004eb6..a56707b75282 100644 --- a/arch/mips/math-emu/ieee754dp.h +++ b/arch/mips/math-emu/ieee754dp.h @@ -55,6 +55,9 @@ static inline int ieee754dp_finite(union ieee754dp x) #define XDPSRS1(v) \ (((v) >> 1) | ((v) & 1)) +/* 32bit * 32bit => 64bit unsigned integer multiplication */ +#define DPXMULT(x, y) ((u64)(x) * (u64)y) + /* convert denormal to normalized with extended exponent */ #define DPDNORMx(m,e) \ while ((m >> DP_FBITS) == 0) { m <<= 1; e--; } diff --git a/arch/mips/math-emu/sp_add.c b/arch/mips/math-emu/sp_add.c index c55c0c00bca8..51dced9fbdaf 100644 --- a/arch/mips/math-emu/sp_add.c +++ b/arch/mips/math-emu/sp_add.c @@ -104,8 +104,7 @@ union ieee754sp ieee754sp_add(union ieee754sp x, union ieee754sp y) case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): SPDNORMX; - - /* FALL THROUGH */ + /* fall through */ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): SPDNORMY; diff --git a/arch/mips/math-emu/sp_div.c b/arch/mips/math-emu/sp_div.c index 23587b31ca87..5d2904960eb8 100644 --- a/arch/mips/math-emu/sp_div.c +++ b/arch/mips/math-emu/sp_div.c @@ -103,6 +103,7 @@ union ieee754sp ieee754sp_div(union ieee754sp x, union ieee754sp y) case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): SPDNORMX; + /* fall through */ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): SPDNORMY; diff --git a/arch/mips/math-emu/sp_fdp.c b/arch/mips/math-emu/sp_fdp.c index 5060e8fdcb0b..36a50f9082d1 100644 --- a/arch/mips/math-emu/sp_fdp.c +++ b/arch/mips/math-emu/sp_fdp.c @@ -46,7 +46,8 @@ union ieee754sp ieee754sp_fdp(union ieee754dp x) case IEEE754_CLASS_SNAN: x = ieee754dp_nanxcpt(x); EXPLODEXDP; - /* Fall through. */ + /* fall through */ + case IEEE754_CLASS_QNAN: y = ieee754sp_nan_fdp(xs, xm); if (!ieee754_csr.nan2008) { diff --git a/arch/mips/math-emu/sp_fmax.c b/arch/mips/math-emu/sp_fmax.c index 74a5a00d2f22..22019ed691df 100644 --- a/arch/mips/math-emu/sp_fmax.c +++ b/arch/mips/math-emu/sp_fmax.c @@ -96,6 +96,7 @@ union ieee754sp ieee754sp_fmax(union ieee754sp x, union ieee754sp y) case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): SPDNORMX; + /* fall through */ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): SPDNORMY; @@ -224,6 +225,7 @@ union ieee754sp ieee754sp_fmaxa(union ieee754sp x, union ieee754sp y) case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): SPDNORMX; + /* fall through */ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): SPDNORMY; diff --git a/arch/mips/math-emu/sp_fmin.c b/arch/mips/math-emu/sp_fmin.c index c51385f46b09..feaec3985cca 100644 --- a/arch/mips/math-emu/sp_fmin.c +++ b/arch/mips/math-emu/sp_fmin.c @@ -96,6 +96,7 @@ union ieee754sp ieee754sp_fmin(union ieee754sp x, union ieee754sp y) case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): SPDNORMX; + /* fall through */ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): SPDNORMY; @@ -224,6 +225,7 @@ union ieee754sp ieee754sp_fmina(union ieee754sp x, union ieee754sp y) case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): SPDNORMX; + /* fall through */ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): SPDNORMY; diff --git a/arch/mips/math-emu/sp_maddf.c b/arch/mips/math-emu/sp_maddf.c index f823338dbb65..07ba675401e2 100644 --- a/arch/mips/math-emu/sp_maddf.c +++ b/arch/mips/math-emu/sp_maddf.c @@ -126,6 +126,7 @@ static union ieee754sp _sp_maddf(union ieee754sp z, union ieee754sp x, case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): SPDNORMX; + /* fall through */ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): if (zc == IEEE754_CLASS_INF) @@ -142,7 +143,7 @@ static union ieee754sp _sp_maddf(union ieee754sp z, union ieee754sp x, case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM): if (zc == IEEE754_CLASS_INF) return ieee754sp_inf(zs); - /* fall through to real computations */ + /* continue to real computations */ } /* Finally get to do some computation */ diff --git a/arch/mips/math-emu/sp_mul.c b/arch/mips/math-emu/sp_mul.c index 4015101fbc37..fde71e293ec4 100644 --- a/arch/mips/math-emu/sp_mul.c +++ b/arch/mips/math-emu/sp_mul.c @@ -101,6 +101,7 @@ union ieee754sp ieee754sp_mul(union ieee754sp x, union ieee754sp y) case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): SPDNORMX; + /* fall through */ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): SPDNORMY; diff --git a/arch/mips/math-emu/sp_sqrt.c b/arch/mips/math-emu/sp_sqrt.c index 67059c33a250..9cc83f012342 100644 --- a/arch/mips/math-emu/sp_sqrt.c +++ b/arch/mips/math-emu/sp_sqrt.c @@ -82,7 +82,8 @@ union ieee754sp ieee754sp_sqrt(union ieee754sp x) /* generate sqrt(x) bit by bit */ ix += ix; - q = s = 0; /* q = sqrt(x) */ + s = 0; + q = 0; /* q = sqrt(x) */ r = 0x01000000; /* r = moving bit from right to left */ while (r != 0) { diff --git a/arch/mips/math-emu/sp_sub.c b/arch/mips/math-emu/sp_sub.c index dc998ed47295..9f2ff72c3d6b 100644 --- a/arch/mips/math-emu/sp_sub.c +++ b/arch/mips/math-emu/sp_sub.c @@ -106,6 +106,7 @@ union ieee754sp ieee754sp_sub(union ieee754sp x, union ieee754sp y) case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): SPDNORMX; + /* fall through */ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): SPDNORMY; diff --git a/arch/mips/math-emu/sp_tlong.c b/arch/mips/math-emu/sp_tlong.c index a2450c7e452a..bca5ac995801 100644 --- a/arch/mips/math-emu/sp_tlong.c +++ b/arch/mips/math-emu/sp_tlong.c @@ -20,7 +20,6 @@ */ #include "ieee754sp.h" -#include "ieee754dp.h" s64 ieee754sp_tlong(union ieee754sp x) { diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c index 237532e89919..dcafa43613b6 100644 --- a/arch/mips/mm/dma-default.c +++ b/arch/mips/mm/dma-default.c @@ -370,11 +370,6 @@ static void mips_dma_sync_sg_for_device(struct device *dev, } } -static int mips_dma_mapping_error(struct device *dev, dma_addr_t dma_addr) -{ - return 0; -} - static int mips_dma_supported(struct device *dev, u64 mask) { return plat_dma_supported(dev, mask); @@ -401,7 +396,6 @@ static const struct dma_map_ops mips_default_dma_map_ops = { .sync_single_for_device = mips_dma_sync_single_for_device, .sync_sg_for_cpu = mips_dma_sync_sg_for_cpu, .sync_sg_for_device = mips_dma_sync_sg_for_device, - .mapping_error = mips_dma_mapping_error, .dma_supported = mips_dma_supported, .cache_sync = mips_dma_cache_sync, }; diff --git a/arch/mips/mm/sc-mips.c b/arch/mips/mm/sc-mips.c index 548acb7f8557..394673991bab 100644 --- a/arch/mips/mm/sc-mips.c +++ b/arch/mips/mm/sc-mips.c @@ -16,6 +16,7 @@ #include <asm/mmu_context.h> #include <asm/r4kcache.h> #include <asm/mips-cps.h> +#include <asm/bootinfo.h> /* * MIPS32/MIPS64 L2 cache handling @@ -220,6 +221,14 @@ static inline int __init mips_sc_probe(void) else return 0; + /* + * According to config2 it would be 5-ways, but that is contradicted + * by all documentation. + */ + if (current_cpu_type() == CPU_JZRISC && + mips_machtype == MACH_INGENIC_JZ4770) + c->scache.ways = 4; + c->scache.waysize = c->scache.sets * c->scache.linesz; c->scache.waybit = __ffs(c->scache.waysize); diff --git a/arch/mips/mti-malta/malta-setup.c b/arch/mips/mti-malta/malta-setup.c index de34adb76157..7b63914d2e58 100644 --- a/arch/mips/mti-malta/malta-setup.c +++ b/arch/mips/mti-malta/malta-setup.c @@ -47,31 +47,31 @@ static struct resource standard_io_resources[] = { .name = "dma1", .start = 0x00, .end = 0x1f, - .flags = IORESOURCE_BUSY + .flags = IORESOURCE_IO | IORESOURCE_BUSY }, { .name = "timer", .start = 0x40, .end = 0x5f, - .flags = IORESOURCE_BUSY + .flags = IORESOURCE_IO | IORESOURCE_BUSY }, { .name = "keyboard", .start = 0x60, .end = 0x6f, - .flags = IORESOURCE_BUSY + .flags = IORESOURCE_IO | IORESOURCE_BUSY }, { .name = "dma page reg", .start = 0x80, .end = 0x8f, - .flags = IORESOURCE_BUSY + .flags = IORESOURCE_IO | IORESOURCE_BUSY }, { .name = "dma2", .start = 0xc0, .end = 0xdf, - .flags = IORESOURCE_BUSY + .flags = IORESOURCE_IO | IORESOURCE_BUSY }, }; diff --git a/arch/mips/txx9/rbtx4939/setup.c b/arch/mips/txx9/rbtx4939/setup.c index 8b937300fb7f..fd26fadc8617 100644 --- a/arch/mips/txx9/rbtx4939/setup.c +++ b/arch/mips/txx9/rbtx4939/setup.c @@ -186,7 +186,7 @@ static void __init rbtx4939_update_ioc_pen(void) #define RBTX4939_MAX_7SEGLEDS 8 -#if IS_ENABLED(CONFIG_LEDS_CLASS) +#if IS_BUILTIN(CONFIG_LEDS_CLASS) static u8 led_val[RBTX4939_MAX_7SEGLEDS]; struct rbtx4939_led_data { struct led_classdev cdev; @@ -261,7 +261,7 @@ static inline void rbtx4939_led_setup(void) static void __rbtx4939_7segled_putc(unsigned int pos, unsigned char val) { -#if IS_ENABLED(CONFIG_LEDS_CLASS) +#if IS_BUILTIN(CONFIG_LEDS_CLASS) unsigned long flags; local_irq_save(flags); /* bit7: reserved for LED class */ diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 9d3329811cc1..73ce5dd07642 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -141,6 +141,7 @@ config PPC select ARCH_HAS_GCOV_PROFILE_ALL select ARCH_HAS_PHYS_TO_DMA select ARCH_HAS_PMEM_API if PPC64 + select ARCH_HAS_MEMBARRIER_CALLBACKS select ARCH_HAS_SCALED_CPUTIME if VIRT_CPU_ACCOUNTING_NATIVE select ARCH_HAS_SG_CHAIN select ARCH_HAS_STRICT_KERNEL_RWX if ((PPC_BOOK3S_64 || PPC32) && !RELOCATABLE && !HIBERNATION) diff --git a/arch/powerpc/include/asm/membarrier.h b/arch/powerpc/include/asm/membarrier.h new file mode 100644 index 000000000000..6e20bb5c74ea --- /dev/null +++ b/arch/powerpc/include/asm/membarrier.h @@ -0,0 +1,27 @@ +#ifndef _ASM_POWERPC_MEMBARRIER_H +#define _ASM_POWERPC_MEMBARRIER_H + +static inline void membarrier_arch_switch_mm(struct mm_struct *prev, + struct mm_struct *next, + struct task_struct *tsk) +{ + /* + * Only need the full barrier when switching between processes. + * Barrier when switching from kernel to userspace is not + * required here, given that it is implied by mmdrop(). Barrier + * when switching from userspace to kernel is not needed after + * store to rq->curr. + */ + if (likely(!(atomic_read(&next->membarrier_state) & + (MEMBARRIER_STATE_PRIVATE_EXPEDITED | + MEMBARRIER_STATE_GLOBAL_EXPEDITED)) || !prev)) + return; + + /* + * The membarrier system call requires a full memory barrier + * after storing to rq->curr, before going back to user-space. + */ + smp_mb(); +} + +#endif /* _ASM_POWERPC_MEMBARRIER_H */ diff --git a/arch/powerpc/kernel/eeh.c b/arch/powerpc/kernel/eeh.c index cc649809885e..2b9df0040d6b 100644 --- a/arch/powerpc/kernel/eeh.c +++ b/arch/powerpc/kernel/eeh.c @@ -756,14 +756,14 @@ int eeh_restore_vf_config(struct pci_dn *pdn) eeh_ops->write_config(pdn, edev->pcie_cap + PCI_EXP_DEVCTL, 2, devctl); - /* Disable Completion Timeout */ + /* Disable Completion Timeout if possible */ eeh_ops->read_config(pdn, edev->pcie_cap + PCI_EXP_DEVCAP2, 4, &cap2); - if (cap2 & 0x10) { + if (cap2 & PCI_EXP_DEVCAP2_COMP_TMOUT_DIS) { eeh_ops->read_config(pdn, edev->pcie_cap + PCI_EXP_DEVCTL2, 4, &cap2); - cap2 |= 0x10; + cap2 |= PCI_EXP_DEVCTL2_COMP_TMOUT_DIS; eeh_ops->write_config(pdn, edev->pcie_cap + PCI_EXP_DEVCTL2, 4, cap2); diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index 208e623b2557..ae2ede4de6be 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c @@ -362,8 +362,7 @@ struct pci_controller* pci_find_hose_for_OF_device(struct device_node* node) */ static int pci_read_irq_line(struct pci_dev *pci_dev) { - struct of_phandle_args oirq; - unsigned int virq; + unsigned int virq = 0; pr_debug("PCI: Try to map irq for %s...\n", pci_name(pci_dev)); @@ -371,7 +370,7 @@ static int pci_read_irq_line(struct pci_dev *pci_dev) memset(&oirq, 0xff, sizeof(oirq)); #endif /* Try to get a mapping from the device-tree */ - if (of_irq_parse_pci(pci_dev, &oirq)) { + if (!of_irq_parse_and_map_pci(pci_dev, 0, 0)) { u8 line, pin; /* If that fails, lets fallback to what is in the config @@ -395,11 +394,6 @@ static int pci_read_irq_line(struct pci_dev *pci_dev) virq = irq_create_mapping(NULL, line); if (virq) irq_set_irq_type(virq, IRQ_TYPE_LEVEL_LOW); - } else { - pr_debug(" Got one, spec %d cells (0x%08x 0x%08x...) on %pOF\n", - oirq.args_count, oirq.args[0], oirq.args[1], oirq.np); - - virq = irq_create_of_mapping(&oirq); } if (!virq) { diff --git a/arch/powerpc/kernel/pci-hotplug.c b/arch/powerpc/kernel/pci-hotplug.c index 2d71269e7dc1..cf47b1aec4c2 100644 --- a/arch/powerpc/kernel/pci-hotplug.c +++ b/arch/powerpc/kernel/pci-hotplug.c @@ -104,7 +104,7 @@ EXPORT_SYMBOL_GPL(pci_hp_remove_devices); */ void pci_hp_add_devices(struct pci_bus *bus) { - int slotno, mode, pass, max; + int slotno, mode, max; struct pci_dev *dev; struct pci_controller *phb; struct device_node *dn = pci_bus_to_OF_node(bus); @@ -133,13 +133,17 @@ void pci_hp_add_devices(struct pci_bus *bus) pci_scan_slot(bus, PCI_DEVFN(slotno, 0)); pcibios_setup_bus_devices(bus); max = bus->busn_res.start; - for (pass = 0; pass < 2; pass++) { - list_for_each_entry(dev, &bus->devices, bus_list) { - if (pci_is_bridge(dev)) - max = pci_scan_bridge(bus, dev, - max, pass); - } - } + /* + * Scan bridges that are already configured. We don't touch + * them unless they are misconfigured (which will be done in + * the second scan below). + */ + for_each_pci_bridge(dev, bus) + max = pci_scan_bridge(bus, dev, max, 0); + + /* Scan bridges that need to be reconfigured */ + for_each_pci_bridge(dev, bus) + max = pci_scan_bridge(bus, dev, max, 1); } pcibios_finish_adding_to_bus(bus); } diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c index 1d817f4d97d9..85ad2f78b889 100644 --- a/arch/powerpc/kernel/pci_32.c +++ b/arch/powerpc/kernel/pci_32.c @@ -96,7 +96,8 @@ make_one_node_map(struct device_node* node, u8 pci_bus) reg = of_get_property(node, "reg", NULL); if (!reg) continue; - dev = pci_get_bus_and_slot(pci_bus, ((reg[0] >> 8) & 0xff)); + dev = pci_get_domain_bus_and_slot(0, pci_bus, + ((reg[0] >> 8) & 0xff)); if (!dev || !dev->subordinate) { pci_dev_put(dev); continue; diff --git a/arch/powerpc/kernel/pci_of_scan.c b/arch/powerpc/kernel/pci_of_scan.c index 20ceec4a5f5e..98f04725def7 100644 --- a/arch/powerpc/kernel/pci_of_scan.c +++ b/arch/powerpc/kernel/pci_of_scan.c @@ -369,11 +369,8 @@ static void __of_scan_bus(struct device_node *node, struct pci_bus *bus, pcibios_setup_bus_devices(bus); /* Now scan child busses */ - list_for_each_entry(dev, &bus->devices, bus_list) { - if (pci_is_bridge(dev)) { - of_scan_pci_bridge(dev); - } - } + for_each_pci_bridge(dev, bus) + of_scan_pci_bridge(dev); } /** diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c index f6eb7e8f4c93..fdb424a29f03 100644 --- a/arch/powerpc/mm/init_64.c +++ b/arch/powerpc/mm/init_64.c @@ -183,7 +183,8 @@ static __meminit void vmemmap_list_populate(unsigned long phys, vmemmap_list = vmem_back; } -int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node) +int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node, + struct vmem_altmap *altmap) { unsigned long page_size = 1 << mmu_psize_defs[mmu_vmemmap_psize].shift; @@ -193,17 +194,16 @@ int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node) pr_debug("vmemmap_populate %lx..%lx, node %d\n", start, end, node); for (; start < end; start += page_size) { - struct vmem_altmap *altmap; void *p; int rc; if (vmemmap_populated(start, page_size)) continue; - /* altmap lookups only work at section boundaries */ - altmap = to_vmem_altmap(SECTION_ALIGN_DOWN(start)); - - p = __vmemmap_alloc_block_buf(page_size, node, altmap); + if (altmap) + p = altmap_alloc_block_buf(page_size, altmap); + else + p = vmemmap_alloc_block_buf(page_size, node); if (!p) return -ENOMEM; @@ -256,7 +256,8 @@ static unsigned long vmemmap_list_free(unsigned long start) return vmem_back->phys; } -void __ref vmemmap_free(unsigned long start, unsigned long end) +void __ref vmemmap_free(unsigned long start, unsigned long end, + struct vmem_altmap *altmap) { unsigned long page_size = 1 << mmu_psize_defs[mmu_vmemmap_psize].shift; unsigned long page_order = get_order(page_size); @@ -267,7 +268,6 @@ void __ref vmemmap_free(unsigned long start, unsigned long end) for (; start < end; start += page_size) { unsigned long nr_pages, addr; - struct vmem_altmap *altmap; struct page *section_base; struct page *page; @@ -287,7 +287,6 @@ void __ref vmemmap_free(unsigned long start, unsigned long end) section_base = pfn_to_page(vmemmap_section_start(start)); nr_pages = 1 << page_order; - altmap = to_vmem_altmap((unsigned long) section_base); if (altmap) { vmem_altmap_free(altmap, nr_pages); } else if (PageReserved(page)) { diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c index 1281c6eb3a85..fe8c61149fb8 100644 --- a/arch/powerpc/mm/mem.c +++ b/arch/powerpc/mm/mem.c @@ -127,7 +127,8 @@ int __weak remove_section_mapping(unsigned long start, unsigned long end) return -ENODEV; } -int arch_add_memory(int nid, u64 start, u64 size, bool want_memblock) +int arch_add_memory(int nid, u64 start, u64 size, struct vmem_altmap *altmap, + bool want_memblock) { unsigned long start_pfn = start >> PAGE_SHIFT; unsigned long nr_pages = size >> PAGE_SHIFT; @@ -143,15 +144,14 @@ int arch_add_memory(int nid, u64 start, u64 size, bool want_memblock) return -EFAULT; } - return __add_pages(nid, start_pfn, nr_pages, want_memblock); + return __add_pages(nid, start_pfn, nr_pages, altmap, want_memblock); } #ifdef CONFIG_MEMORY_HOTREMOVE -int arch_remove_memory(u64 start, u64 size) +int arch_remove_memory(u64 start, u64 size, struct vmem_altmap *altmap) { unsigned long start_pfn = start >> PAGE_SHIFT; unsigned long nr_pages = size >> PAGE_SHIFT; - struct vmem_altmap *altmap; struct page *page; int ret; @@ -160,11 +160,10 @@ int arch_remove_memory(u64 start, u64 size) * when querying the zone. */ page = pfn_to_page(start_pfn); - altmap = to_vmem_altmap((unsigned long) page); if (altmap) page += vmem_altmap_offset(altmap); - ret = __remove_pages(page_zone(page), start_pfn, nr_pages); + ret = __remove_pages(page_zone(page), start_pfn, nr_pages, altmap); if (ret) return ret; diff --git a/arch/powerpc/mm/mmu_context.c b/arch/powerpc/mm/mmu_context.c index d60a62bf4fc7..0ab297c4cfad 100644 --- a/arch/powerpc/mm/mmu_context.c +++ b/arch/powerpc/mm/mmu_context.c @@ -12,6 +12,7 @@ #include <linux/mm.h> #include <linux/cpu.h> +#include <linux/sched/mm.h> #include <asm/mmu_context.h> @@ -58,6 +59,10 @@ void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next, * * On the read side the barrier is in pte_xchg(), which orders * the store to the PTE vs the load of mm_cpumask. + * + * This full barrier is needed by membarrier when switching + * between processes after store to rq->curr, before user-space + * memory accesses. */ smp_mb(); @@ -80,6 +85,8 @@ void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next, if (new_on_cpu) radix_kvm_prefetch_workaround(next); + else + membarrier_arch_switch_mm(prev, next, tsk); /* * The actual HW switching method differs between the various diff --git a/arch/powerpc/platforms/maple/time.c b/arch/powerpc/platforms/maple/time.c index 81799d70a1ee..cfddc87f81bf 100644 --- a/arch/powerpc/platforms/maple/time.c +++ b/arch/powerpc/platforms/maple/time.c @@ -134,7 +134,7 @@ int maple_set_rtc_time(struct rtc_time *tm) static struct resource rtc_iores = { .name = "rtc", - .flags = IORESOURCE_BUSY, + .flags = IORESOURCE_IO | IORESOURCE_BUSY, }; unsigned long __init maple_get_boot_time(void) diff --git a/arch/powerpc/platforms/powermac/feature.c b/arch/powerpc/platforms/powermac/feature.c index 466b84234683..3f82cb24eb2b 100644 --- a/arch/powerpc/platforms/powermac/feature.c +++ b/arch/powerpc/platforms/powermac/feature.c @@ -829,7 +829,7 @@ core99_ata100_enable(struct device_node *node, long value) if (value) { if (pci_device_from_OF_node(node, &pbus, &pid) == 0) - pdev = pci_get_bus_and_slot(pbus, pid); + pdev = pci_get_domain_bus_and_slot(0, pbus, pid); if (pdev == NULL) return 0; rc = pci_enable_device(pdev); diff --git a/arch/powerpc/sysdev/i8259.c b/arch/powerpc/sysdev/i8259.c index bafb014e1a7e..cb9a8b71fd0f 100644 --- a/arch/powerpc/sysdev/i8259.c +++ b/arch/powerpc/sysdev/i8259.c @@ -145,21 +145,21 @@ static struct resource pic1_iores = { .name = "8259 (master)", .start = 0x20, .end = 0x21, - .flags = IORESOURCE_BUSY, + .flags = IORESOURCE_IO | IORESOURCE_BUSY, }; static struct resource pic2_iores = { .name = "8259 (slave)", .start = 0xa0, .end = 0xa1, - .flags = IORESOURCE_BUSY, + .flags = IORESOURCE_IO | IORESOURCE_BUSY, }; static struct resource pic_edgectrl_iores = { .name = "8259 edge control", .start = 0x4d0, .end = 0x4d1, - .flags = IORESOURCE_BUSY, + .flags = IORESOURCE_IO | IORESOURCE_BUSY, }; static int i8259_host_match(struct irq_domain *h, struct device_node *node, diff --git a/arch/powerpc/sysdev/mv64x60_pci.c b/arch/powerpc/sysdev/mv64x60_pci.c index 50c411b1761e..1afcdb428e51 100644 --- a/arch/powerpc/sysdev/mv64x60_pci.c +++ b/arch/powerpc/sysdev/mv64x60_pci.c @@ -37,7 +37,7 @@ static ssize_t mv64x60_hs_reg_read(struct file *filp, struct kobject *kobj, if (count < MV64X60_VAL_LEN_MAX) return -EINVAL; - phb = pci_get_bus_and_slot(0, PCI_DEVFN(0, 0)); + phb = pci_get_domain_bus_and_slot(0, 0, PCI_DEVFN(0, 0)); if (!phb) return -ENODEV; pci_read_config_dword(phb, MV64X60_PCICFG_CPCI_HOTSWAP, &v); @@ -61,7 +61,7 @@ static ssize_t mv64x60_hs_reg_write(struct file *filp, struct kobject *kobj, if (sscanf(buf, "%i", &v) != 1) return -EINVAL; - phb = pci_get_bus_and_slot(0, PCI_DEVFN(0, 0)); + phb = pci_get_domain_bus_and_slot(0, 0, PCI_DEVFN(0, 0)); if (!phb) return -ENODEV; pci_write_config_dword(phb, MV64X60_PCICFG_CPCI_HOTSWAP, v); diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index 865e14f50c14..b6722c246d9c 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -22,6 +22,7 @@ config RISCV select GENERIC_ATOMIC64 if !64BIT || !RISCV_ISA_A select ARCH_WANT_OPTIONAL_GPIOLIB select HAVE_MEMBLOCK + select HAVE_MEMBLOCK_NODE_MAP select HAVE_DMA_API_DEBUG select HAVE_DMA_CONTIGUOUS select HAVE_GENERIC_DMA_COHERENT @@ -43,6 +44,10 @@ config MMU config ARCH_PHYS_ADDR_T_64BIT def_bool y +config ZONE_DMA32 + bool + default y + config ARCH_DMA_ADDR_T_64BIT def_bool y @@ -55,6 +60,9 @@ config PAGE_OFFSET config STACKTRACE_SUPPORT def_bool y +config TRACE_IRQFLAGS_SUPPORT + def_bool y + config RWSEM_GENERIC_SPINLOCK def_bool y @@ -107,6 +115,8 @@ config ARCH_RV64I bool "RV64I" select CPU_SUPPORTS_64BIT_KERNEL select 64BIT + select HAVE_FUNCTION_TRACER + select HAVE_FUNCTION_GRAPH_TRACER endchoice diff --git a/arch/riscv/include/asm/Kbuild b/arch/riscv/include/asm/Kbuild index 681ac0d09314..4286a5f83876 100644 --- a/arch/riscv/include/asm/Kbuild +++ b/arch/riscv/include/asm/Kbuild @@ -12,7 +12,6 @@ generic-y += errno.h generic-y += exec.h generic-y += fb.h generic-y += fcntl.h -generic-y += ftrace.h generic-y += futex.h generic-y += hardirq.h generic-y += hash.h diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h index 3c7a2c97e377..421fa3585798 100644 --- a/arch/riscv/include/asm/csr.h +++ b/arch/riscv/include/asm/csr.h @@ -40,15 +40,15 @@ #define SR_SD _AC(0x8000000000000000, UL) /* FS/XS dirty */ #endif -/* SPTBR flags */ +/* SATP flags */ #if __riscv_xlen == 32 -#define SPTBR_PPN _AC(0x003FFFFF, UL) -#define SPTBR_MODE_32 _AC(0x80000000, UL) -#define SPTBR_MODE SPTBR_MODE_32 +#define SATP_PPN _AC(0x003FFFFF, UL) +#define SATP_MODE_32 _AC(0x80000000, UL) +#define SATP_MODE SATP_MODE_32 #else -#define SPTBR_PPN _AC(0x00000FFFFFFFFFFF, UL) -#define SPTBR_MODE_39 _AC(0x8000000000000000, UL) -#define SPTBR_MODE SPTBR_MODE_39 +#define SATP_PPN _AC(0x00000FFFFFFFFFFF, UL) +#define SATP_MODE_39 _AC(0x8000000000000000, UL) +#define SATP_MODE SATP_MODE_39 #endif /* Interrupt Enable and Interrupt Pending flags */ diff --git a/arch/riscv/include/asm/ftrace.h b/arch/riscv/include/asm/ftrace.h new file mode 100644 index 000000000000..66d4175eb13e --- /dev/null +++ b/arch/riscv/include/asm/ftrace.h @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (C) 2017 Andes Technology Corporation */ + +/* + * The graph frame test is not possible if CONFIG_FRAME_POINTER is not enabled. + * Check arch/riscv/kernel/mcount.S for detail. + */ +#if defined(CONFIG_FUNCTION_GRAPH_TRACER) && defined(CONFIG_FRAME_POINTER) +#define HAVE_FUNCTION_GRAPH_FP_TEST +#endif diff --git a/arch/riscv/include/asm/mmu_context.h b/arch/riscv/include/asm/mmu_context.h index 97424834dce2..336d60ec5698 100644 --- a/arch/riscv/include/asm/mmu_context.h +++ b/arch/riscv/include/asm/mmu_context.h @@ -39,16 +39,6 @@ static inline void destroy_context(struct mm_struct *mm) { } -static inline pgd_t *current_pgdir(void) -{ - return pfn_to_virt(csr_read(sptbr) & SPTBR_PPN); -} - -static inline void set_pgdir(pgd_t *pgd) -{ - csr_write(sptbr, virt_to_pfn(pgd) | SPTBR_MODE); -} - /* * When necessary, performs a deferred icache flush for the given MM context, * on the local CPU. RISC-V has no direct mechanism for instruction cache @@ -93,7 +83,12 @@ static inline void switch_mm(struct mm_struct *prev, cpumask_clear_cpu(cpu, mm_cpumask(prev)); cpumask_set_cpu(cpu, mm_cpumask(next)); - set_pgdir(next->pgd); + /* + * Use the old spbtr name instead of using the current satp + * name to support binutils 2.29 which doesn't know about the + * privileged ISA 1.10 yet. + */ + csr_write(sptbr, virt_to_pfn(next->pgd) | SATP_MODE); local_flush_tlb_all(); flush_icache_deferred(next); diff --git a/arch/riscv/include/asm/tlbflush.h b/arch/riscv/include/asm/tlbflush.h index 7b9c24ebdf52..7b209aec355d 100644 --- a/arch/riscv/include/asm/tlbflush.h +++ b/arch/riscv/include/asm/tlbflush.h @@ -36,7 +36,14 @@ static inline void local_flush_tlb_page(unsigned long addr) #define flush_tlb_all() local_flush_tlb_all() #define flush_tlb_page(vma, addr) local_flush_tlb_page(addr) -#define flush_tlb_range(vma, start, end) local_flush_tlb_all() + +static inline void flush_tlb_range(struct vm_area_struct *vma, + unsigned long start, unsigned long end) +{ + local_flush_tlb_all(); +} + +#define flush_tlb_mm(mm) flush_tlb_all() #else /* CONFIG_SMP */ @@ -45,16 +52,13 @@ static inline void local_flush_tlb_page(unsigned long addr) #define flush_tlb_all() sbi_remote_sfence_vma(0, 0, -1) #define flush_tlb_page(vma, addr) flush_tlb_range(vma, addr, 0) #define flush_tlb_range(vma, start, end) \ - sbi_remote_sfence_vma(0, start, (end) - (start)) + sbi_remote_sfence_vma(mm_cpumask((vma)->vm_mm)->bits, \ + start, (end) - (start)) +#define flush_tlb_mm(mm) \ + sbi_remote_sfence_vma(mm_cpumask(mm)->bits, 0, -1) #endif /* CONFIG_SMP */ -/* Flush the TLB entries of the specified mm context */ -static inline void flush_tlb_mm(struct mm_struct *mm) -{ - flush_tlb_all(); -} - /* Flush a range of kernel pages */ static inline void flush_tlb_kernel_range(unsigned long start, unsigned long end) diff --git a/arch/riscv/include/asm/unistd.h b/arch/riscv/include/asm/unistd.h index 2f704a5c4196..080fb28061de 100644 --- a/arch/riscv/include/asm/unistd.h +++ b/arch/riscv/include/asm/unistd.h @@ -11,7 +11,6 @@ * GNU General Public License for more details. */ -#define __ARCH_HAVE_MMU #define __ARCH_WANT_SYS_CLONE #include <uapi/asm/unistd.h> #include <uapi/asm/syscalls.h> diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile index ab8baf7bd142..196f62ffc428 100644 --- a/arch/riscv/kernel/Makefile +++ b/arch/riscv/kernel/Makefile @@ -2,6 +2,11 @@ # Makefile for the RISC-V Linux kernel # +ifdef CONFIG_FTRACE +CFLAGS_REMOVE_ftrace.o = -pg +CFLAGS_REMOVE_setup.o = -pg +endif + extra-y += head.o extra-y += vmlinux.lds @@ -29,5 +34,7 @@ CFLAGS_setup.o := -mcmodel=medany obj-$(CONFIG_SMP) += smpboot.o obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_MODULES) += module.o +obj-$(CONFIG_FUNCTION_TRACER) += mcount.o +obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o clean: diff --git a/arch/riscv/kernel/entry.S b/arch/riscv/kernel/entry.S index 7404ec222406..87fc045be51f 100644 --- a/arch/riscv/kernel/entry.S +++ b/arch/riscv/kernel/entry.S @@ -78,10 +78,13 @@ _save_context: REG_S x31, PT_T6(sp) /* - * Disable FPU to detect illegal usage of - * floating point in kernel space + * Disable user-mode memory access as it should only be set in the + * actual user copy routines. + * + * Disable the FPU to detect illegal usage of floating point in kernel + * space. */ - li t0, SR_FS + li t0, SR_SUM | SR_FS REG_L s0, TASK_TI_USER_SP(tp) csrrc s1, sstatus, t0 diff --git a/arch/riscv/kernel/ftrace.c b/arch/riscv/kernel/ftrace.c new file mode 100644 index 000000000000..d0de68d144cb --- /dev/null +++ b/arch/riscv/kernel/ftrace.c @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2013 Linaro Limited + * Author: AKASHI Takahiro <takahiro.akashi@linaro.org> + * Copyright (C) 2017 Andes Technology Corporation + */ + +#include <linux/ftrace.h> + +/* + * Most of this file is copied from arm64. + */ +void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr, + unsigned long frame_pointer) +{ + unsigned long return_hooker = (unsigned long)&return_to_handler; + unsigned long old; + struct ftrace_graph_ent trace; + int err; + + if (unlikely(atomic_read(¤t->tracing_graph_pause))) + return; + + /* + * We don't suffer access faults, so no extra fault-recovery assembly + * is needed here. + */ + old = *parent; + + trace.func = self_addr; + trace.depth = current->curr_ret_stack + 1; + + if (!ftrace_graph_entry(&trace)) + return; + + err = ftrace_push_return_trace(old, self_addr, &trace.depth, + frame_pointer, NULL); + if (err == -EBUSY) + return; + *parent = return_hooker; +} diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S index 78f670d70133..226eeb190f90 100644 --- a/arch/riscv/kernel/head.S +++ b/arch/riscv/kernel/head.S @@ -74,15 +74,15 @@ relocate: sub a1, a1, a0 add ra, ra, a1 - /* Point stvec to virtual address of intruction after sptbr write */ + /* Point stvec to virtual address of intruction after satp write */ la a0, 1f add a0, a0, a1 csrw stvec, a0 - /* Compute sptbr for kernel page tables, but don't load it yet */ + /* Compute satp for kernel page tables, but don't load it yet */ la a2, swapper_pg_dir srl a2, a2, PAGE_SHIFT - li a1, SPTBR_MODE + li a1, SATP_MODE or a2, a2, a1 /* diff --git a/arch/riscv/kernel/mcount.S b/arch/riscv/kernel/mcount.S new file mode 100644 index 000000000000..c46a778627be --- /dev/null +++ b/arch/riscv/kernel/mcount.S @@ -0,0 +1,126 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (C) 2017 Andes Technology Corporation */ + +#include <linux/init.h> +#include <linux/linkage.h> +#include <asm/asm.h> +#include <asm/csr.h> +#include <asm/unistd.h> +#include <asm/thread_info.h> +#include <asm/asm-offsets.h> +#include <asm-generic/export.h> +#include <asm/ftrace.h> + + .text + + .macro SAVE_ABI_STATE + addi sp, sp, -16 + sd s0, 0(sp) + sd ra, 8(sp) + addi s0, sp, 16 + .endm + + /* + * The call to ftrace_return_to_handler would overwrite the return + * register if a0 was not saved. + */ + .macro SAVE_RET_ABI_STATE + addi sp, sp, -32 + sd s0, 16(sp) + sd ra, 24(sp) + sd a0, 8(sp) + addi s0, sp, 32 + .endm + + .macro STORE_ABI_STATE + ld ra, 8(sp) + ld s0, 0(sp) + addi sp, sp, 16 + .endm + + .macro STORE_RET_ABI_STATE + ld ra, 24(sp) + ld s0, 16(sp) + ld a0, 8(sp) + addi sp, sp, 32 + .endm + +ENTRY(ftrace_stub) + ret +ENDPROC(ftrace_stub) + +#ifdef CONFIG_FUNCTION_GRAPH_TRACER +ENTRY(return_to_handler) +/* + * On implementing the frame point test, the ideal way is to compare the + * s0 (frame pointer, if enabled) on entry and the sp (stack pointer) on return. + * However, the psABI of variable-length-argument functions does not allow this. + * + * So alternatively we check the *old* frame pointer position, that is, the + * value stored in -16(s0) on entry, and the s0 on return. + */ +#ifdef HAVE_FUNCTION_GRAPH_FP_TEST + mv t6, s0 +#endif + SAVE_RET_ABI_STATE +#ifdef HAVE_FUNCTION_GRAPH_FP_TEST + mv a0, t6 +#endif + la t0, ftrace_return_to_handler + jalr t0 + mv a1, a0 + STORE_RET_ABI_STATE + jalr a1 +ENDPROC(return_to_handler) +EXPORT_SYMBOL(return_to_handler) +#endif + +ENTRY(_mcount) + la t4, ftrace_stub +#ifdef CONFIG_FUNCTION_GRAPH_TRACER + la t0, ftrace_graph_return + ld t1, 0(t0) + bne t1, t4, do_ftrace_graph_caller + + la t3, ftrace_graph_entry + ld t2, 0(t3) + la t6, ftrace_graph_entry_stub + bne t2, t6, do_ftrace_graph_caller +#endif + la t3, ftrace_trace_function + ld t5, 0(t3) + bne t5, t4, do_trace + ret + +#ifdef CONFIG_FUNCTION_GRAPH_TRACER +/* + * A pseudo representation for the function graph tracer: + * prepare_to_return(&ra_to_caller_of_caller, ra_to_caller) + */ +do_ftrace_graph_caller: + addi a0, s0, -8 + mv a1, ra +#ifdef HAVE_FUNCTION_GRAPH_FP_TEST + ld a2, -16(s0) +#endif + SAVE_ABI_STATE + la t0, prepare_ftrace_return + jalr t0 + STORE_ABI_STATE + ret +#endif + +/* + * A pseudo representation for the function tracer: + * (*ftrace_trace_function)(ra_to_caller, ra_to_caller_of_caller) + */ +do_trace: + ld a1, -8(s0) + mv a0, ra + + SAVE_ABI_STATE + jalr t5 + STORE_ABI_STATE + ret +ENDPROC(_mcount) +EXPORT_SYMBOL(_mcount) diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c index cb7b0c63014e..09f7064e898c 100644 --- a/arch/riscv/kernel/setup.c +++ b/arch/riscv/kernel/setup.c @@ -49,10 +49,6 @@ struct screen_info screen_info = { }; #endif -#ifdef CONFIG_CMDLINE_BOOL -static char __initdata builtin_cmdline[COMMAND_LINE_SIZE] = CONFIG_CMDLINE; -#endif /* CONFIG_CMDLINE_BOOL */ - unsigned long va_pa_offset; EXPORT_SYMBOL(va_pa_offset); unsigned long pfn_base; @@ -153,25 +149,6 @@ void __init sbi_save(unsigned int hartid, void *dtb) early_init_dt_scan(__va(dtb)); } -/* - * Allow the user to manually add a memory region (in case DTS is broken); - * "mem_end=nn[KkMmGg]" - */ -static int __init mem_end_override(char *p) -{ - resource_size_t base, end; - - if (!p) - return -EINVAL; - base = (uintptr_t) __pa(PAGE_OFFSET); - end = memparse(p, &p) & PMD_MASK; - if (end == 0) - return -EINVAL; - memblock_add(base, end - base); - return 0; -} -early_param("mem_end", mem_end_override); - static void __init setup_bootmem(void) { struct memblock_region *reg; @@ -204,22 +181,19 @@ static void __init setup_bootmem(void) early_init_fdt_scan_reserved_mem(); memblock_allow_resize(); memblock_dump_all(); + + for_each_memblock(memory, reg) { + unsigned long start_pfn = memblock_region_memory_base_pfn(reg); + unsigned long end_pfn = memblock_region_memory_end_pfn(reg); + + memblock_set_node(PFN_PHYS(start_pfn), + PFN_PHYS(end_pfn - start_pfn), + &memblock.memory, 0); + } } void __init setup_arch(char **cmdline_p) { -#ifdef CONFIG_CMDLINE_BOOL -#ifdef CONFIG_CMDLINE_OVERRIDE - strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE); -#else - if (builtin_cmdline[0] != '\0') { - /* Append bootloader command line to built-in */ - strlcat(builtin_cmdline, " ", COMMAND_LINE_SIZE); - strlcat(builtin_cmdline, boot_command_line, COMMAND_LINE_SIZE); - strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE); - } -#endif /* CONFIG_CMDLINE_OVERRIDE */ -#endif /* CONFIG_CMDLINE_BOOL */ *cmdline_p = boot_command_line; parse_early_param(); diff --git a/arch/riscv/kernel/vdso.c b/arch/riscv/kernel/vdso.c index e8a178df8144..582cb153eb24 100644 --- a/arch/riscv/kernel/vdso.c +++ b/arch/riscv/kernel/vdso.c @@ -74,7 +74,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, down_write(&mm->mmap_sem); vdso_base = get_unmapped_area(NULL, 0, vdso_len, 0, 0); - if (unlikely(IS_ERR_VALUE(vdso_base))) { + if (IS_ERR_VALUE(vdso_base)) { ret = vdso_base; goto end; } diff --git a/arch/riscv/mm/fault.c b/arch/riscv/mm/fault.c index ceebfc29305b..148c98ca9b45 100644 --- a/arch/riscv/mm/fault.c +++ b/arch/riscv/mm/fault.c @@ -238,6 +238,10 @@ vmalloc_fault: * Do _not_ use "tsk->active_mm->pgd" here. * We might be inside an interrupt in the middle * of a task switch. + * + * Note: Use the old spbtr name instead of using the current + * satp name to support binutils 2.29 which doesn't know about + * the privileged ISA 1.10 yet. */ index = pgd_index(addr); pgd = (pgd_t *)pfn_to_virt(csr_read(sptbr)) + index; diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c index 9f4bee5e51fd..c77df8142be2 100644 --- a/arch/riscv/mm/init.c +++ b/arch/riscv/mm/init.c @@ -17,6 +17,7 @@ #include <linux/initrd.h> #include <linux/memblock.h> #include <linux/swap.h> +#include <linux/sizes.h> #include <asm/tlbflush.h> #include <asm/sections.h> @@ -25,11 +26,12 @@ static void __init zone_sizes_init(void) { - unsigned long zones_size[MAX_NR_ZONES]; + unsigned long max_zone_pfns[MAX_NR_ZONES] = { 0, }; - memset(zones_size, 0, sizeof(zones_size)); - zones_size[ZONE_NORMAL] = max_mapnr; - free_area_init_node(0, zones_size, pfn_base, NULL); + max_zone_pfns[ZONE_DMA32] = PFN_DOWN(min(4UL * SZ_1G, max_low_pfn)); + max_zone_pfns[ZONE_NORMAL] = max_low_pfn; + + free_area_init_nodes(max_zone_pfns); } void setup_zero_page(void) @@ -39,8 +41,6 @@ void setup_zero_page(void) void __init paging_init(void) { - init_mm.pgd = (pgd_t *)pfn_to_virt(csr_read(sptbr)); - setup_zero_page(); local_flush_tlb_all(); zone_sizes_init(); diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c index 671535e64aba..3fa3e5323612 100644 --- a/arch/s390/mm/init.c +++ b/arch/s390/mm/init.c @@ -222,7 +222,8 @@ device_initcall(s390_cma_mem_init); #endif /* CONFIG_CMA */ -int arch_add_memory(int nid, u64 start, u64 size, bool want_memblock) +int arch_add_memory(int nid, u64 start, u64 size, struct vmem_altmap *altmap, + bool want_memblock) { unsigned long start_pfn = PFN_DOWN(start); unsigned long size_pages = PFN_DOWN(size); @@ -232,14 +233,14 @@ int arch_add_memory(int nid, u64 start, u64 size, bool want_memblock) if (rc) return rc; - rc = __add_pages(nid, start_pfn, size_pages, want_memblock); + rc = __add_pages(nid, start_pfn, size_pages, altmap, want_memblock); if (rc) vmem_remove_mapping(start, size); return rc; } #ifdef CONFIG_MEMORY_HOTREMOVE -int arch_remove_memory(u64 start, u64 size) +int arch_remove_memory(u64 start, u64 size, struct vmem_altmap *altmap) { /* * There is no hardware or firmware interface which could trigger a diff --git a/arch/s390/mm/vmem.c b/arch/s390/mm/vmem.c index 3316d463fc29..db55561c5981 100644 --- a/arch/s390/mm/vmem.c +++ b/arch/s390/mm/vmem.c @@ -211,7 +211,8 @@ static void vmem_remove_range(unsigned long start, unsigned long size) /* * Add a backed mem_map array to the virtual mem_map array. */ -int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node) +int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node, + struct vmem_altmap *altmap) { unsigned long pgt_prot, sgt_prot; unsigned long address = start; @@ -296,7 +297,8 @@ out: return ret; } -void vmemmap_free(unsigned long start, unsigned long end) +void vmemmap_free(unsigned long start, unsigned long end, + struct vmem_altmap *altmap) { } diff --git a/arch/score/kernel/setup.c b/arch/score/kernel/setup.c index f3a0649ab521..627416bbd0b1 100644 --- a/arch/score/kernel/setup.c +++ b/arch/score/kernel/setup.c @@ -124,9 +124,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) { unsigned long n = (unsigned long) v - 1; - seq_printf(m, "processor\t\t: %ld\n", n); - seq_printf(m, "\n"); - + seq_printf(m, "processor\t\t: %ld\n\n", n); return 0; } diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c index bf726af5f1a5..ce0bbaa7e404 100644 --- a/arch/sh/mm/init.c +++ b/arch/sh/mm/init.c @@ -485,20 +485,20 @@ void free_initrd_mem(unsigned long start, unsigned long end) #endif #ifdef CONFIG_MEMORY_HOTPLUG -int arch_add_memory(int nid, u64 start, u64 size, bool want_memblock) +int arch_add_memory(int nid, u64 start, u64 size, struct vmem_altmap *altmap, + bool want_memblock) { unsigned long start_pfn = PFN_DOWN(start); unsigned long nr_pages = size >> PAGE_SHIFT; int ret; /* We only have ZONE_NORMAL, so this is easy.. */ - ret = __add_pages(nid, start_pfn, nr_pages, want_memblock); + ret = __add_pages(nid, start_pfn, nr_pages, altmap, want_memblock); if (unlikely(ret)) printk("%s: Failed, __add_pages() == %d\n", __func__, ret); return ret; } -EXPORT_SYMBOL_GPL(arch_add_memory); #ifdef CONFIG_NUMA int memory_add_physaddr_to_nid(u64 addr) @@ -510,7 +510,7 @@ EXPORT_SYMBOL_GPL(memory_add_physaddr_to_nid); #endif #ifdef CONFIG_MEMORY_HOTREMOVE -int arch_remove_memory(u64 start, u64 size) +int arch_remove_memory(u64 start, u64 size, struct vmem_altmap *altmap) { unsigned long start_pfn = PFN_DOWN(start); unsigned long nr_pages = size >> PAGE_SHIFT; @@ -518,7 +518,7 @@ int arch_remove_memory(u64 start, u64 size) int ret; zone = page_zone(pfn_to_page(start_pfn)); - ret = __remove_pages(zone, start_pfn, nr_pages); + ret = __remove_pages(zone, start_pfn, nr_pages, altmap); if (unlikely(ret)) pr_warn("%s: Failed, __remove_pages() == %d\n", __func__, ret); diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c index 55ba62957e64..995f9490334d 100644 --- a/arch/sparc/mm/init_64.c +++ b/arch/sparc/mm/init_64.c @@ -2628,7 +2628,7 @@ EXPORT_SYMBOL(_PAGE_CACHE); #ifdef CONFIG_SPARSEMEM_VMEMMAP int __meminit vmemmap_populate(unsigned long vstart, unsigned long vend, - int node) + int node, struct vmem_altmap *altmap) { unsigned long pte_base; @@ -2671,7 +2671,8 @@ int __meminit vmemmap_populate(unsigned long vstart, unsigned long vend, return 0; } -void vmemmap_free(unsigned long start, unsigned long end) +void vmemmap_free(unsigned long start, unsigned long end, + struct vmem_altmap *altmap) { } #endif /* CONFIG_SPARSEMEM_VMEMMAP */ diff --git a/arch/unicore32/include/asm/bitops.h b/arch/unicore32/include/asm/bitops.h index 401f597bc38c..c0cbdbe17168 100644 --- a/arch/unicore32/include/asm/bitops.h +++ b/arch/unicore32/include/asm/bitops.h @@ -44,4 +44,6 @@ static inline int fls(int x) #define find_first_bit find_first_bit #define find_first_zero_bit find_first_zero_bit +#include <asm-generic/bitops/find.h> + #endif /* __UNICORE_BITOPS_H__ */ diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index b0771ceabb4b..63bf349b2b24 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -55,6 +55,7 @@ config X86 select ARCH_HAS_GCOV_PROFILE_ALL select ARCH_HAS_KCOV if X86_64 select ARCH_HAS_PHYS_TO_DMA + select ARCH_HAS_MEMBARRIER_SYNC_CORE select ARCH_HAS_PMEM_API if X86_64 select ARCH_HAS_REFCOUNT select ARCH_HAS_UACCESS_FLUSHCACHE if X86_64 @@ -62,6 +63,7 @@ config X86 select ARCH_HAS_SG_CHAIN select ARCH_HAS_STRICT_KERNEL_RWX select ARCH_HAS_STRICT_MODULE_RWX + select ARCH_HAS_SYNC_CORE_BEFORE_USERMODE select ARCH_HAS_UBSAN_SANITIZE_ALL select ARCH_HAS_ZONE_DEVICE if X86_64 select ARCH_HAVE_NMI_SAFE_CMPXCHG @@ -322,7 +324,7 @@ config X86_64_SMP config X86_32_LAZY_GS def_bool y - depends on X86_32 && !CC_STACKPROTECTOR + depends on X86_32 && CC_STACKPROTECTOR_NONE config ARCH_SUPPORTS_UPROBES def_bool y diff --git a/arch/x86/entry/entry_32.S b/arch/x86/entry/entry_32.S index 2a35b1e0fb90..abee6d2b9311 100644 --- a/arch/x86/entry/entry_32.S +++ b/arch/x86/entry/entry_32.S @@ -566,6 +566,11 @@ restore_all: .Lrestore_nocheck: RESTORE_REGS 4 # skip orig_eax/error_code .Lirq_return: + /* + * ARCH_HAS_MEMBARRIER_SYNC_CORE rely on IRET core serialization + * when returning from IPI handler and when returning from + * scheduler to user-space. + */ INTERRUPT_RETURN .section .fixup, "ax" diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S index c752abe89d80..4a9bef6aca34 100644 --- a/arch/x86/entry/entry_64.S +++ b/arch/x86/entry/entry_64.S @@ -691,6 +691,10 @@ GLOBAL(restore_regs_and_return_to_kernel) POP_EXTRA_REGS POP_C_REGS addq $8, %rsp /* skip regs->orig_ax */ + /* + * ARCH_HAS_MEMBARRIER_SYNC_CORE rely on IRET core serialization + * when returning from IPI handler. + */ INTERRUPT_RETURN ENTRY(native_iret) diff --git a/arch/x86/events/perf_event.h b/arch/x86/events/perf_event.h index 8e4ea143ed96..78f91ec1056e 100644 --- a/arch/x86/events/perf_event.h +++ b/arch/x86/events/perf_event.h @@ -93,7 +93,8 @@ struct amd_nb { PERF_SAMPLE_ID | PERF_SAMPLE_CPU | PERF_SAMPLE_STREAM_ID | \ PERF_SAMPLE_DATA_SRC | PERF_SAMPLE_IDENTIFIER | \ PERF_SAMPLE_TRANSACTION | PERF_SAMPLE_PHYS_ADDR | \ - PERF_SAMPLE_REGS_INTR | PERF_SAMPLE_REGS_USER) + PERF_SAMPLE_REGS_INTR | PERF_SAMPLE_REGS_USER | \ + PERF_SAMPLE_PERIOD) #define PEBS_REGS \ (PERF_REG_X86_AX | \ diff --git a/arch/x86/include/asm/intel-family.h b/arch/x86/include/asm/intel-family.h index 35a6bc4da8ad..cf090e584202 100644 --- a/arch/x86/include/asm/intel-family.h +++ b/arch/x86/include/asm/intel-family.h @@ -10,6 +10,10 @@ * * Things ending in "2" are usually because we have no better * name for them. There's no processor called "SILVERMONT2". + * + * While adding a new CPUID for a new microarchitecture, add a new + * group to keep logically sorted out in chronological order. Within + * that group keep the CPUID for the variants sorted by model number. */ #define INTEL_FAM6_CORE_YONAH 0x0E @@ -49,6 +53,8 @@ #define INTEL_FAM6_KABYLAKE_MOBILE 0x8E #define INTEL_FAM6_KABYLAKE_DESKTOP 0x9E +#define INTEL_FAM6_CANNONLAKE_MOBILE 0x66 + /* "Small Core" Processors (Atom) */ #define INTEL_FAM6_ATOM_PINEVIEW 0x1C diff --git a/arch/x86/include/asm/intel_pmc_ipc.h b/arch/x86/include/asm/intel_pmc_ipc.h index 528ed4be4393..9e7adcdbe031 100644 --- a/arch/x86/include/asm/intel_pmc_ipc.h +++ b/arch/x86/include/asm/intel_pmc_ipc.h @@ -38,6 +38,7 @@ int intel_pmc_ipc_command(u32 cmd, u32 sub, u8 *in, u32 inlen, u32 *out, u32 outlen); int intel_pmc_s0ix_counter_read(u64 *data); int intel_pmc_gcr_read(u32 offset, u32 *data); +int intel_pmc_gcr_read64(u32 offset, u64 *data); int intel_pmc_gcr_write(u32 offset, u32 data); int intel_pmc_gcr_update(u32 offset, u32 mask, u32 val); @@ -70,6 +71,11 @@ static inline int intel_pmc_gcr_read(u32 offset, u32 *data) return -EINVAL; } +static inline int intel_pmc_gcr_read64(u32 offset, u64 *data) +{ + return -EINVAL; +} + static inline int intel_pmc_gcr_write(u32 offset, u32 data) { return -EINVAL; diff --git a/arch/x86/include/asm/kasan.h b/arch/x86/include/asm/kasan.h index b577dd0916aa..13e70da38bed 100644 --- a/arch/x86/include/asm/kasan.h +++ b/arch/x86/include/asm/kasan.h @@ -4,6 +4,7 @@ #include <linux/const.h> #define KASAN_SHADOW_OFFSET _AC(CONFIG_KASAN_SHADOW_OFFSET, UL) +#define KASAN_SHADOW_SCALE_SHIFT 3 /* * Compiler uses shadow offset assuming that addresses start @@ -12,12 +13,15 @@ * 'kernel address space start' >> KASAN_SHADOW_SCALE_SHIFT */ #define KASAN_SHADOW_START (KASAN_SHADOW_OFFSET + \ - ((-1UL << __VIRTUAL_MASK_SHIFT) >> 3)) + ((-1UL << __VIRTUAL_MASK_SHIFT) >> \ + KASAN_SHADOW_SCALE_SHIFT)) /* - * 47 bits for kernel address -> (47 - 3) bits for shadow - * 56 bits for kernel address -> (56 - 3) bits for shadow + * 47 bits for kernel address -> (47 - KASAN_SHADOW_SCALE_SHIFT) bits for shadow + * 56 bits for kernel address -> (56 - KASAN_SHADOW_SCALE_SHIFT) bits for shadow */ -#define KASAN_SHADOW_END (KASAN_SHADOW_START + (1ULL << (__VIRTUAL_MASK_SHIFT - 3))) +#define KASAN_SHADOW_END (KASAN_SHADOW_START + \ + (1ULL << (__VIRTUAL_MASK_SHIFT - \ + KASAN_SHADOW_SCALE_SHIFT))) #ifndef __ASSEMBLY__ diff --git a/arch/x86/include/asm/pmc_core.h b/arch/x86/include/asm/pmc_core.h deleted file mode 100644 index d4855f11136d..000000000000 --- a/arch/x86/include/asm/pmc_core.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Intel Core SoC Power Management Controller Header File - * - * Copyright (c) 2016, Intel Corporation. - * All Rights Reserved. - * - * Authors: Rajneesh Bhardwaj <rajneesh.bhardwaj@intel.com> - * Vishwanath Somayaji <vishwanath.somayaji@intel.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope 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. - * - */ - -#ifndef _ASM_PMC_CORE_H -#define _ASM_PMC_CORE_H - -/* API to read SLP_S0_RESIDENCY counter */ -int intel_pmc_slp_s0_counter_read(u32 *data); - -#endif /* _ASM_PMC_CORE_H */ diff --git a/arch/x86/include/asm/sync_core.h b/arch/x86/include/asm/sync_core.h new file mode 100644 index 000000000000..c67caafd3381 --- /dev/null +++ b/arch/x86/include/asm/sync_core.h @@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _ASM_X86_SYNC_CORE_H +#define _ASM_X86_SYNC_CORE_H + +#include <linux/preempt.h> +#include <asm/processor.h> +#include <asm/cpufeature.h> + +/* + * Ensure that a core serializing instruction is issued before returning + * to user-mode. x86 implements return to user-space through sysexit, + * sysrel, and sysretq, which are not core serializing. + */ +static inline void sync_core_before_usermode(void) +{ + /* With PTI, we unconditionally serialize before running user code. */ + if (static_cpu_has(X86_FEATURE_PTI)) + return; + /* + * Return from interrupt and NMI is done through iret, which is core + * serializing. + */ + if (in_irq() || in_nmi()) + return; + sync_core(); +} + +#endif /* _ASM_X86_SYNC_CORE_H */ diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c index 135c9a7898c7..79cb066f40c0 100644 --- a/arch/x86/mm/init_32.c +++ b/arch/x86/mm/init_32.c @@ -829,23 +829,24 @@ void __init mem_init(void) } #ifdef CONFIG_MEMORY_HOTPLUG -int arch_add_memory(int nid, u64 start, u64 size, bool want_memblock) +int arch_add_memory(int nid, u64 start, u64 size, struct vmem_altmap *altmap, + bool want_memblock) { unsigned long start_pfn = start >> PAGE_SHIFT; unsigned long nr_pages = size >> PAGE_SHIFT; - return __add_pages(nid, start_pfn, nr_pages, want_memblock); + return __add_pages(nid, start_pfn, nr_pages, altmap, want_memblock); } #ifdef CONFIG_MEMORY_HOTREMOVE -int arch_remove_memory(u64 start, u64 size) +int arch_remove_memory(u64 start, u64 size, struct vmem_altmap *altmap) { unsigned long start_pfn = start >> PAGE_SHIFT; unsigned long nr_pages = size >> PAGE_SHIFT; struct zone *zone; zone = page_zone(pfn_to_page(start_pfn)); - return __remove_pages(zone, start_pfn, nr_pages); + return __remove_pages(zone, start_pfn, nr_pages, altmap); } #endif #endif diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c index 4a837289f2ad..1ab42c852069 100644 --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c @@ -772,12 +772,12 @@ static void update_end_of_memory_vars(u64 start, u64 size) } } -int add_pages(int nid, unsigned long start_pfn, - unsigned long nr_pages, bool want_memblock) +int add_pages(int nid, unsigned long start_pfn, unsigned long nr_pages, + struct vmem_altmap *altmap, bool want_memblock) { int ret; - ret = __add_pages(nid, start_pfn, nr_pages, want_memblock); + ret = __add_pages(nid, start_pfn, nr_pages, altmap, want_memblock); WARN_ON_ONCE(ret); /* update max_pfn, max_low_pfn and high_memory */ @@ -787,24 +787,24 @@ int add_pages(int nid, unsigned long start_pfn, return ret; } -int arch_add_memory(int nid, u64 start, u64 size, bool want_memblock) +int arch_add_memory(int nid, u64 start, u64 size, struct vmem_altmap *altmap, + bool want_memblock) { unsigned long start_pfn = start >> PAGE_SHIFT; unsigned long nr_pages = size >> PAGE_SHIFT; init_memory_mapping(start, start + size); - return add_pages(nid, start_pfn, nr_pages, want_memblock); + return add_pages(nid, start_pfn, nr_pages, altmap, want_memblock); } -EXPORT_SYMBOL_GPL(arch_add_memory); #define PAGE_INUSE 0xFD -static void __meminit free_pagetable(struct page *page, int order) +static void __meminit free_pagetable(struct page *page, int order, + struct vmem_altmap *altmap) { unsigned long magic; unsigned int nr_pages = 1 << order; - struct vmem_altmap *altmap = to_vmem_altmap((unsigned long) page); if (altmap) { vmem_altmap_free(altmap, nr_pages); @@ -826,7 +826,8 @@ static void __meminit free_pagetable(struct page *page, int order) free_pages((unsigned long)page_address(page), order); } -static void __meminit free_pte_table(pte_t *pte_start, pmd_t *pmd) +static void __meminit free_pte_table(pte_t *pte_start, pmd_t *pmd, + struct vmem_altmap *altmap) { pte_t *pte; int i; @@ -838,13 +839,14 @@ static void __meminit free_pte_table(pte_t *pte_start, pmd_t *pmd) } /* free a pte talbe */ - free_pagetable(pmd_page(*pmd), 0); + free_pagetable(pmd_page(*pmd), 0, altmap); spin_lock(&init_mm.page_table_lock); pmd_clear(pmd); spin_unlock(&init_mm.page_table_lock); } -static void __meminit free_pmd_table(pmd_t *pmd_start, pud_t *pud) +static void __meminit free_pmd_table(pmd_t *pmd_start, pud_t *pud, + struct vmem_altmap *altmap) { pmd_t *pmd; int i; @@ -856,13 +858,14 @@ static void __meminit free_pmd_table(pmd_t *pmd_start, pud_t *pud) } /* free a pmd talbe */ - free_pagetable(pud_page(*pud), 0); + free_pagetable(pud_page(*pud), 0, altmap); spin_lock(&init_mm.page_table_lock); pud_clear(pud); spin_unlock(&init_mm.page_table_lock); } -static void __meminit free_pud_table(pud_t *pud_start, p4d_t *p4d) +static void __meminit free_pud_table(pud_t *pud_start, p4d_t *p4d, + struct vmem_altmap *altmap) { pud_t *pud; int i; @@ -874,7 +877,7 @@ static void __meminit free_pud_table(pud_t *pud_start, p4d_t *p4d) } /* free a pud talbe */ - free_pagetable(p4d_page(*p4d), 0); + free_pagetable(p4d_page(*p4d), 0, altmap); spin_lock(&init_mm.page_table_lock); p4d_clear(p4d); spin_unlock(&init_mm.page_table_lock); @@ -882,7 +885,7 @@ static void __meminit free_pud_table(pud_t *pud_start, p4d_t *p4d) static void __meminit remove_pte_table(pte_t *pte_start, unsigned long addr, unsigned long end, - bool direct) + struct vmem_altmap *altmap, bool direct) { unsigned long next, pages = 0; pte_t *pte; @@ -913,7 +916,7 @@ remove_pte_table(pte_t *pte_start, unsigned long addr, unsigned long end, * freed when offlining, or simplely not in use. */ if (!direct) - free_pagetable(pte_page(*pte), 0); + free_pagetable(pte_page(*pte), 0, altmap); spin_lock(&init_mm.page_table_lock); pte_clear(&init_mm, addr, pte); @@ -936,7 +939,7 @@ remove_pte_table(pte_t *pte_start, unsigned long addr, unsigned long end, page_addr = page_address(pte_page(*pte)); if (!memchr_inv(page_addr, PAGE_INUSE, PAGE_SIZE)) { - free_pagetable(pte_page(*pte), 0); + free_pagetable(pte_page(*pte), 0, altmap); spin_lock(&init_mm.page_table_lock); pte_clear(&init_mm, addr, pte); @@ -953,7 +956,7 @@ remove_pte_table(pte_t *pte_start, unsigned long addr, unsigned long end, static void __meminit remove_pmd_table(pmd_t *pmd_start, unsigned long addr, unsigned long end, - bool direct) + bool direct, struct vmem_altmap *altmap) { unsigned long next, pages = 0; pte_t *pte_base; @@ -972,7 +975,8 @@ remove_pmd_table(pmd_t *pmd_start, unsigned long addr, unsigned long end, IS_ALIGNED(next, PMD_SIZE)) { if (!direct) free_pagetable(pmd_page(*pmd), - get_order(PMD_SIZE)); + get_order(PMD_SIZE), + altmap); spin_lock(&init_mm.page_table_lock); pmd_clear(pmd); @@ -986,7 +990,8 @@ remove_pmd_table(pmd_t *pmd_start, unsigned long addr, unsigned long end, if (!memchr_inv(page_addr, PAGE_INUSE, PMD_SIZE)) { free_pagetable(pmd_page(*pmd), - get_order(PMD_SIZE)); + get_order(PMD_SIZE), + altmap); spin_lock(&init_mm.page_table_lock); pmd_clear(pmd); @@ -998,8 +1003,8 @@ remove_pmd_table(pmd_t *pmd_start, unsigned long addr, unsigned long end, } pte_base = (pte_t *)pmd_page_vaddr(*pmd); - remove_pte_table(pte_base, addr, next, direct); - free_pte_table(pte_base, pmd); + remove_pte_table(pte_base, addr, next, altmap, direct); + free_pte_table(pte_base, pmd, altmap); } /* Call free_pmd_table() in remove_pud_table(). */ @@ -1009,7 +1014,7 @@ remove_pmd_table(pmd_t *pmd_start, unsigned long addr, unsigned long end, static void __meminit remove_pud_table(pud_t *pud_start, unsigned long addr, unsigned long end, - bool direct) + struct vmem_altmap *altmap, bool direct) { unsigned long next, pages = 0; pmd_t *pmd_base; @@ -1028,7 +1033,8 @@ remove_pud_table(pud_t *pud_start, unsigned long addr, unsigned long end, IS_ALIGNED(next, PUD_SIZE)) { if (!direct) free_pagetable(pud_page(*pud), - get_order(PUD_SIZE)); + get_order(PUD_SIZE), + altmap); spin_lock(&init_mm.page_table_lock); pud_clear(pud); @@ -1042,7 +1048,8 @@ remove_pud_table(pud_t *pud_start, unsigned long addr, unsigned long end, if (!memchr_inv(page_addr, PAGE_INUSE, PUD_SIZE)) { free_pagetable(pud_page(*pud), - get_order(PUD_SIZE)); + get_order(PUD_SIZE), + altmap); spin_lock(&init_mm.page_table_lock); pud_clear(pud); @@ -1054,8 +1061,8 @@ remove_pud_table(pud_t *pud_start, unsigned long addr, unsigned long end, } pmd_base = pmd_offset(pud, 0); - remove_pmd_table(pmd_base, addr, next, direct); - free_pmd_table(pmd_base, pud); + remove_pmd_table(pmd_base, addr, next, direct, altmap); + free_pmd_table(pmd_base, pud, altmap); } if (direct) @@ -1064,7 +1071,7 @@ remove_pud_table(pud_t *pud_start, unsigned long addr, unsigned long end, static void __meminit remove_p4d_table(p4d_t *p4d_start, unsigned long addr, unsigned long end, - bool direct) + struct vmem_altmap *altmap, bool direct) { unsigned long next, pages = 0; pud_t *pud_base; @@ -1080,14 +1087,14 @@ remove_p4d_table(p4d_t *p4d_start, unsigned long addr, unsigned long end, BUILD_BUG_ON(p4d_large(*p4d)); pud_base = pud_offset(p4d, 0); - remove_pud_table(pud_base, addr, next, direct); + remove_pud_table(pud_base, addr, next, altmap, direct); /* * For 4-level page tables we do not want to free PUDs, but in the * 5-level case we should free them. This code will have to change * to adapt for boot-time switching between 4 and 5 level page tables. */ if (CONFIG_PGTABLE_LEVELS == 5) - free_pud_table(pud_base, p4d); + free_pud_table(pud_base, p4d, altmap); } if (direct) @@ -1096,7 +1103,8 @@ remove_p4d_table(p4d_t *p4d_start, unsigned long addr, unsigned long end, /* start and end are both virtual address. */ static void __meminit -remove_pagetable(unsigned long start, unsigned long end, bool direct) +remove_pagetable(unsigned long start, unsigned long end, bool direct, + struct vmem_altmap *altmap) { unsigned long next; unsigned long addr; @@ -1111,15 +1119,16 @@ remove_pagetable(unsigned long start, unsigned long end, bool direct) continue; p4d = p4d_offset(pgd, 0); - remove_p4d_table(p4d, addr, next, direct); + remove_p4d_table(p4d, addr, next, altmap, direct); } flush_tlb_all(); } -void __ref vmemmap_free(unsigned long start, unsigned long end) +void __ref vmemmap_free(unsigned long start, unsigned long end, + struct vmem_altmap *altmap) { - remove_pagetable(start, end, false); + remove_pagetable(start, end, false, altmap); } #ifdef CONFIG_MEMORY_HOTREMOVE @@ -1129,24 +1138,22 @@ kernel_physical_mapping_remove(unsigned long start, unsigned long end) start = (unsigned long)__va(start); end = (unsigned long)__va(end); - remove_pagetable(start, end, true); + remove_pagetable(start, end, true, NULL); } -int __ref arch_remove_memory(u64 start, u64 size) +int __ref arch_remove_memory(u64 start, u64 size, struct vmem_altmap *altmap) { unsigned long start_pfn = start >> PAGE_SHIFT; unsigned long nr_pages = size >> PAGE_SHIFT; struct page *page = pfn_to_page(start_pfn); - struct vmem_altmap *altmap; struct zone *zone; int ret; /* With altmap the first mapped page is offset from @start */ - altmap = to_vmem_altmap((unsigned long) page); if (altmap) page += vmem_altmap_offset(altmap); zone = page_zone(page); - ret = __remove_pages(zone, start_pfn, nr_pages); + ret = __remove_pages(zone, start_pfn, nr_pages, altmap); WARN_ON_ONCE(ret); kernel_physical_mapping_remove(start, start + size); @@ -1378,7 +1385,10 @@ static int __meminit vmemmap_populate_hugepages(unsigned long start, if (pmd_none(*pmd)) { void *p; - p = __vmemmap_alloc_block_buf(PMD_SIZE, node, altmap); + if (altmap) + p = altmap_alloc_block_buf(PMD_SIZE, altmap); + else + p = vmemmap_alloc_block_buf(PMD_SIZE, node); if (p) { pte_t entry; @@ -1411,9 +1421,9 @@ static int __meminit vmemmap_populate_hugepages(unsigned long start, return 0; } -int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node) +int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node, + struct vmem_altmap *altmap) { - struct vmem_altmap *altmap = to_vmem_altmap(start); int err; if (boot_cpu_has(X86_FEATURE_PSE)) diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c index 012d02624848..8dcc0607f805 100644 --- a/arch/x86/mm/tlb.c +++ b/arch/x86/mm/tlb.c @@ -229,6 +229,12 @@ void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next, #endif this_cpu_write(cpu_tlbstate.is_lazy, false); + /* + * The membarrier system call requires a full memory barrier and + * core serialization before returning to user-space, after + * storing to rq->curr. Writing to CR3 provides that full + * memory barrier and core serializing instruction. + */ if (real_prev == next) { VM_WARN_ON(this_cpu_read(cpu_tlbstate.ctxs[prev_asid].ctx_id) != next->context.ctx_id); diff --git a/arch/x86/pci/irq.c b/arch/x86/pci/irq.c index 0452629148be..52e55108404e 100644 --- a/arch/x86/pci/irq.c +++ b/arch/x86/pci/irq.c @@ -839,7 +839,8 @@ static void __init pirq_find_router(struct irq_router *r) DBG(KERN_DEBUG "PCI: Attempting to find IRQ router for [%04x:%04x]\n", rt->rtr_vendor, rt->rtr_device); - pirq_router_dev = pci_get_bus_and_slot(rt->rtr_bus, rt->rtr_devfn); + pirq_router_dev = pci_get_domain_bus_and_slot(0, rt->rtr_bus, + rt->rtr_devfn); if (!pirq_router_dev) { DBG(KERN_DEBUG "PCI: Interrupt router not found at " "%02x:%02x\n", rt->rtr_bus, rt->rtr_devfn); diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c index c4b3646bd04c..9542a746dc50 100644 --- a/arch/x86/pci/xen.c +++ b/arch/x86/pci/xen.c @@ -409,10 +409,8 @@ int __init pci_xen_init(void) pcibios_enable_irq = xen_pcifront_enable_irq; pcibios_disable_irq = NULL; -#ifdef CONFIG_ACPI /* Keep ACPI out of the picture */ - acpi_noirq = 1; -#endif + acpi_noirq_set(); #ifdef CONFIG_PCI_MSI x86_msi.setup_msi_irqs = xen_setup_msi_irqs; |