2020-03-24 16:18:13

by Christoph Hellwig

[permalink] [raw]
Subject: MIPS ioremap cleanups

Hi Thomas,

below is a bunch of cleanups for the MIPS ioremap code. Compile tested
only.


2020-03-24 16:20:33

by Christoph Hellwig

[permalink] [raw]
Subject: [PATCH 1/6] MIPS: remove cpu_has_64bit_gp_regs and cpu_has_64bit_addresses

Both macros are always identical to CONFIG_64BIT.

Signed-off-by: Christoph Hellwig <[email protected]>
---
arch/mips/include/asm/cpu-features.h | 12 ------------
arch/mips/include/asm/io.h | 4 ++--
.../include/asm/mach-ath25/cpu-feature-overrides.h | 2 --
.../include/asm/mach-ath79/cpu-feature-overrides.h | 2 --
.../asm/mach-lantiq/falcon/cpu-feature-overrides.h | 2 --
.../asm/mach-ralink/mt7620/cpu-feature-overrides.h | 2 --
.../asm/mach-ralink/mt7621/cpu-feature-overrides.h | 2 --
.../asm/mach-ralink/rt288x/cpu-feature-overrides.h | 2 --
.../asm/mach-ralink/rt305x/cpu-feature-overrides.h | 2 --
.../asm/mach-ralink/rt3883/cpu-feature-overrides.h | 2 --
.../include/asm/mach-rc32434/cpu-feature-overrides.h | 2 --
arch/mips/mm/page.c | 12 ++++++------
12 files changed, 8 insertions(+), 38 deletions(-)

diff --git a/arch/mips/include/asm/cpu-features.h b/arch/mips/include/asm/cpu-features.h
index de44c92b1c1f..2798ea0d5fff 100644
--- a/arch/mips/include/asm/cpu-features.h
+++ b/arch/mips/include/asm/cpu-features.h
@@ -432,12 +432,6 @@
# ifndef cpu_has_64bit_zero_reg
# define cpu_has_64bit_zero_reg (cpu_data[0].isa_level & MIPS_CPU_ISA_64BIT)
# endif
-# ifndef cpu_has_64bit_gp_regs
-# define cpu_has_64bit_gp_regs 0
-# endif
-# ifndef cpu_has_64bit_addresses
-# define cpu_has_64bit_addresses 0
-# endif
# ifndef cpu_vmbits
# define cpu_vmbits 31
# endif
@@ -453,12 +447,6 @@
# ifndef cpu_has_64bit_zero_reg
# define cpu_has_64bit_zero_reg 1
# endif
-# ifndef cpu_has_64bit_gp_regs
-# define cpu_has_64bit_gp_regs 1
-# endif
-# ifndef cpu_has_64bit_addresses
-# define cpu_has_64bit_addresses 1
-# endif
# ifndef cpu_vmbits
# define cpu_vmbits cpu_data[0].vmbits
# define __NEED_VMBITS_PROBE
diff --git a/arch/mips/include/asm/io.h b/arch/mips/include/asm/io.h
index cf1f2a4a2418..7be323ed2bfd 100644
--- a/arch/mips/include/asm/io.h
+++ b/arch/mips/include/asm/io.h
@@ -166,7 +166,7 @@ static inline void __iomem * __ioremap_mode(phys_addr_t offset, unsigned long si

#define __IS_LOW512(addr) (!((phys_addr_t)(addr) & (phys_addr_t) ~0x1fffffffULL))

- if (cpu_has_64bit_addresses) {
+ if (IS_ENABLED(CONFIG_64BIT)) {
u64 base = UNCAC_BASE;

/*
@@ -275,7 +275,7 @@ static inline void iounmap(const volatile void __iomem *addr)

#define __IS_KSEG1(addr) (((unsigned long)(addr) & ~0x1fffffffUL) == CKSEG1)

- if (cpu_has_64bit_addresses ||
+ if (IS_ENABLED(CONFIG_64BIT) ||
(__builtin_constant_p(addr) && __IS_KSEG1(addr)))
return;

diff --git a/arch/mips/include/asm/mach-ath25/cpu-feature-overrides.h b/arch/mips/include/asm/mach-ath25/cpu-feature-overrides.h
index 95a0b580909d..91f638ee68e0 100644
--- a/arch/mips/include/asm/mach-ath25/cpu-feature-overrides.h
+++ b/arch/mips/include/asm/mach-ath25/cpu-feature-overrides.h
@@ -55,7 +55,5 @@

#define cpu_has_64bits 0
#define cpu_has_64bit_zero_reg 0
-#define cpu_has_64bit_gp_regs 0
-#define cpu_has_64bit_addresses 0

#endif /* __ASM_MACH_ATH25_CPU_FEATURE_OVERRIDES_H */
diff --git a/arch/mips/include/asm/mach-ath79/cpu-feature-overrides.h b/arch/mips/include/asm/mach-ath79/cpu-feature-overrides.h
index e7c972fccd9f..bc52a75d77a8 100644
--- a/arch/mips/include/asm/mach-ath79/cpu-feature-overrides.h
+++ b/arch/mips/include/asm/mach-ath79/cpu-feature-overrides.h
@@ -44,8 +44,6 @@

#define cpu_has_64bits 0
#define cpu_has_64bit_zero_reg 0
-#define cpu_has_64bit_gp_regs 0
-#define cpu_has_64bit_addresses 0

#define cpu_dcache_line_size() 32
#define cpu_icache_line_size() 32
diff --git a/arch/mips/include/asm/mach-lantiq/falcon/cpu-feature-overrides.h b/arch/mips/include/asm/mach-lantiq/falcon/cpu-feature-overrides.h
index f03c1c42dd90..0fdec83af64b 100644
--- a/arch/mips/include/asm/mach-lantiq/falcon/cpu-feature-overrides.h
+++ b/arch/mips/include/asm/mach-lantiq/falcon/cpu-feature-overrides.h
@@ -45,8 +45,6 @@

#define cpu_has_64bits 0
#define cpu_has_64bit_zero_reg 0
-#define cpu_has_64bit_gp_regs 0
-#define cpu_has_64bit_addresses 0

#define cpu_dcache_line_size() 32
#define cpu_icache_line_size() 32
diff --git a/arch/mips/include/asm/mach-ralink/mt7620/cpu-feature-overrides.h b/arch/mips/include/asm/mach-ralink/mt7620/cpu-feature-overrides.h
index 6ea5908f0c11..945e0fd4a884 100644
--- a/arch/mips/include/asm/mach-ralink/mt7620/cpu-feature-overrides.h
+++ b/arch/mips/include/asm/mach-ralink/mt7620/cpu-feature-overrides.h
@@ -44,8 +44,6 @@

#define cpu_has_64bits 0
#define cpu_has_64bit_zero_reg 0
-#define cpu_has_64bit_gp_regs 0
-#define cpu_has_64bit_addresses 0

#define cpu_dcache_line_size() 32
#define cpu_icache_line_size() 32
diff --git a/arch/mips/include/asm/mach-ralink/mt7621/cpu-feature-overrides.h b/arch/mips/include/asm/mach-ralink/mt7621/cpu-feature-overrides.h
index e06f517b2588..21f73ef8f695 100644
--- a/arch/mips/include/asm/mach-ralink/mt7621/cpu-feature-overrides.h
+++ b/arch/mips/include/asm/mach-ralink/mt7621/cpu-feature-overrides.h
@@ -45,8 +45,6 @@

#define cpu_has_64bits 0
#define cpu_has_64bit_zero_reg 0
-#define cpu_has_64bit_gp_regs 0
-#define cpu_has_64bit_addresses 0

#define cpu_dcache_line_size() 32
#define cpu_icache_line_size() 32
diff --git a/arch/mips/include/asm/mach-ralink/rt288x/cpu-feature-overrides.h b/arch/mips/include/asm/mach-ralink/rt288x/cpu-feature-overrides.h
index 9c069646d0bd..c314c3cec130 100644
--- a/arch/mips/include/asm/mach-ralink/rt288x/cpu-feature-overrides.h
+++ b/arch/mips/include/asm/mach-ralink/rt288x/cpu-feature-overrides.h
@@ -43,8 +43,6 @@

#define cpu_has_64bits 0
#define cpu_has_64bit_zero_reg 0
-#define cpu_has_64bit_gp_regs 0
-#define cpu_has_64bit_addresses 0

#define cpu_dcache_line_size() 16
#define cpu_icache_line_size() 16
diff --git a/arch/mips/include/asm/mach-ralink/rt305x/cpu-feature-overrides.h b/arch/mips/include/asm/mach-ralink/rt305x/cpu-feature-overrides.h
index 2e423fd15384..9fb175dc9b78 100644
--- a/arch/mips/include/asm/mach-ralink/rt305x/cpu-feature-overrides.h
+++ b/arch/mips/include/asm/mach-ralink/rt305x/cpu-feature-overrides.h
@@ -43,8 +43,6 @@

#define cpu_has_64bits 0
#define cpu_has_64bit_zero_reg 0
-#define cpu_has_64bit_gp_regs 0
-#define cpu_has_64bit_addresses 0

#define cpu_dcache_line_size() 32
#define cpu_icache_line_size() 32
diff --git a/arch/mips/include/asm/mach-ralink/rt3883/cpu-feature-overrides.h b/arch/mips/include/asm/mach-ralink/rt3883/cpu-feature-overrides.h
index 7cee0e232580..57857566e5df 100644
--- a/arch/mips/include/asm/mach-ralink/rt3883/cpu-feature-overrides.h
+++ b/arch/mips/include/asm/mach-ralink/rt3883/cpu-feature-overrides.h
@@ -42,8 +42,6 @@

#define cpu_has_64bits 0
#define cpu_has_64bit_zero_reg 0
-#define cpu_has_64bit_gp_regs 0
-#define cpu_has_64bit_addresses 0

#define cpu_dcache_line_size() 32
#define cpu_icache_line_size() 32
diff --git a/arch/mips/include/asm/mach-rc32434/cpu-feature-overrides.h b/arch/mips/include/asm/mach-rc32434/cpu-feature-overrides.h
index bc46179fdf40..852f15c8853b 100644
--- a/arch/mips/include/asm/mach-rc32434/cpu-feature-overrides.h
+++ b/arch/mips/include/asm/mach-rc32434/cpu-feature-overrides.h
@@ -53,8 +53,6 @@
/* #define cpu_has_nofpuex ? */
#define cpu_has_64bits 0
#define cpu_has_64bit_zero_reg 0
-#define cpu_has_64bit_gp_regs 0
-#define cpu_has_64bit_addresses 0

#define cpu_has_inclusive_pcaches 0

diff --git a/arch/mips/mm/page.c b/arch/mips/mm/page.c
index c5578897a4fa..6bc6540dc9de 100644
--- a/arch/mips/mm/page.c
+++ b/arch/mips/mm/page.c
@@ -104,7 +104,7 @@ static int cache_line_size;
static inline void
pg_addiu(u32 **buf, unsigned int reg1, unsigned int reg2, unsigned int off)
{
- if (cpu_has_64bit_gp_regs && DADDI_WAR && r4k_daddiu_bug()) {
+ if (IS_ENABLED(CONFIG_64BIT) && DADDI_WAR && r4k_daddiu_bug()) {
if (off > 0x7fff) {
uasm_i_lui(buf, T9, uasm_rel_hi(off));
uasm_i_addiu(buf, T9, T9, uasm_rel_lo(off));
@@ -123,12 +123,12 @@ pg_addiu(u32 **buf, unsigned int reg1, unsigned int reg2, unsigned int off)

static void set_prefetch_parameters(void)
{
- if (cpu_has_64bit_gp_regs || cpu_has_64bit_zero_reg)
+ if (IS_ENABLED(CONFIG_64BIT) || cpu_has_64bit_zero_reg)
clear_word_size = 8;
else
clear_word_size = 4;

- if (cpu_has_64bit_gp_regs)
+ if (IS_ENABLED(CONFIG_64BIT))
copy_word_size = 8;
else
copy_word_size = 4;
@@ -232,7 +232,7 @@ static void set_prefetch_parameters(void)

static void build_clear_store(u32 **buf, int off)
{
- if (cpu_has_64bit_gp_regs || cpu_has_64bit_zero_reg) {
+ if (IS_ENABLED(CONFIG_64BIT) || cpu_has_64bit_zero_reg) {
uasm_i_sd(buf, ZERO, off, A0);
} else {
uasm_i_sw(buf, ZERO, off, A0);
@@ -366,7 +366,7 @@ void build_clear_page(void)

static void build_copy_load(u32 **buf, int reg, int off)
{
- if (cpu_has_64bit_gp_regs) {
+ if (IS_ENABLED(CONFIG_64BIT)) {
uasm_i_ld(buf, reg, off, A1);
} else {
uasm_i_lw(buf, reg, off, A1);
@@ -375,7 +375,7 @@ static void build_copy_load(u32 **buf, int reg, int off)

static void build_copy_store(u32 **buf, int reg, int off)
{
- if (cpu_has_64bit_gp_regs) {
+ if (IS_ENABLED(CONFIG_64BIT)) {
uasm_i_sd(buf, reg, off, A0);
} else {
uasm_i_sw(buf, reg, off, A0);
--
2.25.1

2020-03-24 16:20:36

by Christoph Hellwig

[permalink] [raw]
Subject: [PATCH 2/6] MIPS: cleanup fixup_bigphys_addr handling

fixup_bigphys_addr is only provided by the alchemy platform. Remove
all the stubs, and ensure we only call it if it is actually implemented.

Also don't bother implementing io_remap_pfn_range if we don't have to,
and move the remaining implementation to alchemy platform code.

Signed-off-by: Christoph Hellwig <[email protected]>
---
arch/mips/Kconfig | 4 +++
arch/mips/alchemy/common/setup.c | 16 ++++++---
arch/mips/include/asm/mach-au1x00/ioremap.h | 38 --------------------
arch/mips/include/asm/mach-bcm63xx/ioremap.h | 5 ---
arch/mips/include/asm/mach-bmips/ioremap.h | 5 ---
arch/mips/include/asm/mach-generic/ioremap.h | 9 -----
arch/mips/include/asm/mach-tx39xx/ioremap.h | 9 -----
arch/mips/include/asm/mach-tx49xx/ioremap.h | 9 -----
arch/mips/include/asm/pgtable.h | 23 ++++++------
arch/mips/pci/pci-alchemy.c | 2 +-
10 files changed, 27 insertions(+), 93 deletions(-)
delete mode 100644 arch/mips/include/asm/mach-au1x00/ioremap.h

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 797d7f1ad5fe..091e524e5ab4 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -92,6 +92,9 @@ config MIPS
select SYSCTL_EXCEPTION_TRACE
select VIRT_TO_BUS

+config MIPS_FIXUP_BIGPHYS_ADDR
+ bool
+
menu "Machine selection"

choice
@@ -157,6 +160,7 @@ config MIPS_ALCHEMY
select CSRC_R4K
select IRQ_MIPS_CPU
select DMA_MAYBE_COHERENT # Au1000,1500,1100 aren't, rest is
+ select MIPS_FIXUP_BIGPHYS_ADDR if PCI
select SYS_HAS_CPU_MIPS32_R1
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_APM_EMULATION
diff --git a/arch/mips/alchemy/common/setup.c b/arch/mips/alchemy/common/setup.c
index 7faaa6d593a7..a8cbc552bd64 100644
--- a/arch/mips/alchemy/common/setup.c
+++ b/arch/mips/alchemy/common/setup.c
@@ -72,9 +72,9 @@ void __init plat_mem_setup(void)
iomem_resource.end = IOMEM_RESOURCE_END;
}

-#if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_PCI)
+#ifdef CONFIG_MIPS_FIXUP_BIGPHYS_ADDR
/* This routine should be valid for all Au1x based boards */
-phys_addr_t __fixup_bigphys_addr(phys_addr_t phys_addr, phys_addr_t size)
+phys_addr_t fixup_bigphys_addr(phys_addr_t phys_addr, phys_addr_t size)
{
unsigned long start = ALCHEMY_PCI_MEMWIN_START;
unsigned long end = ALCHEMY_PCI_MEMWIN_END;
@@ -90,5 +90,13 @@ phys_addr_t __fixup_bigphys_addr(phys_addr_t phys_addr, phys_addr_t size)
/* default nop */
return phys_addr;
}
-EXPORT_SYMBOL(__fixup_bigphys_addr);
-#endif
+
+int io_remap_pfn_range(struct vm_area_struct *vma, unsigned long vaddr,
+ unsigned long pfn, unsigned long size, pgprot_t prot)
+{
+ phys_addr_t phys_addr = fixup_bigphys_addr(pfn << PAGE_SHIFT, size);
+
+ return remap_pfn_range(vma, vaddr, phys_addr >> PAGE_SHIFT, size, prot);
+}
+EXPORT_SYMBOL(io_remap_pfn_range);
+#endif /* CONFIG_MIPS_FIXUP_BIGPHYS_ADDR */
diff --git a/arch/mips/include/asm/mach-au1x00/ioremap.h b/arch/mips/include/asm/mach-au1x00/ioremap.h
deleted file mode 100644
index f6877ed8b8d0..000000000000
--- a/arch/mips/include/asm/mach-au1x00/ioremap.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * include/asm-mips/mach-au1x00/ioremap.h
- */
-#ifndef __ASM_MACH_AU1X00_IOREMAP_H
-#define __ASM_MACH_AU1X00_IOREMAP_H
-
-#include <linux/types.h>
-
-#if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_PCI)
-extern phys_addr_t __fixup_bigphys_addr(phys_addr_t, phys_addr_t);
-#else
-static inline phys_addr_t __fixup_bigphys_addr(phys_addr_t phys_addr, phys_addr_t size)
-{
- return phys_addr;
-}
-#endif
-
-/*
- * Allow physical addresses to be fixed up to help 36-bit peripherals.
- */
-static inline phys_addr_t fixup_bigphys_addr(phys_addr_t phys_addr, phys_addr_t size)
-{
- return __fixup_bigphys_addr(phys_addr, size);
-}
-
-static inline void __iomem *plat_ioremap(phys_addr_t offset, unsigned long size,
- unsigned long flags)
-{
- return NULL;
-}
-
-static inline int plat_iounmap(const volatile void __iomem *addr)
-{
- return 0;
-}
-
-#endif /* __ASM_MACH_AU1X00_IOREMAP_H */
diff --git a/arch/mips/include/asm/mach-bcm63xx/ioremap.h b/arch/mips/include/asm/mach-bcm63xx/ioremap.h
index 8cd261ec0a75..73f31825bbf3 100644
--- a/arch/mips/include/asm/mach-bcm63xx/ioremap.h
+++ b/arch/mips/include/asm/mach-bcm63xx/ioremap.h
@@ -4,11 +4,6 @@

#include <bcm63xx_cpu.h>

-static inline phys_addr_t fixup_bigphys_addr(phys_addr_t phys_addr, phys_addr_t size)
-{
- return phys_addr;
-}
-
static inline int is_bcm63xx_internal_registers(phys_addr_t offset)
{
switch (bcm63xx_get_cpu_id()) {
diff --git a/arch/mips/include/asm/mach-bmips/ioremap.h b/arch/mips/include/asm/mach-bmips/ioremap.h
index 52632ebc705f..63b4af9916b6 100644
--- a/arch/mips/include/asm/mach-bmips/ioremap.h
+++ b/arch/mips/include/asm/mach-bmips/ioremap.h
@@ -4,11 +4,6 @@

#include <linux/types.h>

-static inline phys_addr_t fixup_bigphys_addr(phys_addr_t phys_addr, phys_addr_t size)
-{
- return phys_addr;
-}
-
static inline int is_bmips_internal_registers(phys_addr_t offset)
{
if (offset >= 0xfff80000)
diff --git a/arch/mips/include/asm/mach-generic/ioremap.h b/arch/mips/include/asm/mach-generic/ioremap.h
index 4e36ea25ed33..f2442b84545c 100644
--- a/arch/mips/include/asm/mach-generic/ioremap.h
+++ b/arch/mips/include/asm/mach-generic/ioremap.h
@@ -7,15 +7,6 @@

#include <linux/types.h>

-/*
- * Allow physical addresses to be fixed up to help peripherals located
- * outside the low 32-bit range -- generic pass-through version.
- */
-static inline phys_addr_t fixup_bigphys_addr(phys_addr_t phys_addr, phys_addr_t size)
-{
- return phys_addr;
-}
-
static inline void __iomem *plat_ioremap(phys_addr_t offset, unsigned long size,
unsigned long flags)
{
diff --git a/arch/mips/include/asm/mach-tx39xx/ioremap.h b/arch/mips/include/asm/mach-tx39xx/ioremap.h
index 077b3c9971f7..157a7292397e 100644
--- a/arch/mips/include/asm/mach-tx39xx/ioremap.h
+++ b/arch/mips/include/asm/mach-tx39xx/ioremap.h
@@ -7,15 +7,6 @@

#include <linux/types.h>

-/*
- * Allow physical addresses to be fixed up to help peripherals located
- * outside the low 32-bit range -- generic pass-through version.
- */
-static inline phys_addr_t fixup_bigphys_addr(phys_addr_t phys_addr, phys_addr_t size)
-{
- return phys_addr;
-}
-
static inline void __iomem *plat_ioremap(phys_addr_t offset, unsigned long size,
unsigned long flags)
{
diff --git a/arch/mips/include/asm/mach-tx49xx/ioremap.h b/arch/mips/include/asm/mach-tx49xx/ioremap.h
index c6b9e05f44c4..b1f3710acf8e 100644
--- a/arch/mips/include/asm/mach-tx49xx/ioremap.h
+++ b/arch/mips/include/asm/mach-tx49xx/ioremap.h
@@ -7,15 +7,6 @@

#include <linux/types.h>

-/*
- * Allow physical addresses to be fixed up to help peripherals located
- * outside the low 32-bit range -- generic pass-through version.
- */
-static inline phys_addr_t fixup_bigphys_addr(phys_addr_t phys_addr, phys_addr_t size)
-{
- return phys_addr;
-}
-
static inline void __iomem *plat_ioremap(phys_addr_t offset, unsigned long size,
unsigned long flags)
{
diff --git a/arch/mips/include/asm/pgtable.h b/arch/mips/include/asm/pgtable.h
index aef5378f909c..80a2ef213777 100644
--- a/arch/mips/include/asm/pgtable.h
+++ b/arch/mips/include/asm/pgtable.h
@@ -491,20 +491,17 @@ static inline void update_mmu_cache_pmd(struct vm_area_struct *vma,

#define kern_addr_valid(addr) (1)

-#ifdef CONFIG_PHYS_ADDR_T_64BIT
-extern int remap_pfn_range(struct vm_area_struct *vma, unsigned long from, unsigned long pfn, unsigned long size, pgprot_t prot);
-
-static inline int io_remap_pfn_range(struct vm_area_struct *vma,
- unsigned long vaddr,
- unsigned long pfn,
- unsigned long size,
- pgprot_t prot)
-{
- phys_addr_t phys_addr_high = fixup_bigphys_addr(pfn << PAGE_SHIFT, size);
- return remap_pfn_range(vma, vaddr, phys_addr_high >> PAGE_SHIFT, size, prot);
-}
+/*
+ * Allow physical addresses to be fixed up to help 36-bit peripherals.
+ */
+#ifdef CONFIG_MIPS_FIXUP_BIGPHYS_ADDR
+phys_addr_t fixup_bigphys_addr(phys_addr_t addr, phys_addr_t size);
+int io_remap_pfn_range(struct vm_area_struct *vma, unsigned long vaddr,
+ unsigned long pfn, unsigned long size, pgprot_t prot);
#define io_remap_pfn_range io_remap_pfn_range
-#endif
+#else
+#define fixup_bigphys_addr(addr, size) (addr)
+#endif /* CONFIG_MIPS_FIXUP_BIGPHYS_ADDR */

#ifdef CONFIG_TRANSPARENT_HUGEPAGE

diff --git a/arch/mips/pci/pci-alchemy.c b/arch/mips/pci/pci-alchemy.c
index 01a2af8215c8..7285b5667568 100644
--- a/arch/mips/pci/pci-alchemy.c
+++ b/arch/mips/pci/pci-alchemy.c
@@ -52,7 +52,7 @@ struct alchemy_pci_context {
static struct alchemy_pci_context *__alchemy_pci_ctx;


-/* IO/MEM resources for PCI. Keep the memres in sync with __fixup_bigphys_addr
+/* IO/MEM resources for PCI. Keep the memres in sync with fixup_bigphys_addr
* in arch/mips/alchemy/common/setup.c
*/
static struct resource alchemy_pci_def_memres = {
--
2.25.1

2020-03-24 16:20:42

by Christoph Hellwig

[permalink] [raw]
Subject: [PATCH 3/6] MIPS: merge __ioremap_mode into ioremap_prot

There is no reason to have two ioremap with flags interfaces. Merge
the historic mips __ioremap_mode into ioremap_prot which is a generic
kernel interface.

Signed-off-by: Christoph Hellwig <[email protected]>
---
arch/mips/include/asm/io.h | 30 +++++++++++++-----------------
1 file changed, 13 insertions(+), 17 deletions(-)

diff --git a/arch/mips/include/asm/io.h b/arch/mips/include/asm/io.h
index 7be323ed2bfd..60513250f8f8 100644
--- a/arch/mips/include/asm/io.h
+++ b/arch/mips/include/asm/io.h
@@ -156,9 +156,17 @@ static inline void *isa_bus_to_virt(unsigned long address)
extern void __iomem * __ioremap(phys_addr_t offset, phys_addr_t size, unsigned long flags);
extern void __iounmap(const volatile void __iomem *addr);

-static inline void __iomem * __ioremap_mode(phys_addr_t offset, unsigned long size,
- unsigned long flags)
+/*
+ * ioremap_prot - map bus memory into CPU space
+ * @offset: bus address of the memory
+ * @size: size of the resource to map
+
+ * ioremap_prot gives the caller control over cache coherency attributes (CCA)
+ */
+static inline void __iomem *ioremap_prot(phys_addr_t offset,
+ unsigned long size, unsigned long prot_val)
{
+ unsigned long flags = prot_val & _CACHE_MASK;
void __iomem *addr = plat_ioremap(offset, size, flags);

if (addr)
@@ -202,18 +210,6 @@ static inline void __iomem * __ioremap_mode(phys_addr_t offset, unsigned long si
#undef __IS_LOW512
}

-/*
- * ioremap_prot - map bus memory into CPU space
- * @offset: bus address of the memory
- * @size: size of the resource to map
-
- * ioremap_prot gives the caller control over cache coherency attributes (CCA)
- */
-static inline void __iomem *ioremap_prot(phys_addr_t offset,
- unsigned long size, unsigned long prot_val) {
- return __ioremap_mode(offset, size, prot_val & _CACHE_MASK);
-}
-
/*
* ioremap - map bus memory into CPU space
* @offset: bus address of the memory
@@ -226,7 +222,7 @@ static inline void __iomem *ioremap_prot(phys_addr_t offset,
* address.
*/
#define ioremap(offset, size) \
- __ioremap_mode((offset), (size), _CACHE_UNCACHED)
+ ioremap_prot((offset), (size), _CACHE_UNCACHED)
#define ioremap_uc ioremap

/*
@@ -245,7 +241,7 @@ static inline void __iomem *ioremap_prot(phys_addr_t offset,
* memory-like regions on I/O busses.
*/
#define ioremap_cache(offset, size) \
- __ioremap_mode((offset), (size), _page_cachable_default)
+ ioremap_prot((offset), (size), _page_cachable_default)

/*
* ioremap_wc - map bus memory into CPU space
@@ -266,7 +262,7 @@ static inline void __iomem *ioremap_prot(phys_addr_t offset,
* _CACHE_UNCACHED option (see cpu_probe() method).
*/
#define ioremap_wc(offset, size) \
- __ioremap_mode((offset), (size), boot_cpu_data.writecombine)
+ ioremap_prot((offset), (size), boot_cpu_data.writecombine)

static inline void iounmap(const volatile void __iomem *addr)
{
--
2.25.1

2020-03-24 16:20:45

by Christoph Hellwig

[permalink] [raw]
Subject: [PATCH 4/6] MIPS: split out the 64-bit ioremap implementation

Split out the mips64 ioremap implementation entirely, as it will never use
page table based remapping.

Signed-off-by: Christoph Hellwig <[email protected]>
---
arch/mips/include/asm/io.h | 65 ++++++++++++++++++++++----------------
1 file changed, 37 insertions(+), 28 deletions(-)

diff --git a/arch/mips/include/asm/io.h b/arch/mips/include/asm/io.h
index 60513250f8f8..f007571e036d 100644
--- a/arch/mips/include/asm/io.h
+++ b/arch/mips/include/asm/io.h
@@ -153,6 +153,25 @@ static inline void *isa_bus_to_virt(unsigned long address)
*/
#define page_to_phys(page) ((dma_addr_t)page_to_pfn(page) << PAGE_SHIFT)

+#ifdef CONFIG_64BIT
+static inline void __iomem *ioremap_prot(phys_addr_t offset,
+ unsigned long size, unsigned long prot_val)
+{
+ unsigned long flags = prot_val & _CACHE_MASK;
+ u64 base = (flags == _CACHE_UNCACHED ? IO_BASE : UNCAC_BASE);
+ void __iomem *addr;
+
+ addr = plat_ioremap(offset, size, flags);
+ if (!addr)
+ addr = (void __iomem *)(unsigned long)(base + offset);
+ return addr;
+}
+
+static inline void iounmap(const volatile void __iomem *addr)
+{
+ plat_iounmap(addr);
+}
+#else /* CONFIG_64BIT */
extern void __iomem * __ioremap(phys_addr_t offset, phys_addr_t size, unsigned long flags);
extern void __iounmap(const volatile void __iomem *addr);

@@ -174,18 +193,8 @@ static inline void __iomem *ioremap_prot(phys_addr_t offset,

#define __IS_LOW512(addr) (!((phys_addr_t)(addr) & (phys_addr_t) ~0x1fffffffULL))

- if (IS_ENABLED(CONFIG_64BIT)) {
- u64 base = UNCAC_BASE;
-
- /*
- * R10000 supports a 2 bit uncached attribute therefore
- * UNCAC_BASE may not equal IO_BASE.
- */
- if (flags == _CACHE_UNCACHED)
- base = (u64) IO_BASE;
- return (void __iomem *) (unsigned long) (base + offset);
- } else if (__builtin_constant_p(offset) &&
- __builtin_constant_p(size) && __builtin_constant_p(flags)) {
+ if (__builtin_constant_p(offset) &&
+ __builtin_constant_p(size) && __builtin_constant_p(flags)) {
phys_addr_t phys_addr, last_addr;

phys_addr = fixup_bigphys_addr(offset, size);
@@ -210,6 +219,22 @@ static inline void __iomem *ioremap_prot(phys_addr_t offset,
#undef __IS_LOW512
}

+static inline void iounmap(const volatile void __iomem *addr)
+{
+ if (plat_iounmap(addr))
+ return;
+
+#define __IS_KSEG1(addr) (((unsigned long)(addr) & ~0x1fffffffUL) == CKSEG1)
+
+ if (__builtin_constant_p(addr) && __IS_KSEG1(addr))
+ return;
+
+ __iounmap(addr);
+
+#undef __IS_KSEG1
+}
+#endif /* !CONFIG_64BIT */
+
/*
* ioremap - map bus memory into CPU space
* @offset: bus address of the memory
@@ -264,22 +289,6 @@ static inline void __iomem *ioremap_prot(phys_addr_t offset,
#define ioremap_wc(offset, size) \
ioremap_prot((offset), (size), boot_cpu_data.writecombine)

-static inline void iounmap(const volatile void __iomem *addr)
-{
- if (plat_iounmap(addr))
- return;
-
-#define __IS_KSEG1(addr) (((unsigned long)(addr) & ~0x1fffffffUL) == CKSEG1)
-
- if (IS_ENABLED(CONFIG_64BIT) ||
- (__builtin_constant_p(addr) && __IS_KSEG1(addr)))
- return;
-
- __iounmap(addr);
-
-#undef __IS_KSEG1
-}
-
#if defined(CONFIG_CPU_CAVIUM_OCTEON) || defined(CONFIG_CPU_LOONGSON64)
#define war_io_reorder_wmb() wmb()
#else
--
2.25.1

2020-03-24 16:22:16

by Christoph Hellwig

[permalink] [raw]
Subject: [PATCH 5/6] MIPS: move ioremap_prot und iounmap out of line

Neither of these interfaces is anywhere near the fast path. Move them
out of line and avoid exposing implementation details to the drivers.

Signed-off-by: Christoph Hellwig <[email protected]>
---
arch/mips/include/asm/io.h | 86 ++------------------------------------
arch/mips/mm/Makefile | 2 +-
arch/mips/mm/ioremap.c | 45 ++++++++++----------
arch/mips/mm/ioremap64.c | 23 ++++++++++
4 files changed, 49 insertions(+), 107 deletions(-)
create mode 100644 arch/mips/mm/ioremap64.c

diff --git a/arch/mips/include/asm/io.h b/arch/mips/include/asm/io.h
index f007571e036d..346fffd9e972 100644
--- a/arch/mips/include/asm/io.h
+++ b/arch/mips/include/asm/io.h
@@ -30,8 +30,6 @@
#include <asm/pgtable-bits.h>
#include <asm/processor.h>
#include <asm/string.h>
-
-#include <ioremap.h>
#include <mangle-port.h>

/*
@@ -153,87 +151,9 @@ static inline void *isa_bus_to_virt(unsigned long address)
*/
#define page_to_phys(page) ((dma_addr_t)page_to_pfn(page) << PAGE_SHIFT)

-#ifdef CONFIG_64BIT
-static inline void __iomem *ioremap_prot(phys_addr_t offset,
- unsigned long size, unsigned long prot_val)
-{
- unsigned long flags = prot_val & _CACHE_MASK;
- u64 base = (flags == _CACHE_UNCACHED ? IO_BASE : UNCAC_BASE);
- void __iomem *addr;
-
- addr = plat_ioremap(offset, size, flags);
- if (!addr)
- addr = (void __iomem *)(unsigned long)(base + offset);
- return addr;
-}
-
-static inline void iounmap(const volatile void __iomem *addr)
-{
- plat_iounmap(addr);
-}
-#else /* CONFIG_64BIT */
-extern void __iomem * __ioremap(phys_addr_t offset, phys_addr_t size, unsigned long flags);
-extern void __iounmap(const volatile void __iomem *addr);
-
-/*
- * ioremap_prot - map bus memory into CPU space
- * @offset: bus address of the memory
- * @size: size of the resource to map
-
- * ioremap_prot gives the caller control over cache coherency attributes (CCA)
- */
-static inline void __iomem *ioremap_prot(phys_addr_t offset,
- unsigned long size, unsigned long prot_val)
-{
- unsigned long flags = prot_val & _CACHE_MASK;
- void __iomem *addr = plat_ioremap(offset, size, flags);
-
- if (addr)
- return addr;
-
-#define __IS_LOW512(addr) (!((phys_addr_t)(addr) & (phys_addr_t) ~0x1fffffffULL))
-
- if (__builtin_constant_p(offset) &&
- __builtin_constant_p(size) && __builtin_constant_p(flags)) {
- phys_addr_t phys_addr, last_addr;
-
- phys_addr = fixup_bigphys_addr(offset, size);
-
- /* Don't allow wraparound or zero size. */
- last_addr = phys_addr + size - 1;
- if (!size || last_addr < phys_addr)
- return NULL;
-
- /*
- * Map uncached objects in the low 512MB of address
- * space using KSEG1.
- */
- if (__IS_LOW512(phys_addr) && __IS_LOW512(last_addr) &&
- flags == _CACHE_UNCACHED)
- return (void __iomem *)
- (unsigned long)CKSEG1ADDR(phys_addr);
- }
-
- return __ioremap(offset, size, flags);
-
-#undef __IS_LOW512
-}
-
-static inline void iounmap(const volatile void __iomem *addr)
-{
- if (plat_iounmap(addr))
- return;
-
-#define __IS_KSEG1(addr) (((unsigned long)(addr) & ~0x1fffffffUL) == CKSEG1)
-
- if (__builtin_constant_p(addr) && __IS_KSEG1(addr))
- return;
-
- __iounmap(addr);
-
-#undef __IS_KSEG1
-}
-#endif /* !CONFIG_64BIT */
+void __iomem *ioremap_prot(phys_addr_t offset, unsigned long size,
+ unsigned long prot_val);
+void iounmap(const volatile void __iomem *addr);

/*
* ioremap - map bus memory into CPU space
diff --git a/arch/mips/mm/Makefile b/arch/mips/mm/Makefile
index 46f483e952c8..865926a37775 100644
--- a/arch/mips/mm/Makefile
+++ b/arch/mips/mm/Makefile
@@ -23,7 +23,7 @@ obj-y += uasm-mips.o
endif

obj-$(CONFIG_32BIT) += ioremap.o pgtable-32.o
-obj-$(CONFIG_64BIT) += pgtable-64.o
+obj-$(CONFIG_64BIT) += ioremap64.o pgtable-64.o
obj-$(CONFIG_HIGHMEM) += highmem.o
obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
obj-$(CONFIG_DMA_NONCOHERENT) += dma-noncoherent.o
diff --git a/arch/mips/mm/ioremap.c b/arch/mips/mm/ioremap.c
index 8317f337a86e..c5b5181c7cd0 100644
--- a/arch/mips/mm/ioremap.c
+++ b/arch/mips/mm/ioremap.c
@@ -17,6 +17,10 @@
#include <asm/cacheflush.h>
#include <asm/io.h>
#include <asm/tlbflush.h>
+#include <ioremap.h>
+
+#define IS_LOW512(addr) (!((phys_addr_t)(addr) & (phys_addr_t) ~0x1fffffffULL))
+#define IS_KSEG1(addr) (((unsigned long)(addr) & ~0x1fffffffUL) == CKSEG1)

static inline void remap_area_pte(pte_t * pte, unsigned long address,
phys_addr_t size, phys_addr_t phys_addr, unsigned long flags)
@@ -118,27 +122,25 @@ static int __ioremap_check_ram(unsigned long start_pfn, unsigned long nr_pages,
}

/*
- * Generic mapping function (not visible outside):
- */
-
-/*
- * Remap an arbitrary physical address space into the kernel virtual
- * address space. Needed when the kernel wants to access high addresses
- * directly.
+ * ioremap_prot - map bus memory into CPU space
+ * @phys_addr: bus address of the memory
+ * @size: size of the resource to map
*
- * NOTE! We need to allow non-page-aligned mappings too: we will obviously
- * have to convert them into an offset in a page-aligned mapping, but the
- * caller shouldn't need to know that small detail.
+ * ioremap_prot gives the caller control over cache coherency attributes (CCA)
*/
-
-#define IS_LOW512(addr) (!((phys_addr_t)(addr) & (phys_addr_t) ~0x1fffffffULL))
-
-void __iomem * __ioremap(phys_addr_t phys_addr, phys_addr_t size, unsigned long flags)
+void __iomem *ioremap_prot(phys_addr_t phys_addr, unsigned long size,
+ unsigned long prot_val)
{
+ unsigned long flags = prot_val & _CACHE_MASK;
unsigned long offset, pfn, last_pfn;
- struct vm_struct * area;
+ struct vm_struct *area;
phys_addr_t last_addr;
- void * addr;
+ void *addr;
+ void __iomem *cpu_addr;
+
+ cpu_addr = plat_ioremap(phys_addr, size, flags);
+ if (cpu_addr)
+ return cpu_addr;

phys_addr = fixup_bigphys_addr(phys_addr, size);

@@ -189,14 +191,13 @@ void __iomem * __ioremap(phys_addr_t phys_addr, phys_addr_t size, unsigned long

return (void __iomem *) (offset + (char *)addr);
}
+EXPORT_SYMBOL(ioremap_prot);

-#define IS_KSEG1(addr) (((unsigned long)(addr) & ~0x1fffffffUL) == CKSEG1)
-
-void __iounmap(const volatile void __iomem *addr)
+void iounmap(const volatile void __iomem *addr)
{
struct vm_struct *p;

- if (IS_KSEG1(addr))
+ if (plat_iounmap(addr) || IS_KSEG1(addr))
return;

p = remove_vm_area((void *) (PAGE_MASK & (unsigned long __force) addr));
@@ -205,6 +206,4 @@ void __iounmap(const volatile void __iomem *addr)

kfree(p);
}
-
-EXPORT_SYMBOL(__ioremap);
-EXPORT_SYMBOL(__iounmap);
+EXPORT_SYMBOL(iounmap);
diff --git a/arch/mips/mm/ioremap64.c b/arch/mips/mm/ioremap64.c
new file mode 100644
index 000000000000..15e7820d6a5f
--- /dev/null
+++ b/arch/mips/mm/ioremap64.c
@@ -0,0 +1,23 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#include <linux/io.h>
+#include <ioremap.h>
+
+void __iomem *ioremap_prot(phys_addr_t offset, unsigned long size,
+ unsigned long prot_val)
+{
+ unsigned long flags = prot_val & _CACHE_MASK;
+ u64 base = (flags == _CACHE_UNCACHED ? IO_BASE : UNCAC_BASE);
+ void __iomem *addr;
+
+ addr = plat_ioremap(offset, size, flags);
+ if (!addr)
+ addr = (void __iomem *)(unsigned long)(base + offset);
+ return addr;
+}
+EXPORT_SYMBOL(ioremap_prot);
+
+void iounmap(const volatile void __iomem *addr)
+{
+ plat_iounmap(addr);
+}
+EXPORT_SYMBOL(iounmap);
--
2.25.1

2020-03-24 16:22:18

by Christoph Hellwig

[permalink] [raw]
Subject: [PATCH 6/6] MIPS: use ioremap_page_range

Use the generic ioremap_page_range helper instead of reimplementing it.

Signed-off-by: Christoph Hellwig <[email protected]>
---
arch/mips/mm/ioremap.c | 112 ++++-------------------------------------
1 file changed, 11 insertions(+), 101 deletions(-)

diff --git a/arch/mips/mm/ioremap.c b/arch/mips/mm/ioremap.c
index c5b5181c7cd0..b6dad2fd5575 100644
--- a/arch/mips/mm/ioremap.c
+++ b/arch/mips/mm/ioremap.c
@@ -14,99 +14,14 @@
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/mm_types.h>
+#include <linux/io.h>
#include <asm/cacheflush.h>
-#include <asm/io.h>
#include <asm/tlbflush.h>
#include <ioremap.h>

#define IS_LOW512(addr) (!((phys_addr_t)(addr) & (phys_addr_t) ~0x1fffffffULL))
#define IS_KSEG1(addr) (((unsigned long)(addr) & ~0x1fffffffUL) == CKSEG1)

-static inline void remap_area_pte(pte_t * pte, unsigned long address,
- phys_addr_t size, phys_addr_t phys_addr, unsigned long flags)
-{
- phys_addr_t end;
- unsigned long pfn;
- pgprot_t pgprot = __pgprot(_PAGE_GLOBAL | _PAGE_PRESENT | __READABLE
- | __WRITEABLE | flags);
-
- address &= ~PMD_MASK;
- end = address + size;
- if (end > PMD_SIZE)
- end = PMD_SIZE;
- BUG_ON(address >= end);
- pfn = phys_addr >> PAGE_SHIFT;
- do {
- if (!pte_none(*pte)) {
- printk("remap_area_pte: page already exists\n");
- BUG();
- }
- set_pte(pte, pfn_pte(pfn, pgprot));
- address += PAGE_SIZE;
- pfn++;
- pte++;
- } while (address && (address < end));
-}
-
-static inline int remap_area_pmd(pmd_t * pmd, unsigned long address,
- phys_addr_t size, phys_addr_t phys_addr, unsigned long flags)
-{
- phys_addr_t end;
-
- address &= ~PGDIR_MASK;
- end = address + size;
- if (end > PGDIR_SIZE)
- end = PGDIR_SIZE;
- phys_addr -= address;
- BUG_ON(address >= end);
- do {
- pte_t * pte = pte_alloc_kernel(pmd, address);
- if (!pte)
- return -ENOMEM;
- remap_area_pte(pte, address, end - address, address + phys_addr, flags);
- address = (address + PMD_SIZE) & PMD_MASK;
- pmd++;
- } while (address && (address < end));
- return 0;
-}
-
-static int remap_area_pages(unsigned long address, phys_addr_t phys_addr,
- phys_addr_t size, unsigned long flags)
-{
- int error;
- pgd_t * dir;
- unsigned long end = address + size;
-
- phys_addr -= address;
- dir = pgd_offset(&init_mm, address);
- flush_cache_all();
- BUG_ON(address >= end);
- do {
- p4d_t *p4d;
- pud_t *pud;
- pmd_t *pmd;
-
- error = -ENOMEM;
- p4d = p4d_alloc(&init_mm, dir, address);
- if (!p4d)
- break;
- pud = pud_alloc(&init_mm, p4d, address);
- if (!pud)
- break;
- pmd = pmd_alloc(&init_mm, pud, address);
- if (!pmd)
- break;
- if (remap_area_pmd(pmd, address, end - address,
- phys_addr + address, flags))
- break;
- error = 0;
- address = (address + PGDIR_SIZE) & PGDIR_MASK;
- dir++;
- } while (address && (address < end));
- flush_tlb_all();
- return error;
-}
-
static int __ioremap_check_ram(unsigned long start_pfn, unsigned long nr_pages,
void *arg)
{
@@ -135,7 +50,7 @@ void __iomem *ioremap_prot(phys_addr_t phys_addr, unsigned long size,
unsigned long offset, pfn, last_pfn;
struct vm_struct *area;
phys_addr_t last_addr;
- void *addr;
+ unsigned long vaddr;
void __iomem *cpu_addr;

cpu_addr = plat_ioremap(phys_addr, size, flags);
@@ -183,27 +98,22 @@ void __iomem *ioremap_prot(phys_addr_t phys_addr, unsigned long size,
area = get_vm_area(size, VM_IOREMAP);
if (!area)
return NULL;
- addr = area->addr;
- if (remap_area_pages((unsigned long) addr, phys_addr, size, flags)) {
- vunmap(addr);
+ vaddr = (unsigned long)area->addr;
+
+ flags |= _PAGE_GLOBAL | _PAGE_PRESENT | __READABLE | __WRITEABLE;
+ if (ioremap_page_range(vaddr, vaddr + size, phys_addr,
+ __pgprot(flags))) {
+ free_vm_area(area);
return NULL;
}

- return (void __iomem *) (offset + (char *)addr);
+ return (void __iomem *)(vaddr + offset);
}
EXPORT_SYMBOL(ioremap_prot);

void iounmap(const volatile void __iomem *addr)
{
- struct vm_struct *p;
-
- if (plat_iounmap(addr) || IS_KSEG1(addr))
- return;
-
- p = remove_vm_area((void *) (PAGE_MASK & (unsigned long __force) addr));
- if (!p)
- printk(KERN_ERR "iounmap: bad address %p\n", addr);
-
- kfree(p);
+ if (!plat_iounmap(addr) && !IS_KSEG1(addr))
+ vunmap((void *)((unsigned long)addr & PAGE_MASK));
}
EXPORT_SYMBOL(iounmap);
--
2.25.1

2020-03-25 02:37:59

by Maciej W. Rozycki

[permalink] [raw]
Subject: Re: [PATCH 1/6] MIPS: remove cpu_has_64bit_gp_regs and cpu_has_64bit_addresses

On Tue, 24 Mar 2020, Christoph Hellwig wrote:

> Both macros are always identical to CONFIG_64BIT.

I think this abstraction makes sense, especially if we want to support
64-bit CPUs that only support 32-bit segments, i.e. MIPS architecture
processors whose CP0.Config.AT=1, or legacy MIPS processors that had a
similar limitation, such as the R5900 currently under review.

Maciej

2020-03-25 08:31:07

by Christoph Hellwig

[permalink] [raw]
Subject: Re: [PATCH 1/6] MIPS: remove cpu_has_64bit_gp_regs and cpu_has_64bit_addresses

On Wed, Mar 25, 2020 at 02:36:57AM +0000, Maciej W. Rozycki wrote:
> On Tue, 24 Mar 2020, Christoph Hellwig wrote:
>
> > Both macros are always identical to CONFIG_64BIT.
>
> I think this abstraction makes sense, especially if we want to support
> 64-bit CPUs that only support 32-bit segments, i.e. MIPS architecture
> processors whose CP0.Config.AT=1, or legacy MIPS processors that had a
> similar limitation, such as the R5900 currently under review.

The only use of cpu_has_64bit_addresses is the choice of the ioremap
code base. Which ioremap code does the R5900 want to use? If it
doesn't match CONFIG_64BIT having a config option for the ioremap
implementation seems much more sensible, and can be added with the
R5900 patch set (do you have a link to it?).

2020-03-25 08:59:32

by Christoph Hellwig

[permalink] [raw]
Subject: Re: [PATCH 1/6] MIPS: remove cpu_has_64bit_gp_regs and cpu_has_64bit_addresses

On Wed, Mar 25, 2020 at 09:55:24AM +0100, Fredrik Noring wrote:
> > The only use of cpu_has_64bit_addresses is the choice of the ioremap
> > code base. Which ioremap code does the R5900 want to use? If it
> > doesn't match CONFIG_64BIT having a config option for the ioremap
> > implementation seems much more sensible, and can be added with the
> > R5900 patch set (do you have a link to it?).
>
> I suppose this would be relevant for the n32 ABI, but initially we only
> have o32 for the R5900.

To enable ABIs you'll need Kconfig symbols, cpu_has_64bit_addresses
isn't going to be very useful for that. Which kinda rather was the
point of this patch - to use the existing Kconfig symbol rather than
two redundant defines that caused a lot weird cargo culting.

> The (slightly outdated) patch series under review
> is available here:
>
> https://lore.kernel.org/linux-mips/[email protected]/T/

You don't happen to have a git tree available somewhere?

2020-03-25 09:06:31

by Fredrik Noring

[permalink] [raw]
Subject: Re: [PATCH 1/6] MIPS: remove cpu_has_64bit_gp_regs and cpu_has_64bit_addresses

> The only use of cpu_has_64bit_addresses is the choice of the ioremap
> code base. Which ioremap code does the R5900 want to use? If it
> doesn't match CONFIG_64BIT having a config option for the ioremap
> implementation seems much more sensible, and can be added with the
> R5900 patch set (do you have a link to it?).

I suppose this would be relevant for the n32 ABI, but initially we only
have o32 for the R5900. The (slightly outdated) patch series under review
is available here:

https://lore.kernel.org/linux-mips/[email protected]/T/

Regarding cpu_has_64bit_gp_regs: another unusual aspect of the R5900 is
its 128-bit GPRs. :)

Fredrik

2020-03-25 09:34:16

by Fredrik Noring

[permalink] [raw]
Subject: Re: [PATCH 1/6] MIPS: remove cpu_has_64bit_gp_regs and cpu_has_64bit_addresses

> > The (slightly outdated) patch series under review
> > is available here:
> >
> > https://lore.kernel.org/linux-mips/[email protected]/T/
>
> You don't happen to have a git tree available somewhere?

https://github.com/frno7/linux/tree/ps2-v5.4

is stable at v5.4,

https://github.com/frno7/linux/tree/ps2-master

has more experimental stuff (also at v5.4 at the moment). There are some
(work-in-progress) notes on the R5900 psABI, that may be of interest, here:

https://github.com/frno7/linux/wiki/R5900-processor-specific-ABI-(psABI)

Fredrik

2020-03-25 09:56:00

by Christoph Hellwig

[permalink] [raw]
Subject: Re: [PATCH 1/6] MIPS: remove cpu_has_64bit_gp_regs and cpu_has_64bit_addresses

On Wed, Mar 25, 2020 at 10:24:46AM +0100, Fredrik Noring wrote:
> > > The (slightly outdated) patch series under review
> > > is available here:
> > >
> > > https://lore.kernel.org/linux-mips/[email protected]/T/
> >
> > You don't happen to have a git tree available somewhere?
>
> https://github.com/frno7/linux/tree/ps2-v5.4
>
> is stable at v5.4,
>
> https://github.com/frno7/linux/tree/ps2-master
>
> has more experimental stuff (also at v5.4 at the moment). There are some
> (work-in-progress) notes on the R5900 psABI, that may be of interest, here:
>
> https://github.com/frno7/linux/wiki/R5900-processor-specific-ABI-(psABI)

So from what I can tell this uses a 32-bit kernel and 32-bit userspace,
and sets both pu_has_64bit_gp_regs and cpu_has_64bit_addresses to 0.

Now if you ever wanted to make use of the 64-bit registeres it would
require quite some changes, which probably really should have a new
Kconfig option. In fact a lot of the workaround for the 64-bit
registeres that are in the code already should be keyed off such an
option rather than CONFIG_CPU_R5900.

2020-03-25 11:05:36

by Fredrik Noring

[permalink] [raw]
Subject: Re: [PATCH 1/6] MIPS: remove cpu_has_64bit_gp_regs and cpu_has_64bit_addresses

> So from what I can tell this uses a 32-bit kernel and 32-bit userspace,
> and sets both pu_has_64bit_gp_regs and cpu_has_64bit_addresses to 0.
>
> Now if you ever wanted to make use of the 64-bit registeres it would
> require quite some changes, which probably really should have a new
> Kconfig option. In fact a lot of the workaround for the 64-bit
> registeres that are in the code already should be keyed off such an
> option rather than CONFIG_CPU_R5900.

Addresses are always 32-bit for the R5900 (and not even sign extended?),
as I understand, but GPRs are also always 128-bit. The kernel is unable
to disable 64-bit operations and 128-bit multimedia instructions (MMIs)
because the R5900 doesn't implement CP0.Status.UX. [ In other MIPS ISA
implementations, attempting to execute 64-bit operations in 32-bit user
or supervisor mode may cause an reserved instruction exception. ]

The best approach, I think, is to have the kernel properly save/restore
128-bit GPRs in all cases, as MMIs are quite useful and actually would
"mostly" work regardless of any kernel support. I wrote "mostly" because
with o32 the upper 96 bits of the GPRs would be clobbered when switching
contexts unless they are restored by the kernel.

Also of note is that some pieces of hardware require a 64-bit store
instruction, even with a 32-bit kernel. This implies that the kernel
either saves 128 or 64 GPR bits in 32-bit mode too, or, that interrupts
are disabled to avoiding clobbering GPRs in these specific cases.

Fredrik