[U-Boot] [PATCH v2 0/4] Malta MIPS64 support

This series allows MIPS64 builds for Malta boards, which can be used either on real Malta boards with a MIPS64 CPU or in QEMU. It prepares by fixing some 64 bit safety issues that affect the ethernet driver, then allows the builds for the Malta board.
This series applies atop u-boot-mips/next as of 4349b55b9953.
Paul Burton (4): MIPS: Use CPHYSADDR to implement mips32 virt_to_phys net: pcnet: Stop converting kseg1->kseg0 addresses net: pcnet: Make 64 bit safe malta: Allow MIPS64 builds
arch/mips/Kconfig | 3 +++ arch/mips/include/asm/io.h | 5 +---- board/imgtec/malta/Kconfig | 3 ++- board/imgtec/malta/lowlevel_init.S | 13 +++++++------ drivers/net/pcnet.c | 33 ++++++++++++++++----------------- include/configs/malta.h | 18 +++++++++++++----- 6 files changed, 42 insertions(+), 33 deletions(-)

Use CPHYSADDR to implement the virt_to_phys function for converting from a virtual to a physical address for MIPS32, much as is already done for MIPS64. This allows for virt_to_phys to work regardless of whether the address being translated is in kseg0 or kseg1, unlike the previous subtraction based approach which only worked for addresses in kseg0. This allows for drivers to provide an address to virt_to_phys without needing to manually ensure that kseg1 addresses are converted to equivalent kseg0 addresses first.
This patch is equivalent to this Linux patch currently waiting to be reviewed & merged:
https://patchwork.linux-mips.org/patch/12564/
Signed-off-by: Paul Burton paul.burton@imgtec.com
---
Changes in v2: - New patch.
arch/mips/include/asm/io.h | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/arch/mips/include/asm/io.h b/arch/mips/include/asm/io.h index 723a60a..5b86386 100644 --- a/arch/mips/include/asm/io.h +++ b/arch/mips/include/asm/io.h @@ -92,11 +92,8 @@ static inline unsigned long virt_to_phys(volatile const void *address) #ifdef CONFIG_64BIT if (addr < CKSEG0) return XPHYSADDR(addr); - - return CPHYSADDR(addr); -#else - return addr - PAGE_OFFSET + PHYS_OFFSET; #endif + return CPHYSADDR(addr); }
/*

Am 26.05.2016 um 15:49 schrieb Paul Burton:
Use CPHYSADDR to implement the virt_to_phys function for converting from a virtual to a physical address for MIPS32, much as is already done for MIPS64. This allows for virt_to_phys to work regardless of whether the address being translated is in kseg0 or kseg1, unlike the previous subtraction based approach which only worked for addresses in kseg0. This allows for drivers to provide an address to virt_to_phys without needing to manually ensure that kseg1 addresses are converted to equivalent kseg0 addresses first.
This patch is equivalent to this Linux patch currently waiting to be reviewed & merged:
https://patchwork.linux-mips.org/patch/12564/
Signed-off-by: Paul Burton paul.burton@imgtec.com
Changes in v2:
- New patch.
arch/mips/include/asm/io.h | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-)
applied to u-boot-mips, thanks.

Now that MIPS virt_to_phys can handle kseg1 addresses on MIPS32, stop manually converting addresses to their kseg0 equivalents in the pcnet driver.
Signed-off-by: Paul Burton paul.burton@imgtec.com
---
Changes in v2: - New patch.
drivers/net/pcnet.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-)
diff --git a/drivers/net/pcnet.c b/drivers/net/pcnet.c index 16a7512..efa4afb 100644 --- a/drivers/net/pcnet.c +++ b/drivers/net/pcnet.c @@ -135,14 +135,11 @@ static void pcnet_halt (struct eth_device *dev); static int pcnet_probe (struct eth_device *dev, bd_t * bis, int dev_num);
static inline pci_addr_t pcnet_virt_to_mem(const struct eth_device *dev, - void *addr, bool uncached) + void *addr) { pci_dev_t devbusfn = (pci_dev_t)dev->priv; void *virt_addr = addr;
- if (uncached) - virt_addr = (void *)CKSEG0ADDR(addr); - return pci_virt_to_mem(devbusfn, virt_addr); }
@@ -361,7 +358,7 @@ static int pcnet_init(struct eth_device *dev, bd_t *bis) */ lp->cur_rx = 0; for (i = 0; i < RX_RING_SIZE; i++) { - addr = pcnet_virt_to_mem(dev, (*lp->rx_buf)[i], false); + addr = pcnet_virt_to_mem(dev, (*lp->rx_buf)[i]); uc->rx_ring[i].base = cpu_to_le32(addr); uc->rx_ring[i].buf_length = cpu_to_le16(-PKT_BUF_SZ); uc->rx_ring[i].status = cpu_to_le16(0x8000); @@ -393,9 +390,9 @@ static int pcnet_init(struct eth_device *dev, bd_t *bis)
uc->init_block.tlen_rlen = cpu_to_le16(TX_RING_LEN_BITS | RX_RING_LEN_BITS); - addr = pcnet_virt_to_mem(dev, uc->rx_ring, true); + addr = pcnet_virt_to_mem(dev, uc->rx_ring); uc->init_block.rx_ring = cpu_to_le32(addr); - addr = pcnet_virt_to_mem(dev, uc->tx_ring, true); + addr = pcnet_virt_to_mem(dev, uc->tx_ring); uc->init_block.tx_ring = cpu_to_le32(addr);
PCNET_DEBUG1("\ntlen_rlen=0x%x rx_ring=0x%x tx_ring=0x%x\n", @@ -406,7 +403,7 @@ static int pcnet_init(struct eth_device *dev, bd_t *bis) * Tell the controller where the Init Block is located. */ barrier(); - addr = pcnet_virt_to_mem(dev, &lp->uc->init_block, true); + addr = pcnet_virt_to_mem(dev, &lp->uc->init_block); pcnet_write_csr(dev, 1, addr & 0xffff); pcnet_write_csr(dev, 2, (addr >> 16) & 0xffff);
@@ -464,7 +461,7 @@ static int pcnet_send(struct eth_device *dev, void *packet, int pkt_len) * Setup Tx ring. Caution: the write order is important here, * set the status with the "ownership" bits last. */ - addr = pcnet_virt_to_mem(dev, packet, false); + addr = pcnet_virt_to_mem(dev, packet); writew(-pkt_len, &entry->length); writel(0, &entry->misc); writel(addr, &entry->base);

Am 26.05.2016 um 15:49 schrieb Paul Burton:
Now that MIPS virt_to_phys can handle kseg1 addresses on MIPS32, stop manually converting addresses to their kseg0 equivalents in the pcnet driver.
Signed-off-by: Paul Burton paul.burton@imgtec.com
Changes in v2:
- New patch.
drivers/net/pcnet.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-)
applied to u-boot-mips, thanks.

Fix the pcnet driver to build safely on 64 bit platforms, in preparation for allowing MIPS64 builds for Malta boards.
Signed-off-by: Paul Burton paul.burton@imgtec.com ---
Changes in v2: None
drivers/net/pcnet.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-)
diff --git a/drivers/net/pcnet.c b/drivers/net/pcnet.c index efa4afb..d1fd4e4 100644 --- a/drivers/net/pcnet.c +++ b/drivers/net/pcnet.c @@ -137,7 +137,7 @@ static int pcnet_probe (struct eth_device *dev, bd_t * bis, int dev_num); static inline pci_addr_t pcnet_virt_to_mem(const struct eth_device *dev, void *addr) { - pci_dev_t devbusfn = (pci_dev_t)dev->priv; + pci_dev_t devbusfn = (pci_dev_t)(unsigned long)dev->priv; void *virt_addr = addr;
return pci_virt_to_mem(devbusfn, virt_addr); @@ -176,7 +176,7 @@ int pcnet_initialize(bd_t *bis) break; } memset(dev, 0, sizeof(*dev)); - dev->priv = (void *)devbusfn; + dev->priv = (void *)(unsigned long)devbusfn; sprintf(dev->name, "pcnet#%d", dev_nr);
/* @@ -187,8 +187,8 @@ int pcnet_initialize(bd_t *bis) dev->iobase = pci_io_to_phys(devbusfn, dev->iobase); dev->iobase &= ~0xf;
- PCNET_DEBUG1("%s: devbusfn=0x%x iobase=0x%x: ", - dev->name, devbusfn, dev->iobase); + PCNET_DEBUG1("%s: devbusfn=0x%x iobase=0x%lx: ", + dev->name, devbusfn, (unsigned long)dev->iobase);
command = PCI_COMMAND_IO | PCI_COMMAND_MASTER; pci_write_config_word(devbusfn, PCI_COMMAND, command); @@ -295,7 +295,7 @@ static int pcnet_init(struct eth_device *dev, bd_t *bis) { struct pcnet_uncached_priv *uc; int i, val; - u32 addr; + unsigned long addr;
PCNET_DEBUG1("%s: pcnet_init...\n", dev->name);
@@ -333,16 +333,18 @@ static int pcnet_init(struct eth_device *dev, bd_t *bis) * must be aligned on 16-byte boundaries. */ if (lp == NULL) { - addr = (u32)malloc(sizeof(pcnet_priv_t) + 0x10); + addr = (unsigned long)malloc(sizeof(pcnet_priv_t) + 0x10); addr = (addr + 0xf) & ~0xf; lp = (pcnet_priv_t *)addr;
- addr = (u32)memalign(ARCH_DMA_MINALIGN, sizeof(*lp->uc)); + addr = (unsigned long)memalign(ARCH_DMA_MINALIGN, + sizeof(*lp->uc)); flush_dcache_range(addr, addr + sizeof(*lp->uc)); addr = UNCACHED_SDRAM(addr); lp->uc = (struct pcnet_uncached_priv *)addr;
- addr = (u32)memalign(ARCH_DMA_MINALIGN, sizeof(*lp->rx_buf)); + addr = (unsigned long)memalign(ARCH_DMA_MINALIGN, + sizeof(*lp->rx_buf)); flush_dcache_range(addr, addr + sizeof(*lp->rx_buf)); lp->rx_buf = (void *)addr; }

Am 26.05.2016 um 15:49 schrieb Paul Burton:
Fix the pcnet driver to build safely on 64 bit platforms, in preparation for allowing MIPS64 builds for Malta boards.
Signed-off-by: Paul Burton paul.burton@imgtec.com
Changes in v2: None
drivers/net/pcnet.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-)
applied to u-boot-mips, thanks.

Both real Malta boards & emulators that mimic Malta (eg. QEMU) can support MIPS64 CPUs. Allow MIPS64 builds of U-Boot for such boards, which enables the user to make use of the whole 64 bit address space.
Signed-off-by: Paul Burton paul.burton@imgtec.com ---
Changes in v2: None
arch/mips/Kconfig | 3 +++ board/imgtec/malta/Kconfig | 3 ++- board/imgtec/malta/lowlevel_init.S | 13 +++++++------ include/configs/malta.h | 18 +++++++++++++----- 4 files changed, 25 insertions(+), 12 deletions(-)
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 53363e3..abaeaf0 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -33,6 +33,9 @@ config TARGET_MALTA select SUPPORTS_CPU_MIPS32_R1 select SUPPORTS_CPU_MIPS32_R2 select SUPPORTS_CPU_MIPS32_R6 + select SUPPORTS_CPU_MIPS64_R1 + select SUPPORTS_CPU_MIPS64_R2 + select SUPPORTS_CPU_MIPS64_R6 select SWAP_IO_SPACE select MIPS_L1_CACHE_SHIFT_6
diff --git a/board/imgtec/malta/Kconfig b/board/imgtec/malta/Kconfig index 2bb8e8b..98eb4d1 100644 --- a/board/imgtec/malta/Kconfig +++ b/board/imgtec/malta/Kconfig @@ -10,6 +10,7 @@ config SYS_CONFIG_NAME default "malta"
config SYS_TEXT_BASE - default 0xbe000000 + default 0xbe000000 if 32BIT + default 0xffffffffbe000000 if 64BIT
endif diff --git a/board/imgtec/malta/lowlevel_init.S b/board/imgtec/malta/lowlevel_init.S index 534db1d..3d48cdc 100644 --- a/board/imgtec/malta/lowlevel_init.S +++ b/board/imgtec/malta/lowlevel_init.S @@ -10,6 +10,7 @@ #include <pci.h>
#include <asm/addrspace.h> +#include <asm/asm.h> #include <asm/regdef.h> #include <asm/malta.h> #include <asm/mipsregs.h> @@ -34,7 +35,7 @@ lowlevel_init: mtc0 t0, CP0_CONFIG, 2
/* detect the core card */ - li t0, KSEG1ADDR(MALTA_REVISION) + PTR_LI t0, CKSEG1ADDR(MALTA_REVISION) lw t0, 0(t0) srl t0, t0, MALTA_REVISION_CORID_SHF andi t0, t0, (MALTA_REVISION_CORID_MSK >> \ @@ -68,12 +69,12 @@ lowlevel_init: */ _gt64120: /* move GT64120 registers from 0x14000000 to 0x1be00000 */ - li t1, KSEG1ADDR(GT_DEF_BASE) + PTR_LI t1, CKSEG1ADDR(GT_DEF_BASE) li t0, CPU_TO_GT32(0xdf000000) sw t0, GT_ISD_OFS(t1)
/* setup MEM-to-PCI0 mapping */ - li t1, KSEG1ADDR(MALTA_GT_BASE) + PTR_LI t1, CKSEG1ADDR(MALTA_GT_BASE)
/* setup PCI0 io window to 0x18000000-0x181fffff */ li t0, CPU_TO_GT32(0xc0000000) @@ -100,7 +101,7 @@ _gt64120: */ _msc01: /* setup peripheral bus controller clock divide */ - li t0, KSEG1ADDR(MALTA_MSC01_PBC_BASE) + PTR_LI t0, CKSEG1ADDR(MALTA_MSC01_PBC_BASE) li t1, 0x1 << MSC01_PBC_CLKCFG_SHF sw t1, MSC01_PBC_CLKCFG_OFS(t0)
@@ -122,7 +123,7 @@ _msc01: sw t1, MSC01_PBC_CS0CFG_OFS(t0)
/* setup basic address decode */ - li t0, KSEG1ADDR(MALTA_MSC01_BIU_BASE) + PTR_LI t0, CKSEG1ADDR(MALTA_MSC01_BIU_BASE) li t1, 0x0 li t2, -CONFIG_SYS_MEM_SIZE sw t1, MSC01_BIU_MCBAS1L_OFS(t0) @@ -157,7 +158,7 @@ _msc01: sw t2, MSC01_BIU_IP3MSK2L_OFS(t0)
/* setup PCI memory */ - li t0, KSEG1ADDR(MALTA_MSC01_PCI_BASE) + PTR_LI t0, CKSEG1ADDR(MALTA_MSC01_PCI_BASE) li t1, MALTA_MSC01_PCIMEM_BASE li t2, (-MALTA_MSC01_PCIMEM_SIZE) & MSC01_PCI_SC2PMMSKL_MSK_MSK li t3, MALTA_MSC01_PCIMEM_MAP diff --git a/include/configs/malta.h b/include/configs/malta.h index a369678..fc4baba 100644 --- a/include/configs/malta.h +++ b/include/configs/malta.h @@ -39,14 +39,18 @@ */ #define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE
-#define CONFIG_SYS_SDRAM_BASE 0x80000000 /* Cached addr */ +#ifdef CONFIG_64BIT +# define CONFIG_SYS_SDRAM_BASE 0xffffffff80000000 +#else +# define CONFIG_SYS_SDRAM_BASE 0x80000000 +#endif #define CONFIG_SYS_MEM_SIZE (256 * 1024 * 1024)
#define CONFIG_SYS_INIT_SP_OFFSET 0x400000
-#define CONFIG_SYS_LOAD_ADDR 0x81000000 -#define CONFIG_SYS_MEMTEST_START 0x80100000 -#define CONFIG_SYS_MEMTEST_END 0x80800000 +#define CONFIG_SYS_LOAD_ADDR (CONFIG_SYS_SDRAM_BASE + 0x01000000) +#define CONFIG_SYS_MEMTEST_START (CONFIG_SYS_SDRAM_BASE + 0x00100000) +#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_SDRAM_BASE + 0x00800000)
#define CONFIG_SYS_MALLOC_LEN (128 * 1024) #define CONFIG_SYS_BOOTPARAMS_LEN (128 * 1024) @@ -69,7 +73,11 @@ /* * Flash configuration */ -#define CONFIG_SYS_FLASH_BASE 0xbe000000 +#ifdef CONFIG_64BIT +# define CONFIG_SYS_FLASH_BASE 0xffffffffbe000000 +#else +# define CONFIG_SYS_FLASH_BASE 0xbe000000 +#endif #define CONFIG_SYS_MAX_FLASH_BANKS 1 #define CONFIG_SYS_MAX_FLASH_SECT 128 #define CONFIG_SYS_FLASH_CFI

Am 26.05.2016 um 15:49 schrieb Paul Burton:
Both real Malta boards & emulators that mimic Malta (eg. QEMU) can support MIPS64 CPUs. Allow MIPS64 builds of U-Boot for such boards, which enables the user to make use of the whole 64 bit address space.
Signed-off-by: Paul Burton paul.burton@imgtec.com
Changes in v2: None
arch/mips/Kconfig | 3 +++ board/imgtec/malta/Kconfig | 3 ++- board/imgtec/malta/lowlevel_init.S | 13 +++++++------ include/configs/malta.h | 18 +++++++++++++----- 4 files changed, 25 insertions(+), 12 deletions(-)
applied to u-boot-mips, thanks.
participants (2)
-
Daniel Schwierzeck
-
Paul Burton