2020-04-26 11:53:27

by Jiaxun Yang

[permalink] [raw]
Subject: [PATCH 0/4] MIPS: Loongson64: Use logic_pio

To add I/O ports for PCI host bridge via devicetree, we have to use
logic_pio mechanism.
That would require convert I/O ports into virt memory map.

Jiaxun Yang (4):
MIPS: Massage address spaces headers
MIPS: Introduce PCI_IO_VMMAP
lib: logic_pio: Introduce MMIO_LOWER_RESERVED
MIPS: Loongson64: Enable PCI_IO_VMMAP

arch/mips/Kconfig | 4 ++
arch/mips/include/asm/addrspace.h | 4 +-
arch/mips/include/asm/io.h | 40 ++++++++++++++++----
arch/mips/include/asm/mach-generic/spaces.h | 42 +++++++++++++++------
arch/mips/include/asm/page-def.h | 28 ++++++++++++++
arch/mips/include/asm/page.h | 21 -----------
arch/mips/include/asm/pgtable-32.h | 2 -
arch/mips/include/asm/pgtable-64.h | 10 +----
arch/mips/include/asm/sync.h | 2 +
arch/mips/kernel/cps-vec.S | 3 +-
arch/mips/kernel/setup.c | 2 +
arch/mips/lib/iomap-pci.c | 2 +-
arch/mips/lib/uncached.c | 6 +--
arch/mips/loongson64/init.c | 12 ++++--
arch/mips/loongson64/pci.c | 2 +-
lib/logic_pio.c | 6 ++-
16 files changed, 122 insertions(+), 64 deletions(-)
create mode 100644 arch/mips/include/asm/page-def.h

--
2.26.0.rc2


2020-04-26 11:53:32

by Jiaxun Yang

[permalink] [raw]
Subject: [PATCH 1/4] MIPS: Massage address spaces headers

That would allow us modify kernel vm address spaces without
step into the hell of includes.

Also use some marcos for address spaces to make spaces.h more
clear.

Signed-off-by: Jiaxun Yang <[email protected]>
---
arch/mips/include/asm/addrspace.h | 4 +--
arch/mips/include/asm/mach-generic/spaces.h | 33 ++++++++++++++-------
arch/mips/include/asm/page-def.h | 28 +++++++++++++++++
arch/mips/include/asm/page.h | 21 -------------
arch/mips/include/asm/pgtable-32.h | 2 --
arch/mips/include/asm/pgtable-64.h | 10 ++-----
arch/mips/include/asm/sync.h | 2 ++
arch/mips/kernel/cps-vec.S | 3 +-
arch/mips/lib/uncached.c | 6 ++--
9 files changed, 60 insertions(+), 49 deletions(-)
create mode 100644 arch/mips/include/asm/page-def.h

diff --git a/arch/mips/include/asm/addrspace.h b/arch/mips/include/asm/addrspace.h
index 59a48c60a065..4fa8ee48ef02 100644
--- a/arch/mips/include/asm/addrspace.h
+++ b/arch/mips/include/asm/addrspace.h
@@ -10,7 +10,7 @@
#ifndef _ASM_ADDRSPACE_H
#define _ASM_ADDRSPACE_H

-#include <spaces.h>
+#include <linux/const.h>

/*
* Configure language
@@ -67,7 +67,7 @@
#define XKSEG _CONST64_(0xc000000000000000)
#define CKSEG0 _CONST64_(0xffffffff80000000)
#define CKSEG1 _CONST64_(0xffffffffa0000000)
-#define CKSSEG _CONST64_(0xffffffffc0000000)
+#define CKSEG2 _CONST64_(0xffffffffc0000000)
#define CKSEG3 _CONST64_(0xffffffffe0000000)

#define CKSEG0ADDR(a) (CPHYSADDR(a) | CKSEG0)
diff --git a/arch/mips/include/asm/mach-generic/spaces.h b/arch/mips/include/asm/mach-generic/spaces.h
index ee5ebe98f6cf..89162740951a 100644
--- a/arch/mips/include/asm/mach-generic/spaces.h
+++ b/arch/mips/include/asm/mach-generic/spaces.h
@@ -10,9 +10,9 @@
#ifndef _ASM_MACH_GENERIC_SPACES_H
#define _ASM_MACH_GENERIC_SPACES_H

-#include <linux/const.h>
-
+#include <asm/addrspace.h>
#include <asm/mipsregs.h>
+#include <asm/page-def.h>

/*
* This gives the physical RAM offset.
@@ -29,20 +29,20 @@
#ifdef CONFIG_KVM_GUEST
#define CAC_BASE _AC(0x40000000, UL)
#else
-#define CAC_BASE _AC(0x80000000, UL)
+#define CAC_BASE CKSEG0
#endif
#ifndef IO_BASE
-#define IO_BASE _AC(0xa0000000, UL)
+#define IO_BASE CKSEG1
#endif
#ifndef UNCAC_BASE
-#define UNCAC_BASE _AC(0xa0000000, UL)
+#define UNCAC_BASE CKSEG1
#endif

#ifndef MAP_BASE
#ifdef CONFIG_KVM_GUEST
#define MAP_BASE _AC(0x60000000, UL)
#else
-#define MAP_BASE _AC(0xc0000000, UL)
+#define MAP_BASE CKSEG2
#endif
#endif

@@ -58,19 +58,19 @@
#ifdef CONFIG_64BIT

#ifndef CAC_BASE
-#define CAC_BASE PHYS_TO_XKPHYS(read_c0_config() & CONF_CM_CMASK, 0)
+#define CAC_BASE PHYS_TO_XKPHYS(read_c0_config() & CONF_CM_CMASK, 0)
#endif

#ifndef IO_BASE
-#define IO_BASE _AC(0x9000000000000000, UL)
+#define IO_BASE PHYS_TO_XKPHYS(K_CALG_UNCACHED, 0)
#endif

#ifndef UNCAC_BASE
-#define UNCAC_BASE _AC(0x9000000000000000, UL)
+#define UNCAC_BASE PHYS_TO_XKPHYS(K_CALG_UNCACHED, 0)
#endif

#ifndef MAP_BASE
-#define MAP_BASE _AC(0xc000000000000000, UL)
+#define MAP_BASE XKSEG
#endif

/*
@@ -99,8 +99,19 @@
#ifdef CONFIG_KVM_GUEST
#define FIXADDR_TOP ((unsigned long)(long)(int)0x7ffe0000)
#else
-#define FIXADDR_TOP ((unsigned long)(long)(int)0xfffe0000)
+#define FIXADDR_TOP (CKSEG3 + 0x1ffe0000)
+#endif
#endif
+
+#ifdef CONFIG_64BIT
+/*
+ * TLB refill handlers also map the vmalloc area into xuseg. Avoid
+ * the first couple of pages so NULL pointer dereferences will still
+ * reliably trap.
+ */
+#define VMALLOC_START (MAP_BASE + (2 * PAGE_SIZE))
+#else
+#define VMALLOC_START MAP_BASE
#endif

#endif /* __ASM_MACH_GENERIC_SPACES_H */
diff --git a/arch/mips/include/asm/page-def.h b/arch/mips/include/asm/page-def.h
new file mode 100644
index 000000000000..a0110bcff7b3
--- /dev/null
+++ b/arch/mips/include/asm/page-def.h
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef __ASM_PAGE_DEF_H
+#define __ASM_PAGE_DEF_H
+
+#include <linux/const.h>
+/*
+ * PAGE_SHIFT determines the page size
+ */
+#ifdef CONFIG_PAGE_SIZE_4KB
+#define PAGE_SHIFT 12
+#endif
+#ifdef CONFIG_PAGE_SIZE_8KB
+#define PAGE_SHIFT 13
+#endif
+#ifdef CONFIG_PAGE_SIZE_16KB
+#define PAGE_SHIFT 14
+#endif
+#ifdef CONFIG_PAGE_SIZE_32KB
+#define PAGE_SHIFT 15
+#endif
+#ifdef CONFIG_PAGE_SIZE_64KB
+#define PAGE_SHIFT 16
+#endif
+#define PAGE_SIZE (_AC(1 ,UL) << PAGE_SHIFT)
+#define PAGE_MASK (~((1 << PAGE_SHIFT) - 1))
+
+#endif /* __ASM_PAGE_DEF_H */
+
diff --git a/arch/mips/include/asm/page.h b/arch/mips/include/asm/page.h
index e2f503fc7a84..07f6a55eec5d 100644
--- a/arch/mips/include/asm/page.h
+++ b/arch/mips/include/asm/page.h
@@ -14,27 +14,6 @@
#include <linux/kernel.h>
#include <asm/mipsregs.h>

-/*
- * PAGE_SHIFT determines the page size
- */
-#ifdef CONFIG_PAGE_SIZE_4KB
-#define PAGE_SHIFT 12
-#endif
-#ifdef CONFIG_PAGE_SIZE_8KB
-#define PAGE_SHIFT 13
-#endif
-#ifdef CONFIG_PAGE_SIZE_16KB
-#define PAGE_SHIFT 14
-#endif
-#ifdef CONFIG_PAGE_SIZE_32KB
-#define PAGE_SHIFT 15
-#endif
-#ifdef CONFIG_PAGE_SIZE_64KB
-#define PAGE_SHIFT 16
-#endif
-#define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT)
-#define PAGE_MASK (~((1 << PAGE_SHIFT) - 1))
-
/*
* This is used for calculating the real page sizes
* for FTLB or VTLB + FTLB configurations.
diff --git a/arch/mips/include/asm/pgtable-32.h b/arch/mips/include/asm/pgtable-32.h
index 1945c8970141..40049fda596b 100644
--- a/arch/mips/include/asm/pgtable-32.h
+++ b/arch/mips/include/asm/pgtable-32.h
@@ -95,8 +95,6 @@ extern int add_temporary_entry(unsigned long entrylo0, unsigned long entrylo1,
#define USER_PTRS_PER_PGD (0x80000000UL/PGDIR_SIZE)
#define FIRST_USER_ADDRESS 0UL

-#define VMALLOC_START MAP_BASE
-
#define PKMAP_END ((FIXADDR_START) & ~((LAST_PKMAP << PAGE_SHIFT)-1))
#define PKMAP_BASE (PKMAP_END - PAGE_SIZE * LAST_PKMAP)

diff --git a/arch/mips/include/asm/pgtable-64.h b/arch/mips/include/asm/pgtable-64.h
index ee5dc0c145b9..037aec0a14de 100644
--- a/arch/mips/include/asm/pgtable-64.h
+++ b/arch/mips/include/asm/pgtable-64.h
@@ -139,21 +139,15 @@
#define USER_PTRS_PER_PGD ((TASK_SIZE64 / PGDIR_SIZE)?(TASK_SIZE64 / PGDIR_SIZE):1)
#define FIRST_USER_ADDRESS 0UL

-/*
- * TLB refill handlers also map the vmalloc area into xuseg. Avoid
- * the first couple of pages so NULL pointer dereferences will still
- * reliably trap.
- */
-#define VMALLOC_START (MAP_BASE + (2 * PAGE_SIZE))
#define VMALLOC_END \
(MAP_BASE + \
min(PTRS_PER_PGD * PTRS_PER_PUD * PTRS_PER_PMD * PTRS_PER_PTE * PAGE_SIZE, \
(1UL << cpu_vmbits)) - (1UL << 32))

#if defined(CONFIG_MODULES) && defined(KBUILD_64BIT_SYM32) && \
- VMALLOC_START != CKSSEG
+ VMALLOC_START != CKSEG2
/* Load modules into 32bit-compatible segment. */
-#define MODULE_START CKSSEG
+#define MODULE_START CKSEG2
#define MODULE_END (FIXADDR_START-2*PAGE_SIZE)
#endif

diff --git a/arch/mips/include/asm/sync.h b/arch/mips/include/asm/sync.h
index aabd097933fe..8b297255854b 100644
--- a/arch/mips/include/asm/sync.h
+++ b/arch/mips/include/asm/sync.h
@@ -2,6 +2,8 @@
#ifndef __MIPS_ASM_SYNC_H__
#define __MIPS_ASM_SYNC_H__

+#include <linux/stringify.h>
+
/*
* sync types are defined by the MIPS64 Instruction Set documentation in Volume
* II-A of the MIPS Architecture Reference Manual, which can be found here:
diff --git a/arch/mips/kernel/cps-vec.S b/arch/mips/kernel/cps-vec.S
index 4db7ff055c9f..ba5e89825308 100644
--- a/arch/mips/kernel/cps-vec.S
+++ b/arch/mips/kernel/cps-vec.S
@@ -4,7 +4,8 @@
* Author: Paul Burton <[email protected]>
*/

-#include <asm/addrspace.h>
+#include <spaces.h>
+
#include <asm/asm.h>
#include <asm/asm-offsets.h>
#include <asm/asmmacro.h>
diff --git a/arch/mips/lib/uncached.c b/arch/mips/lib/uncached.c
index 09d5deea747f..5736f3f4c24f 100644
--- a/arch/mips/lib/uncached.c
+++ b/arch/mips/lib/uncached.c
@@ -9,13 +9,11 @@
*/


-#include <asm/addrspace.h>
+#include <spaces.h>
+
#include <asm/bug.h>
#include <asm/cacheflush.h>

-#ifndef CKSEG2
-#define CKSEG2 CKSSEG
-#endif
#ifndef TO_PHYS_MASK
#define TO_PHYS_MASK -1
#endif
--
2.26.0.rc2

2020-04-26 11:53:41

by Jiaxun Yang

[permalink] [raw]
Subject: [PATCH 4/4] MIPS: Loongson64: Enable PCI_IO_VMMAP

Finally we are able to elegantly add I/O ports for PCI host bridge
via devicetree with logic_pio.

To deal with legacy drivers that have fixed I/O ports range we
reserved 0x10000 in PCI_IOBASE, should be enough for i8259 i8042
stuff.

Signed-off-by: Jiaxun Yang <[email protected]>
---
arch/mips/Kconfig | 1 +
arch/mips/include/asm/io.h | 4 ++++
arch/mips/loongson64/init.c | 12 ++++++++----
arch/mips/loongson64/pci.c | 2 +-
4 files changed, 14 insertions(+), 5 deletions(-)

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 4e5308178649..1669735dacd8 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -479,6 +479,7 @@ config MACH_LOONGSON64
select I8259
select IRQ_MIPS_CPU
select NR_CPUS_DEFAULT_64
+ select PCI_IO_VMMAP
select USE_GENERIC_EARLY_PRINTK_8250
select SYS_HAS_CPU_LOONGSON64
select SYS_HAS_EARLY_PRINTK
diff --git a/arch/mips/include/asm/io.h b/arch/mips/include/asm/io.h
index f15ddcd27f35..7f9716c95aa0 100644
--- a/arch/mips/include/asm/io.h
+++ b/arch/mips/include/asm/io.h
@@ -66,6 +66,10 @@
#define PCI_IOBASE ((void __iomem *)PCI_IO_START)
#define IOPORT_RW_BASE PCI_IO_START

+#ifdef CONFIG_MACH_LOONGSON64
+#define MMIO_LOWER_RESERVED 0x10000
+#endif
+
#else

#define IO_SPACE_LIMIT 0xffff
diff --git a/arch/mips/loongson64/init.c b/arch/mips/loongson64/init.c
index da38944471f4..3117edbbea46 100644
--- a/arch/mips/loongson64/init.c
+++ b/arch/mips/loongson64/init.c
@@ -29,10 +29,6 @@ void __init prom_init(void)
fw_init_cmdline();
prom_init_env();

- /* init base address of io space */
- set_io_port_base((unsigned long)
- ioremap(LOONGSON_PCIIO_BASE, LOONGSON_PCIIO_SIZE));
-
prom_init_numa_memory();

/* Hardcode to CPU UART 0 */
@@ -48,5 +44,13 @@ void __init prom_free_prom_memory(void)

void __init arch_init_irq(void)
{
+ /*
+ * i8259 would access I/O space, so mapping must be done here.
+ * Please remove it when all drivers can be managed by logic_pio.
+ */
+ ioremap_page_range(PCI_IO_START, PCI_IO_START + MMIO_LOWER_RESERVED,
+ LOONGSON_PCIIO_BASE,
+ pgprot_device(PAGE_KERNEL));
+
irqchip_init();
}
diff --git a/arch/mips/loongson64/pci.c b/arch/mips/loongson64/pci.c
index a440a2725a20..7aecb88dd377 100644
--- a/arch/mips/loongson64/pci.c
+++ b/arch/mips/loongson64/pci.c
@@ -37,7 +37,7 @@ extern int sbx00_acpi_init(void);
static int __init pcibios_init(void)
{

- loongson_pci_controller.io_map_base = mips_io_port_base;
+ loongson_pci_controller.io_map_base = IOPORT_RW_BASE;
loongson_pci_mem_resource.start = loongson_sysconf.pci_mem_start_addr;
loongson_pci_mem_resource.end = loongson_sysconf.pci_mem_end_addr;

--
2.26.0.rc2

2020-04-26 11:53:56

by Jiaxun Yang

[permalink] [raw]
Subject: [PATCH 3/4] lib: logic_pio: Introduce MMIO_LOWER_RESERVED

That would allow platforms reserve some lower address in PIO MMIO range
to deal with legacy drivers with hardcoded I/O ports that can't be
managed by logic_pio.

Signed-off-by: Jiaxun Yang <[email protected]>
---
lib/logic_pio.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/lib/logic_pio.c b/lib/logic_pio.c
index f511a99bb389..57fff1cb7063 100644
--- a/lib/logic_pio.c
+++ b/lib/logic_pio.c
@@ -20,6 +20,10 @@
static LIST_HEAD(io_range_list);
static DEFINE_MUTEX(io_range_mutex);

+#ifndef MMIO_LOWER_RESERVED
+#define MMIO_LOWER_RESERVED 0
+#endif
+
/* Consider a kernel general helper for this */
#define in_range(b, first, len) ((b) >= (first) && (b) < (first) + (len))

@@ -36,7 +40,7 @@ int logic_pio_register_range(struct logic_pio_hwaddr *new_range)
struct logic_pio_hwaddr *range;
resource_size_t start;
resource_size_t end;
- resource_size_t mmio_end = 0;
+ resource_size_t mmio_end = MMIO_LOWER_RESERVED;
resource_size_t iio_sz = MMIO_UPPER_LIMIT;
int ret = 0;

--
2.26.0.rc2

2020-04-27 10:46:14

by John Garry

[permalink] [raw]
Subject: Re: [PATCH 3/4] lib: logic_pio: Introduce MMIO_LOWER_RESERVED

On 26/04/2020 12:47, Jiaxun Yang wrote:
> That would allow platforms reserve some lower address in PIO MMIO range
> to deal with legacy drivers with hardcoded I/O ports that can't be
> managed by logic_pio.

Hi,

Is there some reason why the logic_pio code cannot be improved to handle
these devices at these "fixed" addresses? Or do you have a plan to
improve it? We already support fixed bus address devices in the INDIRECT
IO region.

Carving out a region of IO space is less than ideal.

Thanks,
John

>
> Signed-off-by: Jiaxun Yang <[email protected]>
> ---
> lib/logic_pio.c | 6 +++++-
> 1 file changed, 5 insertions(+), 1 deletion(-)
>
> diff --git a/lib/logic_pio.c b/lib/logic_pio.c
> index f511a99bb389..57fff1cb7063 100644
> --- a/lib/logic_pio.c
> +++ b/lib/logic_pio.c
> @@ -20,6 +20,10 @@
> static LIST_HEAD(io_range_list);
> static DEFINE_MUTEX(io_range_mutex);
>
> +#ifndef MMIO_LOWER_RESERVED
> +#define MMIO_LOWER_RESERVED 0
> +#endif
> +
> /* Consider a kernel general helper for this */
> #define in_range(b, first, len) ((b) >= (first) && (b) < (first) + (len))
>
> @@ -36,7 +40,7 @@ int logic_pio_register_range(struct logic_pio_hwaddr *new_range)
> struct logic_pio_hwaddr *range;
> resource_size_t start;
> resource_size_t end;
> - resource_size_t mmio_end = 0;
> + resource_size_t mmio_end = MMIO_LOWER_RESERVED;
> resource_size_t iio_sz = MMIO_UPPER_LIMIT;
> int ret = 0;
>
>

2020-04-27 11:07:43

by Jiaxun Yang

[permalink] [raw]
Subject: Re: [PATCH 3/4] lib: logic_pio: Introduce MMIO_LOWER_RESERVED



于 2020年4月27日 GMT+08:00 下午6:43:09, John Garry <[email protected]> 写到:
>On 26/04/2020 12:47, Jiaxun Yang wrote:
>> That would allow platforms reserve some lower address in PIO MMIO range
>> to deal with legacy drivers with hardcoded I/O ports that can't be
>> managed by logic_pio.
>
>Hi,
>
>Is there some reason why the logic_pio code cannot be improved to handle
>these devices at these "fixed" addresses? Or do you have a plan to
>improve it? We already support fixed bus address devices in the INDIRECT
>IO region.

Hi,

The issue about "Fixed Address" is we can't control the ioport
That driver used to operate devices.
So any attempt to resolve it in logic_pio seems impossible.

Currently we have i8259, i8042, piix4_smbus, mc146818 rely on this assumption.

My plan is after getting this part merged, I'm going to work on a ISA Host bridge driver,
then convert device drivers into logic_pio and Devicetree based driver step by step.

Finally when we nologner have any legacy driver, we can safely remove this reserved
range.

Thanks.


>
>Carving out a region of IO space is less than ideal.
>
>Thanks,
>John
>
>>
>> Signed-off-by: Jiaxun Yang <[email protected]>
>> ---
>> lib/logic_pio.c | 6 +++++-
>> 1 file changed, 5 insertions(+), 1 deletion(-)
>>
>> diff --git a/lib/logic_pio.c b/lib/logic_pio.c
>> index f511a99bb389..57fff1cb7063 100644
>> --- a/lib/logic_pio.c
>> +++ b/lib/logic_pio.c
>> @@ -20,6 +20,10 @@
>> static LIST_HEAD(io_range_list);
>> static DEFINE_MUTEX(io_range_mutex);
>>
>> +#ifndef MMIO_LOWER_RESERVED
>> +#define MMIO_LOWER_RESERVED 0
>> +#endif
>> +
>> /* Consider a kernel general helper for this */
>> #define in_range(b, first, len) ((b) >= (first) && (b) < (first) + (len))
>>
>> @@ -36,7 +40,7 @@ int logic_pio_register_range(struct logic_pio_hwaddr *new_range)
>> struct logic_pio_hwaddr *range;
>> resource_size_t start;
>> resource_size_t end;
>> - resource_size_t mmio_end = 0;
>> + resource_size_t mmio_end = MMIO_LOWER_RESERVED;
>> resource_size_t iio_sz = MMIO_UPPER_LIMIT;
>> int ret = 0;
>>
>>
>

--
Jiaxun Yang

2020-04-27 11:57:04

by John Garry

[permalink] [raw]
Subject: Re: [PATCH 3/4] lib: logic_pio: Introduce MMIO_LOWER_RESERVED

On 27/04/2020 12:03, Jiaxun Yang wrote:
>
>
> 于 2020年4月27日 GMT+08:00 下午6:43:09, John Garry <[email protected]> 写到:
>> On 26/04/2020 12:47, Jiaxun Yang wrote:
>>> That would allow platforms reserve some lower address in PIO MMIO range
>>> to deal with legacy drivers with hardcoded I/O ports that can't be
>>> managed by logic_pio.
>>
>> Hi,
>>
>> Is there some reason why the logic_pio code cannot be improved to handle
>> these devices at these "fixed" addresses? Or do you have a plan to
>> improve it? We already support fixed bus address devices in the INDIRECT
>> IO region.
>
> Hi,
>
> The issue about "Fixed Address" is we can't control the ioport
> That driver used to operate devices.
> So any attempt to resolve it in logic_pio seems impossible.
>
> Currently we have i8259, i8042, piix4_smbus, mc146818 rely on this assumption.

Right, and from glancing at a couple of drivers you mentioned, if we
were to register a logic pio region for that legacy region, there does
not seem to be an easy place to fixup to use logic pio addresses (for
those devices). They use hardcoded values. However if all those drivers
were mips specific, you could fixup those drivers to use logic_pio
addresses today through some macro. But not sure on that.

So, going back to your change, I have a dilemma wondering whether you
should still register a logic pio region for the legacy region instead
of the carveout reservation, but ensure it is the first region
registered, such that logic pio address base is 0 and no translation is
required. At least then you have a region registered and it shows in
/proc/ioports, but then this whole thing becomes a bit fragile.

Maybe Arnd or Bjorn have an opinion on this.

Thanks,
John


>
> My plan is after getting this part merged, I'm going to work on a ISA Host bridge driver,
> then convert device drivers into logic_pio and Devicetree based driver step by step.
>
> Finally when we nologner have any legacy driver, we can safely remove this reserved
> range.
>
> Thanks.
>
>
>>
>> Carving out a region of IO space is less than ideal.
>>
>> Thanks,
>> John
>>
>>>
>>> Signed-off-by: Jiaxun Yang <[email protected]>
>>> ---
>>> lib/logic_pio.c | 6 +++++-
>>> 1 file changed, 5 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/lib/logic_pio.c b/lib/logic_pio.c
>>> index f511a99bb389..57fff1cb7063 100644
>>> --- a/lib/logic_pio.c
>>> +++ b/lib/logic_pio.c
>>> @@ -20,6 +20,10 @@
>>> static LIST_HEAD(io_range_list);
>>> static DEFINE_MUTEX(io_range_mutex);
>>>
>>> +#ifndef MMIO_LOWER_RESERVED
>>> +#define MMIO_LOWER_RESERVED 0
>>> +#endif
>>> +
>>> /* Consider a kernel general helper for this */
>>> #define in_range(b, first, len) ((b) >= (first) && (b) < (first) + (len))
>>>
>>> @@ -36,7 +40,7 @@ int logic_pio_register_range(struct logic_pio_hwaddr *new_range)
>>> struct logic_pio_hwaddr *range;
>>> resource_size_t start;
>>> resource_size_t end;
>>> - resource_size_t mmio_end = 0;
>>> + resource_size_t mmio_end = MMIO_LOWER_RESERVED;
>>> resource_size_t iio_sz = MMIO_UPPER_LIMIT;
>>> int ret = 0;
>>>
>>>
>>
>

2020-04-27 12:23:45

by Jiaxun Yang

[permalink] [raw]
Subject: Re: [PATCH 3/4] lib: logic_pio: Introduce MMIO_LOWER_RESERVED

On Mon, 27 Apr 2020 12:54:06 +0100
John Garry <[email protected]> wrote:

> On 27/04/2020 12:03, Jiaxun Yang wrote:
> >
> >
> > 于 2020年4月27日 GMT+08:00 下午6:43:09, John Garry
> > <[email protected]> 写到:
> >> On 26/04/2020 12:47, Jiaxun Yang wrote:
> >>> That would allow platforms reserve some lower address in PIO MMIO
> >>> range to deal with legacy drivers with hardcoded I/O ports that
> >>> can't be managed by logic_pio.
> >>
> >> Hi,
> >>
> >> Is there some reason why the logic_pio code cannot be improved to
> >> handle these devices at these "fixed" addresses? Or do you have a
> >> plan to improve it? We already support fixed bus address devices
> >> in the INDIRECT IO region.
> >
> > Hi,
> >
> > The issue about "Fixed Address" is we can't control the ioport
> > That driver used to operate devices.
> > So any attempt to resolve it in logic_pio seems impossible.
> >
> > Currently we have i8259, i8042, piix4_smbus, mc146818 rely on this
> > assumption.
>
> Right, and from glancing at a couple of drivers you mentioned, if we
> were to register a logic pio region for that legacy region, there
> does not seem to be an easy place to fixup to use logic pio addresses
> (for those devices). They use hardcoded values. However if all those
> drivers were mips specific, you could fixup those drivers to use
> logic_pio addresses today through some macro. But not sure on that.
>

Well, most of these drivers are shared with x86 so....
I guess the conversion needs two or more release cycles.

>
> So, going back to your change, I have a dilemma wondering whether you
> should still register a logic pio region for the legacy region
> instead of the carveout reservation, but ensure it is the first
> region registered, such that logic pio address base is 0 and no
> translation is required. At least then you have a region registered
> and it shows in /proc/ioports, but then this whole thing becomes a
> bit fragile.

Thanks for your solution. So I must register this range as early as
possible. As IRQ is the first subsystem using ISA, I'll do it before
IRQ init, just at the place I setup iormap for reserved region now.

Should be early enough to avoid any collision, as the only logic_pio
user on our system is PCI controller.

Thanks.
>
--
Jiaxun Yang

2020-04-28 02:17:57

by Jiaxun Yang

[permalink] [raw]
Subject: [PATCH v2 0/3] MIPS: Loongson64: Use logic_pio v2

To add I/O ports for PCI host bridge via devicetree, we have to use
logic_pio mechanism.
That would require convert I/O ports into virt memory map.

v2: Register a logic_pio range instead of reserve in logic_pio system.

Jiaxun Yang (3):
MIPS: Massage address spaces headers
MIPS: Introduce PCI_IO_VMMAP
MIPS: Loongson64: Enable PCI_IO_VMMAP

arch/mips/Kconfig | 4 ++
arch/mips/include/asm/addrspace.h | 4 +-
arch/mips/include/asm/io.h | 36 ++++++++++++----
arch/mips/include/asm/mach-generic/spaces.h | 42 ++++++++++++++-----
.../include/asm/mach-loongson64/loongson.h | 2 +
arch/mips/include/asm/page-def.h | 29 +++++++++++++
arch/mips/include/asm/page.h | 21 ----------
arch/mips/include/asm/pgtable-32.h | 2 -
arch/mips/include/asm/pgtable-64.h | 10 +----
arch/mips/include/asm/sync.h | 2 +
arch/mips/kernel/cps-vec.S | 3 +-
arch/mips/kernel/setup.c | 2 +
arch/mips/lib/iomap-pci.c | 2 +-
arch/mips/lib/uncached.c | 6 +--
arch/mips/loongson64/init.c | 34 +++++++++++++--
arch/mips/loongson64/pci.c | 2 +-
16 files changed, 138 insertions(+), 63 deletions(-)
create mode 100644 arch/mips/include/asm/page-def.h

--
2.26.0.rc2

2020-04-28 02:17:58

by Jiaxun Yang

[permalink] [raw]
Subject: [PATCH v2 1/3] MIPS: Massage address spaces headers

That would allow us modify kernel vm address spaces without
step into the hell of includes.

Also use some marcos for address spaces to make spaces.h more
clear.

Signed-off-by: Jiaxun Yang <[email protected]>
---
arch/mips/include/asm/addrspace.h | 4 +--
arch/mips/include/asm/mach-generic/spaces.h | 33 ++++++++++++++-------
arch/mips/include/asm/page-def.h | 29 ++++++++++++++++++
arch/mips/include/asm/page.h | 21 -------------
arch/mips/include/asm/pgtable-32.h | 2 --
arch/mips/include/asm/pgtable-64.h | 10 ++-----
arch/mips/include/asm/sync.h | 2 ++
arch/mips/kernel/cps-vec.S | 3 +-
arch/mips/lib/uncached.c | 6 ++--
9 files changed, 61 insertions(+), 49 deletions(-)
create mode 100644 arch/mips/include/asm/page-def.h

diff --git a/arch/mips/include/asm/addrspace.h b/arch/mips/include/asm/addrspace.h
index 59a48c60a065..4fa8ee48ef02 100644
--- a/arch/mips/include/asm/addrspace.h
+++ b/arch/mips/include/asm/addrspace.h
@@ -10,7 +10,7 @@
#ifndef _ASM_ADDRSPACE_H
#define _ASM_ADDRSPACE_H

-#include <spaces.h>
+#include <linux/const.h>

/*
* Configure language
@@ -67,7 +67,7 @@
#define XKSEG _CONST64_(0xc000000000000000)
#define CKSEG0 _CONST64_(0xffffffff80000000)
#define CKSEG1 _CONST64_(0xffffffffa0000000)
-#define CKSSEG _CONST64_(0xffffffffc0000000)
+#define CKSEG2 _CONST64_(0xffffffffc0000000)
#define CKSEG3 _CONST64_(0xffffffffe0000000)

#define CKSEG0ADDR(a) (CPHYSADDR(a) | CKSEG0)
diff --git a/arch/mips/include/asm/mach-generic/spaces.h b/arch/mips/include/asm/mach-generic/spaces.h
index ee5ebe98f6cf..89162740951a 100644
--- a/arch/mips/include/asm/mach-generic/spaces.h
+++ b/arch/mips/include/asm/mach-generic/spaces.h
@@ -10,9 +10,9 @@
#ifndef _ASM_MACH_GENERIC_SPACES_H
#define _ASM_MACH_GENERIC_SPACES_H

-#include <linux/const.h>
-
+#include <asm/addrspace.h>
#include <asm/mipsregs.h>
+#include <asm/page-def.h>

/*
* This gives the physical RAM offset.
@@ -29,20 +29,20 @@
#ifdef CONFIG_KVM_GUEST
#define CAC_BASE _AC(0x40000000, UL)
#else
-#define CAC_BASE _AC(0x80000000, UL)
+#define CAC_BASE CKSEG0
#endif
#ifndef IO_BASE
-#define IO_BASE _AC(0xa0000000, UL)
+#define IO_BASE CKSEG1
#endif
#ifndef UNCAC_BASE
-#define UNCAC_BASE _AC(0xa0000000, UL)
+#define UNCAC_BASE CKSEG1
#endif

#ifndef MAP_BASE
#ifdef CONFIG_KVM_GUEST
#define MAP_BASE _AC(0x60000000, UL)
#else
-#define MAP_BASE _AC(0xc0000000, UL)
+#define MAP_BASE CKSEG2
#endif
#endif

@@ -58,19 +58,19 @@
#ifdef CONFIG_64BIT

#ifndef CAC_BASE
-#define CAC_BASE PHYS_TO_XKPHYS(read_c0_config() & CONF_CM_CMASK, 0)
+#define CAC_BASE PHYS_TO_XKPHYS(read_c0_config() & CONF_CM_CMASK, 0)
#endif

#ifndef IO_BASE
-#define IO_BASE _AC(0x9000000000000000, UL)
+#define IO_BASE PHYS_TO_XKPHYS(K_CALG_UNCACHED, 0)
#endif

#ifndef UNCAC_BASE
-#define UNCAC_BASE _AC(0x9000000000000000, UL)
+#define UNCAC_BASE PHYS_TO_XKPHYS(K_CALG_UNCACHED, 0)
#endif

#ifndef MAP_BASE
-#define MAP_BASE _AC(0xc000000000000000, UL)
+#define MAP_BASE XKSEG
#endif

/*
@@ -99,8 +99,19 @@
#ifdef CONFIG_KVM_GUEST
#define FIXADDR_TOP ((unsigned long)(long)(int)0x7ffe0000)
#else
-#define FIXADDR_TOP ((unsigned long)(long)(int)0xfffe0000)
+#define FIXADDR_TOP (CKSEG3 + 0x1ffe0000)
+#endif
#endif
+
+#ifdef CONFIG_64BIT
+/*
+ * TLB refill handlers also map the vmalloc area into xuseg. Avoid
+ * the first couple of pages so NULL pointer dereferences will still
+ * reliably trap.
+ */
+#define VMALLOC_START (MAP_BASE + (2 * PAGE_SIZE))
+#else
+#define VMALLOC_START MAP_BASE
#endif

#endif /* __ASM_MACH_GENERIC_SPACES_H */
diff --git a/arch/mips/include/asm/page-def.h b/arch/mips/include/asm/page-def.h
new file mode 100644
index 000000000000..ace4473e7930
--- /dev/null
+++ b/arch/mips/include/asm/page-def.h
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef __ASM_PAGE_DEF_H
+#define __ASM_PAGE_DEF_H
+
+#include <linux/const.h>
+
+/*
+ * PAGE_SHIFT determines the page size
+ */
+#ifdef CONFIG_PAGE_SIZE_4KB
+#define PAGE_SHIFT 12
+#endif
+#ifdef CONFIG_PAGE_SIZE_8KB
+#define PAGE_SHIFT 13
+#endif
+#ifdef CONFIG_PAGE_SIZE_16KB
+#define PAGE_SHIFT 14
+#endif
+#ifdef CONFIG_PAGE_SIZE_32KB
+#define PAGE_SHIFT 15
+#endif
+#ifdef CONFIG_PAGE_SIZE_64KB
+#define PAGE_SHIFT 16
+#endif
+#define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT)
+#define PAGE_MASK (~((1 << PAGE_SHIFT) - 1))
+
+#endif /* __ASM_PAGE_DEF_H */
+
diff --git a/arch/mips/include/asm/page.h b/arch/mips/include/asm/page.h
index e2f503fc7a84..07f6a55eec5d 100644
--- a/arch/mips/include/asm/page.h
+++ b/arch/mips/include/asm/page.h
@@ -14,27 +14,6 @@
#include <linux/kernel.h>
#include <asm/mipsregs.h>

-/*
- * PAGE_SHIFT determines the page size
- */
-#ifdef CONFIG_PAGE_SIZE_4KB
-#define PAGE_SHIFT 12
-#endif
-#ifdef CONFIG_PAGE_SIZE_8KB
-#define PAGE_SHIFT 13
-#endif
-#ifdef CONFIG_PAGE_SIZE_16KB
-#define PAGE_SHIFT 14
-#endif
-#ifdef CONFIG_PAGE_SIZE_32KB
-#define PAGE_SHIFT 15
-#endif
-#ifdef CONFIG_PAGE_SIZE_64KB
-#define PAGE_SHIFT 16
-#endif
-#define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT)
-#define PAGE_MASK (~((1 << PAGE_SHIFT) - 1))
-
/*
* This is used for calculating the real page sizes
* for FTLB or VTLB + FTLB configurations.
diff --git a/arch/mips/include/asm/pgtable-32.h b/arch/mips/include/asm/pgtable-32.h
index 1945c8970141..40049fda596b 100644
--- a/arch/mips/include/asm/pgtable-32.h
+++ b/arch/mips/include/asm/pgtable-32.h
@@ -95,8 +95,6 @@ extern int add_temporary_entry(unsigned long entrylo0, unsigned long entrylo1,
#define USER_PTRS_PER_PGD (0x80000000UL/PGDIR_SIZE)
#define FIRST_USER_ADDRESS 0UL

-#define VMALLOC_START MAP_BASE
-
#define PKMAP_END ((FIXADDR_START) & ~((LAST_PKMAP << PAGE_SHIFT)-1))
#define PKMAP_BASE (PKMAP_END - PAGE_SIZE * LAST_PKMAP)

diff --git a/arch/mips/include/asm/pgtable-64.h b/arch/mips/include/asm/pgtable-64.h
index ee5dc0c145b9..037aec0a14de 100644
--- a/arch/mips/include/asm/pgtable-64.h
+++ b/arch/mips/include/asm/pgtable-64.h
@@ -139,21 +139,15 @@
#define USER_PTRS_PER_PGD ((TASK_SIZE64 / PGDIR_SIZE)?(TASK_SIZE64 / PGDIR_SIZE):1)
#define FIRST_USER_ADDRESS 0UL

-/*
- * TLB refill handlers also map the vmalloc area into xuseg. Avoid
- * the first couple of pages so NULL pointer dereferences will still
- * reliably trap.
- */
-#define VMALLOC_START (MAP_BASE + (2 * PAGE_SIZE))
#define VMALLOC_END \
(MAP_BASE + \
min(PTRS_PER_PGD * PTRS_PER_PUD * PTRS_PER_PMD * PTRS_PER_PTE * PAGE_SIZE, \
(1UL << cpu_vmbits)) - (1UL << 32))

#if defined(CONFIG_MODULES) && defined(KBUILD_64BIT_SYM32) && \
- VMALLOC_START != CKSSEG
+ VMALLOC_START != CKSEG2
/* Load modules into 32bit-compatible segment. */
-#define MODULE_START CKSSEG
+#define MODULE_START CKSEG2
#define MODULE_END (FIXADDR_START-2*PAGE_SIZE)
#endif

diff --git a/arch/mips/include/asm/sync.h b/arch/mips/include/asm/sync.h
index aabd097933fe..8b297255854b 100644
--- a/arch/mips/include/asm/sync.h
+++ b/arch/mips/include/asm/sync.h
@@ -2,6 +2,8 @@
#ifndef __MIPS_ASM_SYNC_H__
#define __MIPS_ASM_SYNC_H__

+#include <linux/stringify.h>
+
/*
* sync types are defined by the MIPS64 Instruction Set documentation in Volume
* II-A of the MIPS Architecture Reference Manual, which can be found here:
diff --git a/arch/mips/kernel/cps-vec.S b/arch/mips/kernel/cps-vec.S
index 4db7ff055c9f..ba5e89825308 100644
--- a/arch/mips/kernel/cps-vec.S
+++ b/arch/mips/kernel/cps-vec.S
@@ -4,7 +4,8 @@
* Author: Paul Burton <[email protected]>
*/

-#include <asm/addrspace.h>
+#include <spaces.h>
+
#include <asm/asm.h>
#include <asm/asm-offsets.h>
#include <asm/asmmacro.h>
diff --git a/arch/mips/lib/uncached.c b/arch/mips/lib/uncached.c
index 09d5deea747f..5736f3f4c24f 100644
--- a/arch/mips/lib/uncached.c
+++ b/arch/mips/lib/uncached.c
@@ -9,13 +9,11 @@
*/


-#include <asm/addrspace.h>
+#include <spaces.h>
+
#include <asm/bug.h>
#include <asm/cacheflush.h>

-#ifndef CKSEG2
-#define CKSEG2 CKSSEG
-#endif
#ifndef TO_PHYS_MASK
#define TO_PHYS_MASK -1
#endif
--
2.26.0.rc2

2020-04-28 02:18:27

by Jiaxun Yang

[permalink] [raw]
Subject: [PATCH v2 2/3] MIPS: Introduce PCI_IO_VMMAP

Define PCI_IOBASE for MIPS at the strat of kernel mapping segment.
That would allow virt address of I/O ports to be dynamicly mapped.
So we'll be able to combine multiple MMIO ranges into I/O ports
and thus we can take advantage of logic_pio mechanism.

Signed-off-by: Jiaxun Yang <[email protected]>
---
arch/mips/Kconfig | 3 ++
arch/mips/include/asm/io.h | 36 ++++++++++++++++-----
arch/mips/include/asm/mach-generic/spaces.h | 13 ++++++--
arch/mips/kernel/setup.c | 2 ++
arch/mips/lib/iomap-pci.c | 2 +-
5 files changed, 45 insertions(+), 11 deletions(-)

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 0519ca9f00f9..4e5308178649 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -3149,6 +3149,9 @@ config PCI_DRIVERS_LEGACY
select NO_GENERIC_PCI_IOPORT_MAP
select PCI_DOMAINS if PCI

+config PCI_IO_VMMAP
+ def_bool n
+
#
# ISA support is now enabled via select. Too many systems still have the one
# or other ISA chip on the board that users don't know about so don't expect
diff --git a/arch/mips/include/asm/io.h b/arch/mips/include/asm/io.h
index 346fffd9e972..f15ddcd27f35 100644
--- a/arch/mips/include/asm/io.h
+++ b/arch/mips/include/asm/io.h
@@ -51,17 +51,36 @@

/* ioswab[bwlq], __mem_ioswab[bwlq] are defined in mangle-port.h */

+/*
+ * On MIPS I/O ports are memory mapped, so we access them using normal
+ * load/store instructions.
+ */
+#ifdef CONFIG_PCI_IO_VMMAP
+/*
+ * I/O port access primitives for dymatic I/O ports mapping.
+ *
+ * We'll create kmap for I/O ports in this space.
+ */
+#define arch_has_dev_port() (1)
+#define IO_SPACE_LIMIT (PCI_IO_SIZE - 1)
+#define PCI_IOBASE ((void __iomem *)PCI_IO_START)
+#define IOPORT_RW_BASE PCI_IO_START
+
+#else
+
#define IO_SPACE_LIMIT 0xffff

/*
- * On MIPS I/O ports are memory mapped, so we access them using normal
- * load/store instructions. mips_io_port_base is the virtual address to
- * which all ports are being mapped. For sake of efficiency some code
- * assumes that this is an address that can be loaded with a single lui
- * instruction, so the lower 16 bits must be zero. Should be true on
- * on any sane architecture; generic code does not use this assumption.
+ * I/O port access primitives for fixed I/O ports mapping.
+ *
+ * mips_io_port_base is the virtual address to which all ports are
+ * being mapped. For sake of efficiency some code assumes that this
+ * is an address that can be loaded with a single lui, instruction, so
+ * the lower 16 bits must be zero. Should be true on on any sane architecture;
+ * generic code does not use this assumption.
*/
extern unsigned long mips_io_port_base;
+#define IOPORT_RW_BASE mips_io_port_base

static inline void set_io_port_base(unsigned long base)
{
@@ -78,6 +97,7 @@ static inline void set_io_port_base(unsigned long base)
#define PIO_OFFSET mips_io_port_base
#define PIO_MASK IO_SPACE_LIMIT
#define PIO_RESERVED 0x0UL
+#endif

/*
* Enforce in-order execution of data I/O. In the MIPS architecture
@@ -308,7 +328,7 @@ static inline void pfx##out##bwlq##p(type val, unsigned long port) \
else \
war_io_reorder_wmb(); \
\
- __addr = (void *)__swizzle_addr_##bwlq(mips_io_port_base + port); \
+ __addr = (void *)__swizzle_addr_##bwlq(IOPORT_RW_BASE + port); \
\
__val = pfx##ioswab##bwlq(__addr, val); \
\
@@ -323,7 +343,7 @@ static inline type pfx##in##bwlq##p(unsigned long port) \
volatile type *__addr; \
type __val; \
\
- __addr = (void *)__swizzle_addr_##bwlq(mips_io_port_base + port); \
+ __addr = (void *)__swizzle_addr_##bwlq(IOPORT_RW_BASE + port); \
\
BUILD_BUG_ON(sizeof(type) > sizeof(unsigned long)); \
\
diff --git a/arch/mips/include/asm/mach-generic/spaces.h b/arch/mips/include/asm/mach-generic/spaces.h
index 89162740951a..a39714c5fd7b 100644
--- a/arch/mips/include/asm/mach-generic/spaces.h
+++ b/arch/mips/include/asm/mach-generic/spaces.h
@@ -103,15 +103,24 @@
#endif
#endif

+#ifdef CONFIG_PCI_IO_VMMAP
+#define PCI_IO_SIZE SZ_16M
+#else
+#define PCI_IO_SIZE 0
+#endif
+
#ifdef CONFIG_64BIT
/*
* TLB refill handlers also map the vmalloc area into xuseg. Avoid
* the first couple of pages so NULL pointer dereferences will still
* reliably trap.
*/
-#define VMALLOC_START (MAP_BASE + (2 * PAGE_SIZE))
+#define PCI_IO_START (MAP_BASE + (2 * PAGE_SIZE))
#else
-#define VMALLOC_START MAP_BASE
+#define PCI_IO_START MAP_BASE
#endif

+#define PCI_IO_END (PCI_IO_START + PCI_IO_SIZE)
+#define VMALLOC_START PCI_IO_END
+
#endif /* __ASM_MACH_GENERIC_SPACES_H */
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index 8db533cd816c..99225539de3c 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -73,12 +73,14 @@ static const char builtin_cmdline[] __initconst = CONFIG_CMDLINE;
static const char builtin_cmdline[] __initconst = "";
#endif

+#ifndef CONFIG_PCI_IO_VMMAP
/*
* mips_io_port_base is the begin of the address space to which x86 style
* I/O ports are mapped.
*/
unsigned long mips_io_port_base = -1;
EXPORT_SYMBOL(mips_io_port_base);
+#endif

static struct resource code_resource = { .name = "Kernel code", };
static struct resource data_resource = { .name = "Kernel data", };
diff --git a/arch/mips/lib/iomap-pci.c b/arch/mips/lib/iomap-pci.c
index 210f5a95ecb1..f28924aaac1d 100644
--- a/arch/mips/lib/iomap-pci.c
+++ b/arch/mips/lib/iomap-pci.c
@@ -27,7 +27,7 @@ void __iomem *__pci_ioport_map(struct pci_dev *dev,
while (bus->parent)
bus = bus->parent;

- ctrl->io_map_base = base = mips_io_port_base;
+ ctrl->io_map_base = base = IOPORT_RW_BASE;

sprintf(name, "%04x:%02x", pci_domain_nr(bus), bus->number);
printk(KERN_WARNING "io_map_base of root PCI bus %s unset. "
--
2.26.0.rc2

2020-04-28 02:21:18

by Jiaxun Yang

[permalink] [raw]
Subject: [PATCH v2 3/3] MIPS: Loongson64: Enable PCI_IO_VMMAP

Finally we are able to elegantly add I/O ports for PCI host bridge
via devicetree with logic_pio.

To deal with legacy drivers that have fixed I/O ports range we
reserved 0x10000 in PCI_IOBASE, should be enough for i8259 i8042
stuff.

Signed-off-by: Jiaxun Yang <[email protected]>
---
arch/mips/Kconfig | 1 +
.../include/asm/mach-loongson64/loongson.h | 2 ++
arch/mips/loongson64/init.c | 34 ++++++++++++++++---
arch/mips/loongson64/pci.c | 2 +-
4 files changed, 34 insertions(+), 5 deletions(-)

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 4e5308178649..1669735dacd8 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -479,6 +479,7 @@ config MACH_LOONGSON64
select I8259
select IRQ_MIPS_CPU
select NR_CPUS_DEFAULT_64
+ select PCI_IO_VMMAP
select USE_GENERIC_EARLY_PRINTK_8250
select SYS_HAS_CPU_LOONGSON64
select SYS_HAS_EARLY_PRINTK
diff --git a/arch/mips/include/asm/mach-loongson64/loongson.h b/arch/mips/include/asm/mach-loongson64/loongson.h
index fde1b75c45ea..94035a47be5b 100644
--- a/arch/mips/include/asm/mach-loongson64/loongson.h
+++ b/arch/mips/include/asm/mach-loongson64/loongson.h
@@ -86,6 +86,8 @@ extern int mach_i8259_irq(void);
#define LOONGSON_PCIIO_SIZE 0x00100000 /* 1M */
#define LOONGSON_PCIIO_TOP (LOONGSON_PCIIO_BASE+LOONGSON_PCIIO_SIZE-1)

+#define MMIO_LOWER_RESERVED 0x10000
+
/* Loongson Register Bases */

#define LOONGSON_PCICONFIGBASE 0x00
diff --git a/arch/mips/loongson64/init.c b/arch/mips/loongson64/init.c
index da38944471f4..4592eb2f78dd 100644
--- a/arch/mips/loongson64/init.c
+++ b/arch/mips/loongson64/init.c
@@ -5,6 +5,7 @@
*/

#include <linux/irqchip.h>
+#include <linux/logic_pio.h>
#include <linux/memblock.h>
#include <asm/bootinfo.h>
#include <asm/traps.h>
@@ -29,10 +30,6 @@ void __init prom_init(void)
fw_init_cmdline();
prom_init_env();

- /* init base address of io space */
- set_io_port_base((unsigned long)
- ioremap(LOONGSON_PCIIO_BASE, LOONGSON_PCIIO_SIZE));
-
prom_init_numa_memory();

/* Hardcode to CPU UART 0 */
@@ -46,7 +43,36 @@ void __init prom_free_prom_memory(void)
{
}

+static __init void reserve_pio_range(void)
+{
+ struct logic_pio_hwaddr *range;
+
+ range = kzalloc(sizeof(*range), GFP_ATOMIC);
+ if (!range)
+ return;
+
+ range->fwnode = &of_root->fwnode;
+ range->size = MMIO_LOWER_RESERVED;
+ range->hw_start = LOONGSON_PCIIO_BASE;
+ range->flags = LOGIC_PIO_CPU_MMIO;
+
+ if (logic_pio_register_range(range)) {
+ pr_err("Failed to reserve PIO range for legacy ISA\n");
+ kfree(range);
+ return;
+ }
+
+ /*
+ * i8259 would access I/O space, so mapping must be done here.
+ * Please remove it when all drivers can be managed by logic_pio.
+ */
+ ioremap_page_range(PCI_IO_START, PCI_IO_START + MMIO_LOWER_RESERVED,
+ LOONGSON_PCIIO_BASE,
+ pgprot_device(PAGE_KERNEL));
+}
+
void __init arch_init_irq(void)
{
+ reserve_pio_range();
irqchip_init();
}
diff --git a/arch/mips/loongson64/pci.c b/arch/mips/loongson64/pci.c
index a440a2725a20..7aecb88dd377 100644
--- a/arch/mips/loongson64/pci.c
+++ b/arch/mips/loongson64/pci.c
@@ -37,7 +37,7 @@ extern int sbx00_acpi_init(void);
static int __init pcibios_init(void)
{

- loongson_pci_controller.io_map_base = mips_io_port_base;
+ loongson_pci_controller.io_map_base = IOPORT_RW_BASE;
loongson_pci_mem_resource.start = loongson_sysconf.pci_mem_start_addr;
loongson_pci_mem_resource.end = loongson_sysconf.pci_mem_end_addr;

--
2.26.0.rc2

2020-04-28 09:30:26

by John Garry

[permalink] [raw]
Subject: Re: [PATCH v2 3/3] MIPS: Loongson64: Enable PCI_IO_VMMAP

On 28/04/2020 03:14, Jiaxun Yang wrote:
> Finally we are able to elegantly add I/O ports for PCI host bridge
> via devicetree with logic_pio.
>
> To deal with legacy drivers that have fixed I/O ports range we
> reserved 0x10000 in PCI_IOBASE, should be enough for i8259 i8042
> stuff.
>
> Signed-off-by: Jiaxun Yang <[email protected]>
> ---
> arch/mips/Kconfig | 1 +
> .../include/asm/mach-loongson64/loongson.h | 2 ++
> arch/mips/loongson64/init.c | 34 ++++++++++++++++---
> arch/mips/loongson64/pci.c | 2 +-
> 4 files changed, 34 insertions(+), 5 deletions(-)
>
> diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
> index 4e5308178649..1669735dacd8 100644
> --- a/arch/mips/Kconfig
> +++ b/arch/mips/Kconfig
> @@ -479,6 +479,7 @@ config MACH_LOONGSON64
> select I8259
> select IRQ_MIPS_CPU
> select NR_CPUS_DEFAULT_64
> + select PCI_IO_VMMAP
> select USE_GENERIC_EARLY_PRINTK_8250
> select SYS_HAS_CPU_LOONGSON64
> select SYS_HAS_EARLY_PRINTK
> diff --git a/arch/mips/include/asm/mach-loongson64/loongson.h b/arch/mips/include/asm/mach-loongson64/loongson.h
> index fde1b75c45ea..94035a47be5b 100644
> --- a/arch/mips/include/asm/mach-loongson64/loongson.h
> +++ b/arch/mips/include/asm/mach-loongson64/loongson.h
> @@ -86,6 +86,8 @@ extern int mach_i8259_irq(void);
> #define LOONGSON_PCIIO_SIZE 0x00100000 /* 1M */
> #define LOONGSON_PCIIO_TOP (LOONGSON_PCIIO_BASE+LOONGSON_PCIIO_SIZE-1)
>
> +#define MMIO_LOWER_RESERVED 0x10000
> +
> /* Loongson Register Bases */
>
> #define LOONGSON_PCICONFIGBASE 0x00
> diff --git a/arch/mips/loongson64/init.c b/arch/mips/loongson64/init.c
> index da38944471f4..4592eb2f78dd 100644
> --- a/arch/mips/loongson64/init.c
> +++ b/arch/mips/loongson64/init.c
> @@ -5,6 +5,7 @@
> */
>
> #include <linux/irqchip.h>
> +#include <linux/logic_pio.h>
> #include <linux/memblock.h>
> #include <asm/bootinfo.h>
> #include <asm/traps.h>
> @@ -29,10 +30,6 @@ void __init prom_init(void)
> fw_init_cmdline();
> prom_init_env();
>
> - /* init base address of io space */
> - set_io_port_base((unsigned long)
> - ioremap(LOONGSON_PCIIO_BASE, LOONGSON_PCIIO_SIZE));
> -
> prom_init_numa_memory();
>
> /* Hardcode to CPU UART 0 */
> @@ -46,7 +43,36 @@ void __init prom_free_prom_memory(void)
> {
> }
>
> +static __init void reserve_pio_range(void)
> +{
> + struct logic_pio_hwaddr *range;
> +
> + range = kzalloc(sizeof(*range), GFP_ATOMIC);
> + if (!range)
> + return;
> +
> + range->fwnode = &of_root->fwnode;
> + range->size = MMIO_LOWER_RESERVED;
> + range->hw_start = LOONGSON_PCIIO_BASE;
> + range->flags = LOGIC_PIO_CPU_MMIO;
> +
> + if (logic_pio_register_range(range)) {
> + pr_err("Failed to reserve PIO range for legacy ISA\n");
> + kfree(range);
> + return;
> + }

I think that you should also check the range->io_start == 0 is returned
here, as your code relies on that.

And I would also like to reiterate that this is somewhat fragile and
relies on ordering. But I feel better than modifying common code. And I
agree that the right thing to do is take care of the logic pio
translations for your drivers now, as you mention, below.

Thanks,
John

> +
> + /*
> + * i8259 would access I/O space, so mapping must be done here.
> + * Please remove it when all drivers can be managed by logic_pio.
> + */
> + ioremap_page_range(PCI_IO_START, PCI_IO_START + MMIO_LOWER_RESERVED,
> + LOONGSON_PCIIO_BASE,
> + pgprot_device(PAGE_KERNEL));
> +}
> +
> void __init arch_init_irq(void)
> {
> + reserve_pio_range();
> irqchip_init();
> }
> diff --git a/arch/mips/loongson64/pci.c b/arch/mips/loongson64/pci.c
> index a440a2725a20..7aecb88dd377 100644
> --- a/arch/mips/loongson64/pci.c
> +++ b/arch/mips/loongson64/pci.c
> @@ -37,7 +37,7 @@ extern int sbx00_acpi_init(void);
> static int __init pcibios_init(void)
> {
>
> - loongson_pci_controller.io_map_base = mips_io_port_base;
> + loongson_pci_controller.io_map_base = IOPORT_RW_BASE;
> loongson_pci_mem_resource.start = loongson_sysconf.pci_mem_start_addr;
> loongson_pci_mem_resource.end = loongson_sysconf.pci_mem_end_addr;
>
>

2020-04-28 11:38:39

by Thomas Bogendoerfer

[permalink] [raw]
Subject: Re: [PATCH v2 1/3] MIPS: Massage address spaces headers

On Tue, Apr 28, 2020 at 10:14:12AM +0800, Jiaxun Yang wrote:
> That would allow us modify kernel vm address spaces without
> step into the hell of includes.
>
> Also use some marcos for address spaces to make spaces.h more
> clear.
>
> Signed-off-by: Jiaxun Yang <[email protected]>

I don't like this patch as I can't see a good reason for shuffling
stuff arround. Can you drop this from this series ?

Thomas.

--
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea. [ RFC1925, 2.3 ]

2020-04-28 11:49:28

by Jiaxun Yang

[permalink] [raw]
Subject: Re: [PATCH v2 1/3] MIPS: Massage address spaces headers



于 2020年4月28日 GMT+08:00 下午7:33:26, Thomas Bogendoerfer <[email protected]> 写到:
>On Tue, Apr 28, 2020 at 10:14:12AM +0800, Jiaxun Yang wrote:
>> That would allow us modify kernel vm address spaces without
>> step into the hell of includes.
>>
>> Also use some marcos for address spaces to make spaces.h more
>> clear.
>>
>> Signed-off-by: Jiaxun Yang <[email protected]>
>
>I don't like this patch as I can't see a good reason for shuffling
>stuff arround. Can you drop this from this series ?

The problem is without this patch we'll have to include pgtable-32.h and
pgtable-64.h into asm/io.h, and that will become totally hell.

Thanks.

>
>Thomas.
>

--
Jiaxun Yang

2020-04-29 18:35:49

by Thomas Bogendoerfer

[permalink] [raw]
Subject: Re: [PATCH v2 1/3] MIPS: Massage address spaces headers

On Tue, Apr 28, 2020 at 07:45:19PM +0800, Jiaxun Yang wrote:
>
>
> 于 2020年4月28日 GMT+08:00 下午7:33:26, Thomas Bogendoerfer <[email protected]> 写到:
> >On Tue, Apr 28, 2020 at 10:14:12AM +0800, Jiaxun Yang wrote:
> >> That would allow us modify kernel vm address spaces without
> >> step into the hell of includes.
> >>
> >> Also use some marcos for address spaces to make spaces.h more
> >> clear.
> >>
> >> Signed-off-by: Jiaxun Yang <[email protected]>
> >
> >I don't like this patch as I can't see a good reason for shuffling
> >stuff arround. Can you drop this from this series ?
>
> The problem is without this patch we'll have to include pgtable-32.h and
> pgtable-64.h into asm/io.h, and that will become totally hell.

sure, but this would just mean moving VMALLOC_START, but not the other
stuff in this patch, which is more what I dislike...

Thomas.

--
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea. [ RFC1925, 2.3 ]