[PATCH 0/1] MIPS: fix optimised memset returning garbage
There is currently a bug in memset implementation from arch/mips/lib/memset.S that is used when MIPS_OPTIMIZED_STRING_FUNCTIONS option is enabled. It stems from a missing '.set noreorder' directive before the first branch. This results in an assembler stuffing a 'nop' instruction in a delay slot instead of an instruction writing the return value into v0 register that was supposed to go there. That leads to an error that appears when reading memory from SPI Flash and that was mentioned here: http://lists.infradead.org/pipermail/barebox/2021-June/036557.html. There are a few ways of fixing this bug. The directive '.set noreorder' that shows up a bit later in code could be moved up and placed right before the memset label (as it was originally in Linux codebase - see a583158c9ce822c96a718fbf877cec1e5f9ad75d). Or, rather, the move and the branch instruction could be swapped, thus allowing the assembler to properly place move in delay slot (as it is done in Linux now - see 68dec269ee29c3abfd09596fbee7e40d875a6ab3) - that is what is done in patch. Denis Orlov (1): MIPS: fix optimised memset returning garbage arch/mips/lib/memset.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) -- 2.20.1 ___ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox
[PATCH 1/1] MIPS: fix optimised memset returning garbage
There is a subtle bug in arch/mips/lib/memset.S, which results in not writing the correct return value into v0 register if the value to fill memory with is 0. Signed-off-by: Denis Orlov --- arch/mips/lib/memset.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/lib/memset.S b/arch/mips/lib/memset.S index 0b81bd7d8d..cd4e4ccfe8 100644 --- a/arch/mips/lib/memset.S +++ b/arch/mips/lib/memset.S @@ -34,8 +34,8 @@ */ LEAF(memset) - beqza1, 1f movev0, a0 /* result */ + beqza1, 1f andia1, 0xff/* spread fillword */ LONG_SLLt1, a1, 8 -- 2.20.1 ___ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox
[PATCH v2] MIPS: fix optimised memset returning garbage
There is a subtle bug in arch/mips/lib/memset.S, used if option MIPS_OPTIMIZED_STRING_FUNCTIONS is enabled, which results in not writing the correct return value into v0 register if the value to fill memory with is 0. The bug stems from a missing '.set noreorder' directive before the first beqz instruction. This results in an assembler stuffing a 'nop' instruction in the beqz delay slot instead of an instruction writing the return value into v0 register that was supposed to go there. That leads to an error that appears when reading memory from SPI Flash and that was mentioned here: http://lists.infradead.org/pipermail/barebox/2021-June/036557.html There are a few ways of fixing this bug. The directive '.set noreorder' that shows up a bit later in code could be moved up and placed right before the memset label (as it was originally in Linux codebase - see a583158c9ce822c96a718fbf877cec1e5f9ad75d). Or, rather, the move and the branch instruction could be swapped, thus allowing the assembler to properly place move in delay slot (as it is done in Linux now - see 68dec269ee29c3abfd09596fbee7e40d875a6ab3) - that is what is done in this patch. Signed-off-by: Denis Orlov --- arch/mips/lib/memset.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/lib/memset.S b/arch/mips/lib/memset.S index 0b81bd7d8d..cd4e4ccfe8 100644 --- a/arch/mips/lib/memset.S +++ b/arch/mips/lib/memset.S @@ -34,8 +34,8 @@ */ LEAF(memset) - beqza1, 1f movev0, a0 /* result */ + beqza1, 1f andia1, 0xff/* spread fillword */ LONG_SLLt1, a1, 8 -- 2.20.1 ___ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox
[PATCH 2/2] usb: host: ehci: reorder code in ehci_probe()
Currently, after successful memory region requests the driver initialization could still fail, leaving those regions allocated. By reordering the code those requests can be placed later, after the possibly failing calls. Signed-off-by: Denis Orlov --- drivers/usb/host/ehci-hcd.c | 28 ++-- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index facfb3a95b..068504557b 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -1421,20 +1421,6 @@ static int ehci_probe(struct device_d *dev) */ data.flags = EHCI_HAS_TT; - iores = dev_request_mem_resource(dev, 0); - if (IS_ERR(iores)) - return PTR_ERR(iores); - data.hccr = IOMEM(iores->start); - - if (dev->num_resources > 1) { - iores = dev_request_mem_resource(dev, 1); - if (IS_ERR(iores)) - return PTR_ERR(iores); - data.hcor = IOMEM(iores->start); - } - else - data.hcor = NULL; - usb2_generic_phy = phy_optional_get(dev, "usb"); if (IS_ERR(usb2_generic_phy)) return PTR_ERR(usb2_generic_phy); @@ -1456,6 +1442,20 @@ static int ehci_probe(struct device_d *dev) if (ret) return ret; + iores = dev_request_mem_resource(dev, 0); + if (IS_ERR(iores)) + return PTR_ERR(iores); + data.hccr = IOMEM(iores->start); + + if (dev->num_resources > 1) { + iores = dev_request_mem_resource(dev, 1); + if (IS_ERR(iores)) + return PTR_ERR(iores); + data.hcor = IOMEM(iores->start); + } + else + data.hcor = NULL; + ehci = ehci_register(dev, ); if (IS_ERR(ehci)) return PTR_ERR(ehci); -- 2.20.1 ___ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox
[PATCH 1/2] usb: host: ehci: add GENERIC_PHY dependency to Kconfig
With GENERIC_PHY disabled, EHCI driver initialization fails in ehci_probe() as calling phy_optional_get() returns "Function not implemented" value. So it seems reasonable to make USB_EHCI explicitly depend on GENERIC_PHY. Signed-off-by: Denis Orlov --- drivers/usb/host/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index d38b4dcac4..cc71b76902 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -2,6 +2,7 @@ config USB_EHCI bool "EHCI driver" depends on HAS_DMA + depends on GENERIC_PHY config USB_EHCI_OMAP depends on ARCH_OMAP3 -- 2.20.1 ___ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox
[PATCH] ata: ide-sff: fix integer overflow in ata_wait_busy()
Signed-off-by: Denis Orlov --- drivers/ata/ide-sff.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ata/ide-sff.c b/drivers/ata/ide-sff.c index 7884b62bab..69055e0585 100644 --- a/drivers/ata/ide-sff.c +++ b/drivers/ata/ide-sff.c @@ -96,7 +96,7 @@ static int ata_wait_busy(struct ide_port *ide, unsigned timeout) { uint8_t status; uint64_t start = get_time_ns(); - uint64_t toffs = timeout * 1000 * 1000; + uint64_t toffs = timeout * MSECOND; do { status = ata_rd_status(ide); -- 2.20.1 ___ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox
[PATCH] ata: disk_ata_drive: clean up code in ata_dump_id()
Add missing macros and fix misspellings. Signed-off-by: Denis Orlov --- drivers/ata/disk_ata_drive.c | 23 +-- include/ata_drive.h | 5 + 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/drivers/ata/disk_ata_drive.c b/drivers/ata/disk_ata_drive.c index f36e06328c..7df0879b19 100644 --- a/drivers/ata/disk_ata_drive.c +++ b/drivers/ata/disk_ata_drive.c @@ -80,9 +80,9 @@ static void __maybe_unused ata_dump_id(uint16_t *id) ata_id_c_string(id, product, ATA_ID_PROD, sizeof(product)); printf("Product model number: %s\n\r", product); - /* Total sectors of device */ + /* Total sectors of device */ n_sectors = ata_id_n_sectors(id); - printf("Capablity: %lld sectors\n\r", n_sectors); + printf("Capacity: %lld sectors\n\r", n_sectors); printf ("id[49]: capabilities = 0x%04x\n" "id[53]: field valid = 0x%04x\n" @@ -95,12 +95,14 @@ static void __maybe_unused ata_dump_id(uint16_t *id) id[ATA_ID_PIO_MODES], id[ATA_ID_QUEUE_DEPTH]); - printf ("id[76]: sata capablity = 0x%04x\n" + printf ("id[76]: sata capabilities 1 = 0x%04x\n" + "id[77]: sata capabilities 2 = 0x%04x\n" "id[78]: sata features supported = 0x%04x\n" - "id[79]: sata features enable = 0x%04x\n", - id[76], /* FIXME */ - id[78], /* FIXME */ - id[79]); /* FIXME */ + "id[79]: sata features enabled = 0x%04x\n", + id[ATA_ID_SATA_CAPAB_1], + id[ATA_ID_SATA_CAPAB_2], + id[ATA_ID_SATA_FEAT_SUPP], + id[ATA_ID_SATA_FEAT_ENABLE]); printf ("id[80]: major version = 0x%04x\n" "id[81]: minor version = 0x%04x\n" @@ -108,12 +110,13 @@ static void __maybe_unused ata_dump_id(uint16_t *id) "id[83]: command set supported 2 = 0x%04x\n" "id[84]: command set extension = 0x%04x\n", id[ATA_ID_MAJOR_VER], - id[81], /* FIXME */ + id[ATA_ID_MINOR_VER], id[ATA_ID_COMMAND_SET_1], id[ATA_ID_COMMAND_SET_2], id[ATA_ID_CFSSE]); - printf ("id[85]: command set enable 1 = 0x%04x\n" - "id[86]: command set enable 2 = 0x%04x\n" + + printf ("id[85]: command set enabled 1 = 0x%04x\n" + "id[86]: command set enabled 2 = 0x%04x\n" "id[87]: command set default = 0x%04x\n" "id[88]: udma = 0x%04x\n" "id[93]: hardware reset result = 0x%04x\n", diff --git a/include/ata_drive.h b/include/ata_drive.h index 6b8915c9cb..e11172ba39 100644 --- a/include/ata_drive.h +++ b/include/ata_drive.h @@ -67,7 +67,12 @@ enum { ATA_ID_MWDMA_MODES = 63, ATA_ID_PIO_MODES= 64, ATA_ID_QUEUE_DEPTH = 75, + ATA_ID_SATA_CAPAB_1 = 76, + ATA_ID_SATA_CAPAB_2 = 77, + ATA_ID_SATA_FEAT_SUPP = 78, + ATA_ID_SATA_FEAT_ENABLE = 79, ATA_ID_MAJOR_VER= 80, + ATA_ID_MINOR_VER= 81, ATA_ID_COMMAND_SET_1= 82, ATA_ID_COMMAND_SET_2= 83, ATA_ID_CFSSE= 84, -- 2.20.1 ___ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox
[PATCH] clk: fix clk_round_rate() behaviour
Right now this function returns the current rate of the clock in the case when the round_rate() is not given in the clock's ops. This breaks clk_set_rate(), which calls clk_round_rate() to check if the resulting frequency would be the same as the one that is already set. Make it so that clk_round_rate() returns the frequency that was given as argument in this case. Signed-off-by: Denis Orlov --- drivers/clk/clk.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 52e309e877..7492717d3c 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -139,16 +139,16 @@ long clk_round_rate(struct clk *clk, unsigned long rate) if (IS_ERR(clk)) return 0; + if (!clk->ops->round_rate) + return rate; + parent = clk_get_parent(clk); if (parent) parent_rate = clk_get_rate(parent); hw = clk_to_clk_hw(clk); - if (clk->ops->round_rate) - return clk->ops->round_rate(hw, rate, _rate); - - return clk_get_rate(clk); + return clk->ops->round_rate(hw, rate, _rate); } long clk_hw_round_rate(struct clk_hw *hw, unsigned long rate) -- 2.20.1 ___ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox
[PATCH] clk: fix clk_round_rate command description
Signed-off-by: Denis Orlov --- commands/clk.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/commands/clk.c b/commands/clk.c index 0f7d7422e9..dfbc7c988f 100644 --- a/commands/clk.c +++ b/commands/clk.c @@ -99,12 +99,12 @@ static int do_clk_round_rate(int argc, char *argv[]) } BAREBOX_CMD_HELP_START(clk_round_rate) -BAREBOX_CMD_HELP_TEXT("Set clock CLK to RATE") +BAREBOX_CMD_HELP_TEXT("Show clock CLK actual rate if set to HZ") BAREBOX_CMD_HELP_END BAREBOX_CMD_START(clk_round_rate) .cmd= do_clk_round_rate, - BAREBOX_CMD_DESC("set a clocks rate") + BAREBOX_CMD_DESC("show a resulting clocks rate") BAREBOX_CMD_OPTS("CLK HZ") BAREBOX_CMD_GROUP(CMD_GRP_HWMANIP) BAREBOX_CMD_HELP(cmd_clk_round_rate_help) -- 2.20.1 ___ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox
[PATCH 0/7] e1000 and rtl8169 drivers fixes
Denis Orlov (7): net: e1000: remove superfluous allocation check net: e1000: properly read/write MDI registers on 8254x cards net: e1000: do not actually acquire/put swfw_sync on 8254x cards net: e1000: configure tx/rx and rctl in open() instead of init() net: rtl8169: properly map rx/tx buffers for dma net: rtl8169: enable pci device bus mastering on ifup net: rtl8169: free allocated memory on halt() drivers/net/e1000/e1000.h | 3 +++ drivers/net/e1000/main.c | 44 +++-- drivers/net/rtl8169.c | 51 ++- 3 files changed, 73 insertions(+), 25 deletions(-) -- 2.20.1
[PATCH 1/7] net: e1000: remove superfluous allocation check
dma_alloc() calls xmemalign which panics if unable to allocate memory, so there is no need to check the returned pointer for validity. Signed-off-by: Denis Orlov --- drivers/net/e1000/main.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/net/e1000/main.c b/drivers/net/e1000/main.c index f67c5d867b..bfb8d8ff2f 100644 --- a/drivers/net/e1000/main.c +++ b/drivers/net/e1000/main.c @@ -3575,9 +3575,6 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *id) edev->priv = hw; hw->packet = dma_alloc(PAGE_SIZE); - if (!hw->packet) - return -ENOMEM; - hw->packet_dma = dma_map_single(hw->dev, hw->packet, PAGE_SIZE, DMA_FROM_DEVICE); if (dma_mapping_error(hw->dev, hw->packet_dma)) -- 2.20.1
[PATCH 3/7] net: e1000: do not actually acquire/put swfw_sync on 8254x cards
There is no Software-Firmware Synchronization register on these controllers. Signed-off-by: Denis Orlov --- drivers/net/e1000/main.c | 7 +++ 1 file changed, 7 insertions(+) diff --git a/drivers/net/e1000/main.c b/drivers/net/e1000/main.c index 3b45fb3b51..4ca598eb2f 100644 --- a/drivers/net/e1000/main.c +++ b/drivers/net/e1000/main.c @@ -245,6 +245,10 @@ int32_t e1000_swfw_sync_acquire(struct e1000_hw *hw, uint16_t mask) int32_t timeout = 200; DEBUGFUNC(); + + if (hw->mac_type <= e1000_82547_rev_2) + return E1000_SUCCESS; + while (timeout) { if (e1000_get_hw_eeprom_semaphore(hw)) return -E1000_ERR_SWFW_SYNC; @@ -276,6 +280,9 @@ int32_t e1000_swfw_sync_release(struct e1000_hw *hw, uint16_t mask) { uint32_t swfw_sync; + if (hw->mac_type <= e1000_82547_rev_2) + return E1000_SUCCESS; + if (e1000_get_hw_eeprom_semaphore(hw)) return -E1000_ERR_SWFW_SYNC; -- 2.20.1
[PATCH 4/7] net: e1000: configure tx/rx and rctl in open() instead of init()
Otherwise, ifdowning the interface leads to a state in which trying to ifup it again fails. Signed-off-by: Denis Orlov --- drivers/net/e1000/main.c | 12 +++- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/net/e1000/main.c b/drivers/net/e1000/main.c index 4ca598eb2f..363730de0a 100644 --- a/drivers/net/e1000/main.c +++ b/drivers/net/e1000/main.c @@ -62,7 +62,9 @@ static int32_t e1000_phy_hw_reset(struct e1000_hw *hw); static int e1000_phy_reset(struct e1000_hw *hw); static int e1000_detect_gig_phy(struct e1000_hw *hw); static void e1000_set_media_type(struct e1000_hw *hw); - +static void e1000_configure_tx(struct e1000_hw *hw); +static void e1000_configure_rx(struct e1000_hw *hw); +static void e1000_setup_rctl(struct e1000_hw *hw); static int32_t e1000_check_phy_reset_block(struct e1000_hw *hw); @@ -811,6 +813,10 @@ static int e1000_open(struct eth_device *edev) e1000_write_reg(hw, E1000_CTRL_EXT, ctrl_ext); } + e1000_configure_tx(hw); + e1000_configure_rx(hw); + e1000_setup_rctl(hw); + return 0; } @@ -3575,10 +3581,6 @@ static int e1000_init(struct eth_device *edev) if (hw->mac_type == e1000_igb) mdelay(15); - e1000_configure_tx(hw); - e1000_configure_rx(hw); - e1000_setup_rctl(hw); - return 0; } -- 2.20.1
[PATCH 7/7] net: rtl8169: free allocated memory on halt()
Otherwise it just leaks. Signed-off-by: Denis Orlov --- drivers/net/rtl8169.c | 12 1 file changed, 12 insertions(+) diff --git a/drivers/net/rtl8169.c b/drivers/net/rtl8169.c index 4b40c539dd..e923e179bf 100644 --- a/drivers/net/rtl8169.c +++ b/drivers/net/rtl8169.c @@ -478,6 +478,18 @@ static void rtl8169_eth_halt(struct eth_device *edev) RTL_W32(priv, RxMissed, 0); pci_clear_master(priv->pci_dev); + + dma_unmap_single(>dev, priv->tx_buf_phys, NUM_TX_DESC * PKT_BUF_SIZE, +DMA_TO_DEVICE); + free(priv->tx_buf); + dma_free_coherent((void *)priv->tx_desc, priv->tx_desc_phys, + NUM_TX_DESC * sizeof(struct bufdesc)); + + dma_unmap_single(>dev, priv->rx_buf_phys, NUM_RX_DESC * PKT_BUF_SIZE, +DMA_FROM_DEVICE); + free(priv->rx_buf); + dma_free_coherent((void *)priv->rx_desc, priv->rx_desc_phys, + NUM_RX_DESC * sizeof(struct bufdesc)); } static int rtl8169_probe(struct pci_dev *pdev, const struct pci_device_id *id) -- 2.20.1
[PATCH 6/7] net: rtl8169: enable pci device bus mastering on ifup
Otherwise, the board hangs on doing ifup after ifdown as the latter disables bus mastering for the device in rtl8169_eth_halt(). Signed-off-by: Denis Orlov --- drivers/net/rtl8169.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/rtl8169.c b/drivers/net/rtl8169.c index e78cc40ffe..4b40c539dd 100644 --- a/drivers/net/rtl8169.c +++ b/drivers/net/rtl8169.c @@ -293,6 +293,8 @@ static int rtl8169_eth_open(struct eth_device *edev) struct rtl8169_priv *priv = edev->priv; int ret; + pci_set_master(priv->pci_dev); + rtl8169_init_ring(priv); rtl8169_hw_start(priv); -- 2.20.1
[PATCH 2/7] net: e1000: properly read/write MDI registers on 8254x cards
Taken from Linux e1000 driver. Signed-off-by: Denis Orlov --- drivers/net/e1000/e1000.h | 3 +++ drivers/net/e1000/main.c | 22 ++ 2 files changed, 25 insertions(+) diff --git a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h index 52ad3d4cdb..3a5ee9988e 100644 --- a/drivers/net/e1000/e1000.h +++ b/drivers/net/e1000/e1000.h @@ -1388,6 +1388,9 @@ struct e1000_eeprom_info { #define PHY_1000T_STATUS 0x0A/* 1000Base-T Status Reg */ #define PHY_EXT_STATUS 0x0F/* Extended Status Reg */ +#define MAX_PHY_REG_ADDRESS0x1F/* 5 bit address bus (0-0x1F) */ +#define MAX_PHY_MULTI_PAGE_REG 0xF /* Registers equal on all pages */ + /* M88E1000 Specific Registers */ #define M88E1000_PHY_SPEC_CTRL 0x10/* PHY Specific Control Register */ #define M88E1000_PHY_SPEC_STATUS 0x11/* PHY Specific Status Register */ diff --git a/drivers/net/e1000/main.c b/drivers/net/e1000/main.c index bfb8d8ff2f..3b45fb3b51 100644 --- a/drivers/net/e1000/main.c +++ b/drivers/net/e1000/main.c @@ -54,6 +54,8 @@ static int e1000_get_speed_and_duplex(struct e1000_hw *hw, uint16_t *speed, uint16_t *duplex); static int e1000_read_phy_reg(struct e1000_hw *hw, uint32_t reg_addr, uint16_t *phy_data); +static int e1000_phy_write(struct mii_bus *bus, int phy_addr, int reg_addr, + u16 phy_data); static int e1000_write_phy_reg(struct e1000_hw *hw, uint32_t reg_addr, uint16_t phy_data); static int32_t e1000_phy_hw_reset(struct e1000_hw *hw); @@ -2627,6 +2629,15 @@ static int e1000_read_phy_reg(struct e1000_hw *hw, uint32_t reg_addr, { int ret; + if ((hw->phy_type == e1000_phy_igp) && (reg_addr > MAX_PHY_MULTI_PAGE_REG)) { + ret = e1000_phy_write(>miibus, 1, IGP01E1000_PHY_PAGE_SELECT, + (u16)reg_addr); + if (ret) + return ret; + + reg_addr &= MAX_PHY_REG_ADDRESS; + } + ret = e1000_phy_read(>miibus, 1, reg_addr); if (ret < 0) return ret; @@ -2702,6 +2713,17 @@ static int e1000_phy_write(struct mii_bus *bus, int phy_addr, **/ static int e1000_write_phy_reg(struct e1000_hw *hw, uint32_t reg_addr, uint16_t phy_data) { + int ret; + + if ((hw->phy_type == e1000_phy_igp) && (reg_addr > MAX_PHY_MULTI_PAGE_REG)) { + ret = e1000_phy_write(>miibus, 1, IGP01E1000_PHY_PAGE_SELECT, + (u16)reg_addr); + if (ret) + return ret; + + reg_addr &= MAX_PHY_REG_ADDRESS; + } + return e1000_phy_write(>miibus, 1, reg_addr, phy_data); } -- 2.20.1
[PATCH 5/7] net: rtl8169: properly map rx/tx buffers for dma
Signed-off-by: Denis Orlov --- drivers/net/rtl8169.c | 37 - 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/drivers/net/rtl8169.c b/drivers/net/rtl8169.c index 341f5f240e..e78cc40ffe 100644 --- a/drivers/net/rtl8169.c +++ b/drivers/net/rtl8169.c @@ -42,11 +42,13 @@ struct rtl8169_priv { volatile struct bufdesc *tx_desc; dma_addr_t tx_desc_phys; void*tx_buf; + dma_addr_t tx_buf_phys; unsigned intcur_tx; volatile struct bufdesc *rx_desc; dma_addr_t rx_desc_phys; void*rx_buf; + dma_addr_t rx_buf_phys; unsigned intcur_rx; struct mii_bus miibus; @@ -218,14 +220,17 @@ static void rtl8169_init_ring(struct rtl8169_priv *priv) priv->cur_rx = priv->cur_tx = 0; - priv->tx_desc = dma_alloc_coherent(NUM_TX_DESC * - sizeof(struct bufdesc), >tx_desc_phys); + priv->tx_desc = dma_alloc_coherent(NUM_TX_DESC * sizeof(struct bufdesc), + >tx_desc_phys); priv->tx_buf = malloc(NUM_TX_DESC * PKT_BUF_SIZE); - priv->rx_desc = dma_alloc_coherent(NUM_RX_DESC * - sizeof(struct bufdesc), >rx_desc_phys); + priv->tx_buf_phys = dma_map_single(>edev.dev, priv->tx_buf, + NUM_TX_DESC * PKT_BUF_SIZE, DMA_TO_DEVICE); + + priv->rx_desc = dma_alloc_coherent(NUM_RX_DESC * sizeof(struct bufdesc), + >rx_desc_phys); priv->rx_buf = malloc(NUM_RX_DESC * PKT_BUF_SIZE); - dma_sync_single_for_device((unsigned long)priv->rx_buf, - NUM_RX_DESC * PKT_BUF_SIZE, DMA_FROM_DEVICE); + priv->rx_buf_phys = dma_map_single(>edev.dev, priv->rx_buf, + NUM_RX_DESC * PKT_BUF_SIZE, DMA_FROM_DEVICE); for (i = 0; i < NUM_RX_DESC; i++) { if (i == (NUM_RX_DESC - 1)) @@ -236,7 +241,7 @@ static void rtl8169_init_ring(struct rtl8169_priv *priv) cpu_to_le32(BD_STAT_OWN | PKT_BUF_SIZE); priv->rx_desc[i].buf_addr = - cpu_to_le32(virt_to_phys(priv->rx_buf + i * PKT_BUF_SIZE)); + cpu_to_le32(priv->rx_buf_phys + i * PKT_BUF_SIZE); } } @@ -353,12 +358,12 @@ static int rtl8169_eth_send(struct eth_device *edev, void *packet, if (packet_length < ETH_ZLEN) memset(priv->tx_buf + entry * PKT_BUF_SIZE, 0, ETH_ZLEN); memcpy(priv->tx_buf + entry * PKT_BUF_SIZE, packet, packet_length); - dma_sync_single_for_device((unsigned long)priv->tx_buf + entry * + dma_sync_single_for_device(priv->tx_buf_phys + entry * PKT_BUF_SIZE, PKT_BUF_SIZE, DMA_TO_DEVICE); priv->tx_desc[entry].buf_Haddr = 0; priv->tx_desc[entry].buf_addr = - cpu_to_le32(virt_to_phys(priv->tx_buf + entry * PKT_BUF_SIZE)); + cpu_to_le32(priv->tx_buf_phys + entry * PKT_BUF_SIZE); if (entry != (NUM_TX_DESC - 1)) { priv->tx_desc[entry].status = @@ -375,8 +380,8 @@ static int rtl8169_eth_send(struct eth_device *edev, void *packet, while (le32_to_cpu(priv->tx_desc[entry].status) & BD_STAT_OWN) ; - dma_sync_single_for_cpu((unsigned long)priv->tx_buf + entry * - PKT_BUF_SIZE, PKT_BUF_SIZE, DMA_TO_DEVICE); + dma_sync_single_for_cpu(priv->tx_buf_phys + entry * PKT_BUF_SIZE, + PKT_BUF_SIZE, DMA_TO_DEVICE); priv->cur_tx++; @@ -395,15 +400,13 @@ static int rtl8169_eth_rx(struct eth_device *edev) if (!(le32_to_cpu(priv->rx_desc[entry].status) & BD_STAT_RX_RES)) { pkt_size = (le32_to_cpu(priv->rx_desc[entry].status) & 0x1fff) - 4; - dma_sync_single_for_cpu((unsigned long)priv->rx_buf - + entry * PKT_BUF_SIZE, + dma_sync_single_for_cpu(priv->rx_buf_phys + entry * PKT_BUF_SIZE, pkt_size, DMA_FROM_DEVICE); net_receive(edev, priv->rx_buf + entry * PKT_BUF_SIZE, pkt_size); - dma_sync_single_for_device((unsigned long)priv->rx_buf - + entry * PKT_BUF_SIZE, + dma_sync_single_for_device(priv->rx_buf_phys + entry * PKT_BUF_SIZE, pkt_size,
[PATCH 02/16] ata: ahci: replace magic numbers with named constants
Signed-off-by: Denis Orlov --- drivers/ata/ahci.c | 21 +++-- drivers/ata/ahci.h | 12 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index ad9e2f950f..c64c856f94 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -101,7 +101,7 @@ static inline void __iomem *ahci_port_base(void __iomem *base, int port) static int ahci_link_ok(struct ahci_port *ahci_port, int verbose) { - u32 val = ahci_port_read(ahci_port, PORT_SCR_STAT) & 0xf; + u32 val = ahci_port_read(ahci_port, PORT_SCR_STAT) & PORT_SCR_STAT_DET; if (val == 0x3) return true; @@ -166,7 +166,7 @@ static int ahci_io(struct ahci_port *ahci_port, u8 *fis, int fis_len, void *rbuf sg_count = ahci_fill_sg(ahci_port, rbuf ? rbuf : wbuf, buf_len); opts = (fis_len >> 2) | (sg_count << 16); if (wbuf) - opts |= 1 << 6; + opts |= CMD_LIST_OPTS_WRITE; ahci_fill_cmd_slot(ahci_port, opts); ahci_port_write_f(ahci_port, PORT_CMD_ISSUE, 1); @@ -355,7 +355,7 @@ static int ahci_init_port(struct ahci_port *ahci_port) * rarely has it taken between 1-2 ms. Never seen it above 2 ms. */ ret = wait_on_timeout(WAIT_LINKUP, - (ahci_port_read(ahci_port, PORT_SCR_STAT) & 0xf) == 0x3); + (ahci_port_read(ahci_port, PORT_SCR_STAT) & PORT_SCR_STAT_DET) == 0x3); if (ret) { ahci_port_info(ahci_port, "SATA link timeout\n"); ret = -ETIMEDOUT; @@ -373,15 +373,16 @@ static int ahci_init_port(struct ahci_port *ahci_port) ret = wait_on_timeout(WAIT_SPINUP, ((ahci_port_read(ahci_port, PORT_TFDATA) & -(ATA_STATUS_BUSY | ATA_STATUS_DRQ)) == 0) - || ((ahci_port_read(ahci_port, PORT_SCR_STAT) & 0xf) == 1)); +(ATA_STATUS_BUSY | ATA_STATUS_DRQ)) == 0) || + ((ahci_port_read(ahci_port, PORT_SCR_STAT) & +PORT_SCR_STAT_DET) == 1)); if (ret) { ahci_port_info(ahci_port, "timeout.\n"); ret = -ENODEV; goto err_init; } - if ((ahci_port_read(ahci_port, PORT_SCR_STAT) & 0xf) == 1) { + if ((ahci_port_read(ahci_port, PORT_SCR_STAT) & PORT_SCR_STAT_DET) == 1) { ahci_port_info(ahci_port, "down.\n"); ret = -ENODEV; goto err_init; @@ -408,7 +409,7 @@ static int ahci_init_port(struct ahci_port *ahci_port) ahci_port_debug(ahci_port, "status: 0x%08x\n", val); - if ((val & 0xf) == 0x03) + if ((val & PORT_SCR_STAT_DET) == 0x3) return 0; ret = -ENODEV; @@ -581,8 +582,8 @@ int ahci_add_host(struct ahci_device *ahci) ahci_debug(ahci, "ahci_host_init: start\n"); cap_save = ahci_ioread(ahci, HOST_CAP); - cap_save &= ((1 << 28) | (1 << 17)); - cap_save |= (1 << 27); /* Staggered Spin-up. Not needed. */ + cap_save &= (HOST_SMPS | HOST_SPM); + cap_save |= HOST_SSS; /* Staggered Spin-up. Not needed. */ /* global controller reset */ tmp = ahci_ioread(ahci, HOST_CTL); @@ -605,7 +606,7 @@ int ahci_add_host(struct ahci_device *ahci) ahci->cap = ahci_ioread(ahci, HOST_CAP); ahci->port_map = ahci_ioread(ahci, HOST_PORTS_IMPL); - ahci->n_ports = (ahci->cap & 0x1f) + 1; + ahci->n_ports = (ahci->cap & HOST_NP) + 1; ahci_debug(ahci, "cap 0x%x port_map 0x%x n_ports %d\n", ahci->cap, ahci->port_map, ahci->n_ports); diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h index 7fed43045a..5a187fd2e1 100644 --- a/drivers/ata/ahci.h +++ b/drivers/ata/ahci.h @@ -33,6 +33,12 @@ #define HOST_VERSION 0x10 /* AHCI spec. version compliancy */ #define HOST_CAP2 0x24 /* host capabilities, extended */ +/* HOST_CAP bits */ +#define HOST_SMPS (1 << 28) /* supports mechanical presence switch */ +#define HOST_SSS (1 << 27) /* supports staggered spin-up */ +#define HOST_SPM (1 << 17) /* supports port multiplier */ +#define HOST_NP(0x1f << 0) /* number of ports */ + /* HOST_CTL bits */ #define HOST_RESET (1 << 0) /* reset controller; self-clear */ #define HOST_IRQ_EN(1 << 1) /* global IRQ enable */ @@ -98,6 +104,9 @@ #define PORT_CMD_ICC_PARTIAL (0x2 << 28) /* Put i/f in partial state */ #define PORT_CMD_ICC_SLUMBER (0x6 << 28) /* Put i/f in slumber state */ +/* PORT_SCR_STAT bits */ +#define PORT_SCR_STAT_DET (0xf << 0) /* device detecti
[PATCH 03/16] ata: ahci: fix missing whitespace in ahci_add_host()
Signed-off-by: Denis Orlov --- drivers/ata/ahci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index c64c856f94..5aab81fcef 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -596,7 +596,7 @@ int ahci_add_host(struct ahci_device *ahci) */ ret = wait_on_timeout(SECOND, (ahci_ioread(ahci, HOST_CTL) & HOST_RESET) == 0); if (ret) { - ahci_debug(ahci,"controller reset failed (0x%x)\n", tmp); + ahci_debug(ahci, "controller reset failed (0x%x)\n", tmp); return -ENODEV; } -- 2.20.1 ___ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox
[PATCH 04/16] ata: ahci: simplify fis structure creation
Signed-off-by: Denis Orlov --- drivers/ata/ahci.c | 23 +-- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 5aab81fcef..026f83046c 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -192,14 +192,12 @@ static int ahci_io(struct ahci_port *ahci_port, u8 *fis, int fis_len, void *rbuf static int ahci_read_id(struct ata_port *ata, void *buf) { struct ahci_port *ahci = container_of(ata, struct ahci_port, ata); - u8 fis[20]; - - memset(fis, 0, sizeof(fis)); - /* Construct the FIS */ - fis[0] = 0x27; /* Host to device FIS. */ - fis[1] = 1 << 7;/* Command FIS. */ - fis[2] = ATA_CMD_ID_ATA;/* Command byte. */ + u8 fis[20] = { + 0x27, /* Host to device FIS. */ + 1 << 7, /* Command FIS. */ + ATA_CMD_ID_ATA /* Command byte. */ + }; return ahci_io(ahci, fis, sizeof(fis), buf, NULL, SECTOR_SIZE); } @@ -208,16 +206,13 @@ static int ahci_rw(struct ata_port *ata, void *rbuf, const void *wbuf, sector_t block, blkcnt_t num_blocks) { struct ahci_port *ahci = container_of(ata, struct ahci_port, ata); - u8 fis[20]; + u8 fis[20] = { + 0x27, /* Host to device FIS. */ + 1 << 7 /* Command FIS. */ + }; int ret; int lba48 = ata_id_has_lba48(ata->id); - memset(fis, 0, sizeof(fis)); - - /* Construct the FIS */ - fis[0] = 0x27; /* Host to device FIS. */ - fis[1] = 1 << 7;/* Command FIS. */ - /* Command byte. */ if (lba48) fis[2] = wbuf ? ATA_CMD_WRITE_EXT : ATA_CMD_READ_EXT; -- 2.20.1 ___ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox
[PATCH 01/16] ata: ahci: use abstract read/write functions uniformly
Currently those are used in some routines side by side with underlying functions with no apparent reason for it. Make their usage uniform, this cleans up code a bit and allows to remove unneeded variables. Signed-off-by: Denis Orlov --- drivers/ata/ahci.c | 18 +++--- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 3c0b0a5450..ad9e2f950f 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -172,7 +172,7 @@ static int ahci_io(struct ahci_port *ahci_port, u8 *fis, int fis_len, void *rbuf ahci_port_write_f(ahci_port, PORT_CMD_ISSUE, 1); ret = wait_on_timeout(WAIT_DATAIO, - (readl(ahci_port->port_mmio + PORT_CMD_ISSUE) & 0x1) == 0); + (ahci_port_read(ahci_port, PORT_CMD_ISSUE) & 0x1) == 0); if (ret) return -ETIMEDOUT; @@ -274,12 +274,9 @@ static int ahci_write(struct ata_port *ata, const void *buf, sector_t block, static int ahci_init_port(struct ahci_port *ahci_port) { - void __iomem *port_mmio; u32 val, cmd; int ret; - port_mmio = ahci_port->port_mmio; - /* make sure port is not active */ val = ahci_port_read(ahci_port, PORT_CMD); if (val & (PORT_CMD_LIST_ON | PORT_CMD_FIS_ON | PORT_CMD_FIS_RX | PORT_CMD_START)) { @@ -375,16 +372,16 @@ static int ahci_init_port(struct ahci_port *ahci_port) ahci_port_info(ahci_port, "Spinning up device...\n"); ret = wait_on_timeout(WAIT_SPINUP, - ((readl(port_mmio + PORT_TFDATA) & + ((ahci_port_read(ahci_port, PORT_TFDATA) & (ATA_STATUS_BUSY | ATA_STATUS_DRQ)) == 0) - || ((readl(port_mmio + PORT_SCR_STAT) & 0xf) == 1)); + || ((ahci_port_read(ahci_port, PORT_SCR_STAT) & 0xf) == 1)); if (ret) { ahci_port_info(ahci_port, "timeout.\n"); ret = -ENODEV; goto err_init; } - if ((readl(port_mmio + PORT_SCR_STAT) & 0xf) == 1) { + if ((ahci_port_read(ahci_port, PORT_SCR_STAT) & 0xf) == 1) { ahci_port_info(ahci_port, "down.\n"); ret = -ENODEV; goto err_init; @@ -570,7 +567,6 @@ static int ahci_detect(struct device_d *dev) int ahci_add_host(struct ahci_device *ahci) { - u8 *mmio = (u8 *)ahci->mmio_base; u32 tmp, cap_save; int i, ret; @@ -584,7 +580,7 @@ int ahci_add_host(struct ahci_device *ahci) ahci_debug(ahci, "ahci_host_init: start\n"); - cap_save = readl(mmio + HOST_CAP); + cap_save = ahci_ioread(ahci, HOST_CAP); cap_save &= ((1 << 28) | (1 << 17)); cap_save |= (1 << 27); /* Staggered Spin-up. Not needed. */ @@ -597,7 +593,7 @@ int ahci_add_host(struct ahci_device *ahci) * reset must complete within 1 second, or * the hardware should be considered fried. */ - ret = wait_on_timeout(SECOND, (readl(mmio + HOST_CTL) & HOST_RESET) == 0); + ret = wait_on_timeout(SECOND, (ahci_ioread(ahci, HOST_CTL) & HOST_RESET) == 0); if (ret) { ahci_debug(ahci,"controller reset failed (0x%x)\n", tmp); return -ENODEV; @@ -620,7 +616,7 @@ int ahci_add_host(struct ahci_device *ahci) ahci_port->num = i; ahci_port->ahci = ahci; ahci_port->ata.dev = ahci->dev; - ahci_port->port_mmio = ahci_port_base(mmio, i); + ahci_port->port_mmio = ahci_port_base(ahci->mmio_base, i); ahci_port->ata.ops = _ops; ata_port_register(_port->ata); } -- 2.20.1 ___ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox
[PATCH 16/16] ata: ahci: allocate memory in one call in ahci_init_port()
Memory allocated with dma_alloc_coherent() is aligned by page size. Calling it multiple times leads to unnecessary fragmentation and overhead considering that we are actually able to allocate all the memory that we need at once by issuing only one call. Signed-off-by: Denis Orlov --- drivers/ata/ahci.c | 40 ++-- 1 file changed, 14 insertions(+), 26 deletions(-) diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 24098ada08..f707efb50f 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -273,6 +273,8 @@ static int ahci_write(struct ata_port *ata, const void *buf, sector_t block, static int ahci_init_port(struct ahci_port *ahci_port) { u32 val, cmd; + void *mem; + dma_addr_t mem_dma; int ret; /* make sure port is not active */ @@ -290,16 +292,17 @@ static int ahci_init_port(struct ahci_port *ahci_port) mdelay(500); } + mem = dma_alloc_coherent(AHCI_PORT_PRIV_DMA_SZ, _dma); + if (!mem) { + return -ENOMEM; + } + /* * First item in chunk of DMA memory: 32-slot command list, * 32 bytes each in size */ - ahci_port->cmd_slot = dma_alloc_coherent(AHCI_CMD_LIST_SZ, - _port->cmd_slot_dma); - if (!ahci_port->cmd_slot) { - ret = -ENOMEM; - goto err_alloc; - } + ahci_port->cmd_slot = mem; + ahci_port->cmd_slot_dma = mem_dma; ahci_port_debug(ahci_port, "cmd_slot = 0x%p (0x%pa)\n", ahci_port->cmd_slot, ahci_port->cmd_slot_dma); @@ -307,22 +310,15 @@ static int ahci_init_port(struct ahci_port *ahci_port) /* * Second item: Received-FIS area */ - ahci_port->rx_fis = dma_alloc_coherent(AHCI_RX_FIS_SZ, _port->rx_fis_dma); - if (!ahci_port->rx_fis) { - ret = -ENOMEM; - goto err_alloc1; - } + ahci_port->rx_fis = mem + AHCI_CMD_SLOT_SZ; + ahci_port->rx_fis_dma = mem_dma + AHCI_CMD_SLOT_SZ; /* * Third item: data area for storing a single command * and its scatter-gather table */ - ahci_port->cmd_tbl = dma_alloc_coherent(AHCI_CMD_TBL_SZ, -_port->cmd_tbl_dma); - if (!ahci_port->cmd_tbl) { - ret = -ENOMEM; - goto err_alloc2; - } + ahci_port->cmd_tbl = mem + AHCI_CMD_SLOT_SZ + AHCI_RX_FIS_SZ; + ahci_port->cmd_tbl_dma = mem_dma + AHCI_CMD_SLOT_SZ + AHCI_RX_FIS_SZ; ahci_port_debug(ahci_port, "cmd_tbl = 0x%p (0x%pa)\n", ahci_port->cmd_tbl, ahci_port->cmd_tbl_dma); @@ -418,15 +414,7 @@ static int ahci_init_port(struct ahci_port *ahci_port) ret = -ENODEV; err_init: - dma_free_coherent(ahci_port->cmd_tbl, ahci_port->cmd_tbl_dma, - AHCI_CMD_TBL_SZ); -err_alloc2: - dma_free_coherent(ahci_port->rx_fis, ahci_port->rx_fis_dma, - AHCI_RX_FIS_SZ); -err_alloc1: - dma_free_coherent(ahci_port->cmd_slot, ahci_port->cmd_slot_dma, - AHCI_CMD_LIST_SZ); -err_alloc: + dma_free_coherent(mem, mem_dma, AHCI_PORT_PRIV_DMA_SZ); return ret; } -- 2.20.1 ___ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox
[PATCH 15/16] ata: ahci: register only implemented ports
The value from the "ports implemented" register should be kept in mind when registering ports or detecting devices on them. Signed-off-by: Denis Orlov --- drivers/ata/ahci.c | 15 --- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index f9056ff418..24098ada08 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -563,11 +563,15 @@ void ahci_info(struct device_d *dev) static int ahci_detect(struct device_d *dev) { struct ahci_device *ahci = dev->priv; + int n_ports = max_t(int, ahci->n_ports, fls(ahci->port_map)); int i; - for (i = 0; i < ahci->n_ports; i++) { + for (i = 0; i < n_ports; i++) { struct ahci_port *ahci_port = >ports[i]; + if (!(ahci->port_map & (1 << i))) + continue; + ata_port_detect(_port->ata); } @@ -577,7 +581,7 @@ static int ahci_detect(struct device_d *dev) int ahci_add_host(struct ahci_device *ahci) { u32 tmp, cap_save; - int i, ret; + int n_ports, i, ret; ahci->host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY @@ -619,9 +623,14 @@ int ahci_add_host(struct ahci_device *ahci) ahci_debug(ahci, "cap 0x%x port_map 0x%x n_ports %d\n", ahci->cap, ahci->port_map, ahci->n_ports); - for (i = 0; i < ahci->n_ports; i++) { + n_ports = max_t(int, ahci->n_ports, fls(ahci->port_map)); + + for (i = 0; i < n_ports; i++) { struct ahci_port *ahci_port = >ports[i]; + if (!(ahci->port_map & (1 << i))) + continue; + ahci_port->num = i; ahci_port->ahci = ahci; ahci_port->ata.dev = ahci->dev; -- 2.20.1 ___ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox
[PATCH 14/16] ata: ahci: remove redundant cast in ahci_io()
Signed-off-by: Denis Orlov --- drivers/ata/ahci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 2d5adcfca9..f9056ff418 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -171,7 +171,7 @@ static int ahci_io(struct ahci_port *ahci_port, u8 *fis, int fis_len, void *rbuf buf_dma = dma_map_single(ahci_port->ahci->dev, buf, buf_len, dma_dir); - memcpy((unsigned char *)ahci_port->cmd_tbl, fis, fis_len); + memcpy(ahci_port->cmd_tbl, fis, fis_len); sg_count = ahci_fill_sg(ahci_port, buf_dma, buf_len); opts = (fis_len >> 2) | (sg_count << 16); -- 2.20.1 ___ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox
[PATCH 13/16] ata: ahci: add missing capability in ahci_print_info()
Signed-off-by: Denis Orlov --- drivers/ata/ahci.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 23085ebe09..2d5adcfca9 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -532,6 +532,7 @@ void ahci_print_info(struct ahci_device *ahci) "%s%s%s%s%s%s\n", cap & HOST_CAP_64 ? "64bit " : "", cap & HOST_CAP_NCQ ? "ncq " : "", + cap & HOST_CAP_SNTF ? "sntf " : "", cap & HOST_CAP_SMPS ? "ilck " : "", cap & HOST_CAP_SSS ? "stag " : "", cap & HOST_CAP_ALPM ? "pm " : "", -- 2.20.1 ___ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox
[PATCH 08/16] ata: ahci: properly fill scatter/gather table
We are supposed to populate a table, but instead we were just overwriting the same entry over and over in a loop. Signed-off-by: Denis Orlov --- drivers/ata/ahci.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index f7eb35c09d..2d7b527755 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -139,6 +139,7 @@ static int ahci_fill_sg(struct ahci_port *ahci_port, const void *buf, int buf_le buf_len -= now; buf += now; + ahci_sg++; } return sg_count; -- 2.20.1 ___ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox
[PATCH 10/16] ata: ahci: map buffers properly
Using dma_sync_single_for_*() does not make sense in there - we are given a cpu side address of a buffer and need to actually map it for the device. Signed-off-by: Denis Orlov --- drivers/ata/ahci.c | 37 ++--- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 1d8099c2ee..ff9093c7b7 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -121,7 +121,7 @@ static void ahci_fill_cmd_slot(struct ahci_port *ahci_port, u32 opts) ahci_port->cmd_slot->tbl_addr_hi = 0; } -static int ahci_fill_sg(struct ahci_port *ahci_port, const void *buf, int buf_len) +static int ahci_fill_sg(struct ahci_port *ahci_port, dma_addr_t buf_dma, int buf_len) { struct ahci_sg *ahci_sg = ahci_port->cmd_tbl_sg; u32 sg_count; @@ -133,12 +133,12 @@ static int ahci_fill_sg(struct ahci_port *ahci_port, const void *buf, int buf_le while (buf_len) { unsigned int now = min(AHCI_MAX_DATA_BYTE_COUNT, buf_len); - ahci_sg->addr = cpu_to_le32((u32)buf); + ahci_sg->addr = cpu_to_le32(buf_dma); ahci_sg->addr_hi = 0; ahci_sg->flags_size = cpu_to_le32(now - 1); buf_len -= now; - buf += now; + buf_dma += now; ahci_sg++; } @@ -151,20 +151,26 @@ static int ahci_io(struct ahci_port *ahci_port, u8 *fis, int fis_len, void *rbuf u32 opts; int sg_count; int ret; + void *buf; + dma_addr_t buf_dma; + enum dma_data_direction dma_dir; if (!ahci_link_ok(ahci_port, 1)) return -EIO; - if (wbuf) - dma_sync_single_for_device((unsigned long)wbuf, buf_len, - DMA_TO_DEVICE); - if (rbuf) - dma_sync_single_for_device((unsigned long)rbuf, buf_len, - DMA_FROM_DEVICE); + if (wbuf) { + buf = (void *)wbuf; + dma_dir = DMA_TO_DEVICE; + } else { + buf = rbuf; + dma_dir = DMA_FROM_DEVICE; + } + + buf_dma = dma_map_single(ahci_port->ahci->dev, buf, buf_len, dma_dir); memcpy((unsigned char *)ahci_port->cmd_tbl, fis, fis_len); - sg_count = ahci_fill_sg(ahci_port, rbuf ? rbuf : wbuf, buf_len); + sg_count = ahci_fill_sg(ahci_port, buf_dma, buf_len); opts = (fis_len >> 2) | (sg_count << 16); if (wbuf) opts |= CMD_LIST_OPTS_WRITE; @@ -174,17 +180,10 @@ static int ahci_io(struct ahci_port *ahci_port, u8 *fis, int fis_len, void *rbuf ret = wait_on_timeout(WAIT_DATAIO, (ahci_port_read(ahci_port, PORT_CMD_ISSUE) & 0x1) == 0); - if (ret) - return -ETIMEDOUT; - if (wbuf) - dma_sync_single_for_cpu((unsigned long)wbuf, buf_len, - DMA_TO_DEVICE); - if (rbuf) - dma_sync_single_for_cpu((unsigned long)rbuf, buf_len, - DMA_FROM_DEVICE); + dma_unmap_single(ahci_port->ahci->dev, buf_dma, buf_len, dma_dir); - return 0; + return ret; } /* -- 2.20.1 ___ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox
[PATCH 12/16] ata: ahci: make rx_fis field in ahci_port of type void*
It is supposed to represent a pointer so make it actually be one. Signed-off-by: Denis Orlov --- drivers/ata/ahci.c | 5 ++--- drivers/ata/ahci.h | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index d423da3a48..23085ebe09 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -307,8 +307,7 @@ static int ahci_init_port(struct ahci_port *ahci_port) /* * Second item: Received-FIS area */ - ahci_port->rx_fis = (unsigned long)dma_alloc_coherent(AHCI_RX_FIS_SZ, - _port->rx_fis_dma); + ahci_port->rx_fis = dma_alloc_coherent(AHCI_RX_FIS_SZ, _port->rx_fis_dma); if (!ahci_port->rx_fis) { ret = -ENOMEM; goto err_alloc1; @@ -422,7 +421,7 @@ err_init: dma_free_coherent(ahci_port->cmd_tbl, ahci_port->cmd_tbl_dma, AHCI_CMD_TBL_SZ); err_alloc2: - dma_free_coherent((void *)ahci_port->rx_fis, ahci_port->rx_fis_dma, + dma_free_coherent(ahci_port->rx_fis, ahci_port->rx_fis_dma, AHCI_RX_FIS_SZ); err_alloc1: dma_free_coherent(ahci_port->cmd_slot, ahci_port->cmd_slot_dma, diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h index de404e2e16..77196592ed 100644 --- a/drivers/ata/ahci.h +++ b/drivers/ata/ahci.h @@ -179,7 +179,7 @@ struct ahci_port { struct ahci_sg *cmd_tbl_sg; void*cmd_tbl; dma_addr_t cmd_tbl_dma; - u32 rx_fis; + void*rx_fis; dma_addr_t rx_fis_dma; }; -- 2.20.1 ___ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox
[PATCH 11/16] ata: ahci: use 64-bit addressing if available
Signed-off-by: Denis Orlov --- drivers/ata/ahci.c | 19 +-- 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index ff9093c7b7..d423da3a48 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -117,8 +117,10 @@ static void ahci_fill_cmd_slot(struct ahci_port *ahci_port, u32 opts) ahci_port->cmd_slot->opts = cpu_to_le32(opts); ahci_port->cmd_slot->status = 0; ahci_port->cmd_slot->tbl_addr = - cpu_to_le32(ahci_port->cmd_tbl_dma & 0x); - ahci_port->cmd_slot->tbl_addr_hi = 0; + cpu_to_le32(lower_32_bits(ahci_port->cmd_tbl_dma)); + if (ahci_port->ahci->cap & HOST_CAP_64) + ahci_port->cmd_slot->tbl_addr_hi = + cpu_to_le32(upper_32_bits(ahci_port->cmd_tbl_dma)); } static int ahci_fill_sg(struct ahci_port *ahci_port, dma_addr_t buf_dma, int buf_len) @@ -133,8 +135,9 @@ static int ahci_fill_sg(struct ahci_port *ahci_port, dma_addr_t buf_dma, int buf while (buf_len) { unsigned int now = min(AHCI_MAX_DATA_BYTE_COUNT, buf_len); - ahci_sg->addr = cpu_to_le32(buf_dma); - ahci_sg->addr_hi = 0; + ahci_sg->addr = cpu_to_le32(lower_32_bits(buf_dma)); + if (ahci_port->ahci->cap & HOST_CAP_64) + ahci_sg->addr_hi = cpu_to_le32(upper_32_bits(buf_dma)); ahci_sg->flags_size = cpu_to_le32(now - 1); buf_len -= now; @@ -327,8 +330,12 @@ static int ahci_init_port(struct ahci_port *ahci_port) ahci_port->cmd_tbl_sg = ahci_port->cmd_tbl + AHCI_CMD_TBL_HDR_SZ; - ahci_port_write_f(ahci_port, PORT_LST_ADDR, ahci_port->cmd_slot_dma); - ahci_port_write_f(ahci_port, PORT_FIS_ADDR, ahci_port->rx_fis_dma); + ahci_port_write_f(ahci_port, PORT_LST_ADDR, lower_32_bits(ahci_port->cmd_slot_dma)); + if (ahci_port->ahci->cap & HOST_CAP_64) + ahci_port_write_f(ahci_port, PORT_LST_ADDR_HI, upper_32_bits(ahci_port->cmd_slot_dma)); + ahci_port_write_f(ahci_port, PORT_FIS_ADDR, lower_32_bits(ahci_port->rx_fis_dma)); + if (ahci_port->ahci->cap & HOST_CAP_64) + ahci_port_write_f(ahci_port, PORT_FIS_ADDR_HI, upper_32_bits(ahci_port->rx_fis_dma)); /* * Add the spinup command to whatever mode bits may -- 2.20.1 ___ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox
[PATCH 05/16] ata: ahci: do not ignore dma handles
They represent addresses from the device side and should be used instead of cpu side ones when populating device registers than hold addresses. Signed-off-by: Denis Orlov --- drivers/ata/ahci.c | 21 - drivers/ata/ahci.h | 3 +++ 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 026f83046c..095eb93a08 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -117,7 +117,7 @@ static void ahci_fill_cmd_slot(struct ahci_port *ahci_port, u32 opts) ahci_port->cmd_slot->opts = cpu_to_le32(opts); ahci_port->cmd_slot->status = 0; ahci_port->cmd_slot->tbl_addr = - cpu_to_le32((unsigned long)ahci_port->cmd_tbl & 0x); + cpu_to_le32(ahci_port->cmd_tbl_dma & 0x); ahci_port->cmd_slot->tbl_addr_hi = 0; } @@ -292,7 +292,7 @@ static int ahci_init_port(struct ahci_port *ahci_port) * 32 bytes each in size */ ahci_port->cmd_slot = dma_alloc_coherent(AHCI_CMD_SLOT_SZ * 32, -DMA_ADDRESS_BROKEN); + _port->cmd_slot_dma); if (!ahci_port->cmd_slot) { ret = -ENOMEM; goto err_alloc; @@ -304,7 +304,7 @@ static int ahci_init_port(struct ahci_port *ahci_port) * Second item: Received-FIS area */ ahci_port->rx_fis = (unsigned long)dma_alloc_coherent(AHCI_RX_FIS_SZ, - DMA_ADDRESS_BROKEN); + _port->rx_fis_dma); if (!ahci_port->rx_fis) { ret = -ENOMEM; goto err_alloc1; @@ -315,7 +315,7 @@ static int ahci_init_port(struct ahci_port *ahci_port) * and its scatter-gather table */ ahci_port->cmd_tbl = dma_alloc_coherent(AHCI_CMD_TBL_SZ, - DMA_ADDRESS_BROKEN); +_port->cmd_tbl_dma); if (!ahci_port->cmd_tbl) { ret = -ENOMEM; goto err_alloc2; @@ -325,8 +325,8 @@ static int ahci_init_port(struct ahci_port *ahci_port) ahci_port->cmd_tbl_sg = ahci_port->cmd_tbl + AHCI_CMD_TBL_HDR_SZ; - ahci_port_write_f(ahci_port, PORT_LST_ADDR, (u32)ahci_port->cmd_slot); - ahci_port_write_f(ahci_port, PORT_FIS_ADDR, ahci_port->rx_fis); + ahci_port_write_f(ahci_port, PORT_LST_ADDR, ahci_port->cmd_slot_dma); + ahci_port_write_f(ahci_port, PORT_FIS_ADDR, ahci_port->rx_fis_dma); /* * Add the spinup command to whatever mode bits may @@ -410,11 +410,14 @@ static int ahci_init_port(struct ahci_port *ahci_port) ret = -ENODEV; err_init: - dma_free_coherent(ahci_port->cmd_tbl, 0, AHCI_CMD_TBL_SZ); + dma_free_coherent(ahci_port->cmd_tbl, ahci_port->cmd_tbl_dma, + AHCI_CMD_TBL_SZ); err_alloc2: - dma_free_coherent((void *)ahci_port->rx_fis, 0, AHCI_RX_FIS_SZ); + dma_free_coherent((void *)ahci_port->rx_fis, ahci_port->rx_fis_dma, + AHCI_RX_FIS_SZ); err_alloc1: - dma_free_coherent(ahci_port->cmd_slot, 0, AHCI_CMD_SLOT_SZ * 32); + dma_free_coherent(ahci_port->cmd_slot, ahci_port->cmd_slot_dma, + AHCI_CMD_SLOT_SZ * 32); err_alloc: return ret; } diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h index 5a187fd2e1..3ca64c3d70 100644 --- a/drivers/ata/ahci.h +++ b/drivers/ata/ahci.h @@ -151,9 +151,12 @@ struct ahci_port { unsignedflags; void __iomem*port_mmio; struct ahci_cmd_hdr *cmd_slot; + dma_addr_t cmd_slot_dma; struct ahci_sg *cmd_tbl_sg; void*cmd_tbl; + dma_addr_t cmd_tbl_dma; u32 rx_fis; + dma_addr_t rx_fis_dma; }; struct ahci_device { -- 2.20.1 ___ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox
[PATCH 06/16] ata: ahci: adjust debug messages in ahci_init_port()
The output was a bit misleading, not displaying physical addresses while for some reason using "dma" to specify a variable in one case. Make it print both types of addresses. Signed-off-by: Denis Orlov --- drivers/ata/ahci.c | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 095eb93a08..c02f499ac1 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -298,7 +298,8 @@ static int ahci_init_port(struct ahci_port *ahci_port) goto err_alloc; } - ahci_port_debug(ahci_port, "cmd_slot = 0x%x\n", (unsigned)ahci_port->cmd_slot); + ahci_port_debug(ahci_port, "cmd_slot = 0x%p (0x%pa)\n", + ahci_port->cmd_slot, ahci_port->cmd_slot_dma); /* * Second item: Received-FIS area @@ -321,7 +322,8 @@ static int ahci_init_port(struct ahci_port *ahci_port) goto err_alloc2; } - ahci_port_debug(ahci_port, "cmd_tbl_dma = 0x%p\n", ahci_port->cmd_tbl); + ahci_port_debug(ahci_port, "cmd_tbl = 0x%p (0x%pa)\n", + ahci_port->cmd_tbl, ahci_port->cmd_tbl_dma); ahci_port->cmd_tbl_sg = ahci_port->cmd_tbl + AHCI_CMD_TBL_HDR_SZ; -- 2.20.1 ___ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox
[PATCH 07/16] ata: ahci: correct named constants values and names
This gives more clear names to some of the macros that designate the sizes of various memory structures and fixes a mistake in one of them. The command table item was regarded as taking 32 bytes in size while it is actually supposed to only take 16 bytes according to the spec. This also changes a somewhat misleading comment that calls the command list a command table. There is a cmt_tbl field that actually holds a pointer to a different structure that is called a command table in the specification, so it seems better to more clearly disambiguate them. Signed-off-by: Denis Orlov --- drivers/ata/ahci.c | 6 +++--- drivers/ata/ahci.h | 10 ++ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index c02f499ac1..f7eb35c09d 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -288,10 +288,10 @@ static int ahci_init_port(struct ahci_port *ahci_port) } /* -* First item in chunk of DMA memory: 32-slot command table, +* First item in chunk of DMA memory: 32-slot command list, * 32 bytes each in size */ - ahci_port->cmd_slot = dma_alloc_coherent(AHCI_CMD_SLOT_SZ * 32, + ahci_port->cmd_slot = dma_alloc_coherent(AHCI_CMD_LIST_SZ, _port->cmd_slot_dma); if (!ahci_port->cmd_slot) { ret = -ENOMEM; @@ -419,7 +419,7 @@ err_alloc2: AHCI_RX_FIS_SZ); err_alloc1: dma_free_coherent(ahci_port->cmd_slot, ahci_port->cmd_slot_dma, - AHCI_CMD_SLOT_SZ * 32); + AHCI_CMD_LIST_SZ); err_alloc: return ret; } diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h index 3ca64c3d70..99c45f30fc 100644 --- a/drivers/ata/ahci.h +++ b/drivers/ata/ahci.h @@ -10,13 +10,15 @@ #define AHCI_PCI_BAR 0x24 #define AHCI_MAX_SG56 /* hardware max is 64K */ #define AHCI_CMD_SLOT_SZ 32 -#define AHCI_MAX_CMD_SLOT 32 +#define AHCI_MAX_CMDS 32 +#define AHCI_CMD_LIST_SZ (AHCI_CMD_SLOT_SZ * AHCI_MAX_CMDS) #define AHCI_RX_FIS_SZ 256 #define AHCI_CMD_TBL_HDR_SZ0x80 #define AHCI_CMD_TBL_CDB 0x40 -#define AHCI_CMD_TBL_SZAHCI_CMD_TBL_HDR_SZ + (AHCI_MAX_SG * 32) -#define AHCI_PORT_PRIV_DMA_SZ (AHCI_CMD_SLOT_SZ * AHCI_MAX_CMD_SLOT + \ - AHCI_CMD_TBL_SZ + AHCI_RX_FIS_SZ) +#define AHCI_CMD_TBL_ITM_SZ16 +#define AHCI_CMD_TBL_SZ(AHCI_CMD_TBL_HDR_SZ + (AHCI_MAX_SG * AHCI_CMD_TBL_ITM_SZ)) +#define AHCI_PORT_PRIV_DMA_SZ (AHCI_CMD_LIST_SZ + AHCI_CMD_TBL_SZ + AHCI_RX_FIS_SZ) + #define AHCI_CMD_ATAPI (1 << 5) #define AHCI_CMD_WRITE (1 << 6) #define AHCI_CMD_PREFETCH (1 << 7) -- 2.20.1 ___ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox
[PATCH 09/16] ata: ahci: use named constants for capabilities bits
Signed-off-by: Denis Orlov --- drivers/ata/ahci.c | 51 +++--- drivers/ata/ahci.h | 30 +++ 2 files changed, 52 insertions(+), 29 deletions(-) diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 2d7b527755..1d8099c2ee 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -500,7 +500,7 @@ void ahci_print_info(struct ahci_device *ahci) cap2 = ahci_ioread(ahci, HOST_CAP2); impl = ahci->port_map; - speed = (cap >> 20) & 0xf; + speed = (cap & HOST_CAP_ISS) >> 20; if (speed == 1) speed_s = "1.5"; else if (speed == 2) @@ -518,32 +518,33 @@ void ahci_print_info(struct ahci_device *ahci) (vers >> 16) & 0xff, (vers >> 8) & 0xff, vers & 0xff, - ((cap >> 8) & 0x1f) + 1, (cap & 0x1f) + 1, speed_s, impl, scc_s); + ((cap & HOST_CAP_NCS) >> 8) + 1, + (cap & HOST_CAP_NP) + 1, speed_s, impl, scc_s); printf("flags: " "%s%s%s%s%s%s%s" "%s%s%s%s%s%s%s" "%s%s%s%s%s%s\n", - cap & (1 << 31) ? "64bit " : "", - cap & (1 << 30) ? "ncq " : "", - cap & (1 << 28) ? "ilck " : "", - cap & (1 << 27) ? "stag " : "", - cap & (1 << 26) ? "pm " : "", - cap & (1 << 25) ? "led " : "", - cap & (1 << 24) ? "clo " : "", - cap & (1 << 19) ? "nz " : "", - cap & (1 << 18) ? "only " : "", - cap & (1 << 17) ? "pmp " : "", - cap & (1 << 16) ? "fbss " : "", - cap & (1 << 15) ? "pio " : "", - cap & (1 << 14) ? "slum " : "", - cap & (1 << 13) ? "part " : "", - cap & (1 << 7) ? "ccc " : "", - cap & (1 << 6) ? "ems " : "", - cap & (1 << 5) ? "sxs " : "", - cap2 & (1 << 2) ? "apst " : "", - cap2 & (1 << 1) ? "nvmp " : "", - cap2 & (1 << 0) ? "boh " : ""); + cap & HOST_CAP_64 ? "64bit " : "", + cap & HOST_CAP_NCQ ? "ncq " : "", + cap & HOST_CAP_SMPS ? "ilck " : "", + cap & HOST_CAP_SSS ? "stag " : "", + cap & HOST_CAP_ALPM ? "pm " : "", + cap & HOST_CAP_LED ? "led " : "", + cap & HOST_CAP_CLO ? "clo " : "", + cap & HOST_CAP_RESERVED ? "nz " : "", + cap & HOST_CAP_ONLY ? "only " : "", + cap & HOST_CAP_SPM ? "pmp " : "", + cap & HOST_CAP_FBS ? "fbss " : "", + cap & HOST_CAP_PIO_MULTI ? "pio " : "", + cap & HOST_CAP_SSC ? "slum " : "", + cap & HOST_CAP_PART ? "part " : "", + cap & HOST_CAP_CCC ? "ccc " : "", + cap & HOST_CAP_EMS ? "ems " : "", + cap & HOST_CAP_SXS ? "sxs " : "", + cap2 & HOST_CAP2_APST ? "apst " : "", + cap2 & HOST_CAP2_NVMHCI ? "nvmp " : "", + cap2 & HOST_CAP2_BOH ? "boh " : ""); } void ahci_info(struct device_d *dev) @@ -583,8 +584,8 @@ int ahci_add_host(struct ahci_device *ahci) ahci_debug(ahci, "ahci_host_init: start\n"); cap_save = ahci_ioread(ahci, HOST_CAP); - cap_save &= (HOST_SMPS | HOST_SPM); - cap_save |= HOST_SSS; /* Staggered Spin-up. Not needed. */ + cap_save &= (HOST_CAP_SMPS | HOST_CAP_SPM); + cap_save |= HOST_CAP_SSS; /* Staggered Spin-up. Not needed. */ /* global controller reset */ tmp = ahci_ioread(ahci, HOST_CTL); @@ -607,7 +608,7 @@ int ahci_add_host(struct ahci_device *ahci) ahci->cap = ahci_ioread(ahci, HOST_CAP); ahci->port_map = ahci_ioread(ahci
[PATCH] ata: ahci: use correct macro when calculating offsets in dma memory
The macro that indicates the size of a single element in the command list was incorrectly used instead of the macro that stands for the size of the whole list. Signed-off-by: Denis Orlov --- drivers/ata/ahci.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index f707efb50f..eb9e1bd133 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -310,15 +310,15 @@ static int ahci_init_port(struct ahci_port *ahci_port) /* * Second item: Received-FIS area */ - ahci_port->rx_fis = mem + AHCI_CMD_SLOT_SZ; - ahci_port->rx_fis_dma = mem_dma + AHCI_CMD_SLOT_SZ; + ahci_port->rx_fis = mem + AHCI_CMD_LIST_SZ; + ahci_port->rx_fis_dma = mem_dma + AHCI_CMD_LIST_SZ; /* * Third item: data area for storing a single command * and its scatter-gather table */ - ahci_port->cmd_tbl = mem + AHCI_CMD_SLOT_SZ + AHCI_RX_FIS_SZ; - ahci_port->cmd_tbl_dma = mem_dma + AHCI_CMD_SLOT_SZ + AHCI_RX_FIS_SZ; + ahci_port->cmd_tbl = mem + AHCI_CMD_LIST_SZ + AHCI_RX_FIS_SZ; + ahci_port->cmd_tbl_dma = mem_dma + AHCI_CMD_LIST_SZ + AHCI_RX_FIS_SZ; ahci_port_debug(ahci_port, "cmd_tbl = 0x%p (0x%pa)\n", ahci_port->cmd_tbl, ahci_port->cmd_tbl_dma); -- 2.20.1 ___ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox
[PATCH] net: e1000: fix s in log messages
We do not have an edev.dev set up yet when we are filling in the device structure and reading an EEPROM in probe. Besides, using hw->dev for those messages seems more appropriate. Signed-off-by: Denis Orlov --- drivers/net/e1000/eeprom.c | 6 +++--- drivers/net/e1000/main.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/e1000/eeprom.c b/drivers/net/e1000/eeprom.c index 1072bc54ef..27143bd6d0 100644 --- a/drivers/net/e1000/eeprom.c +++ b/drivers/net/e1000/eeprom.c @@ -800,7 +800,7 @@ int e1000_validate_eeprom_checksum(struct e1000_hw *hw) /* Read the EEPROM */ if (e1000_read_eeprom(hw, 0, EEPROM_CHECKSUM_REG + 1, buf) < 0) { - dev_err(>edev.dev, "Unable to read EEPROM!\n"); + dev_err(hw->dev, "Unable to read EEPROM!\n"); return -E1000_ERR_EEPROM; } @@ -816,8 +816,8 @@ int e1000_validate_eeprom_checksum(struct e1000_hw *hw) return 0; /* Hrm, verification failed, print an error */ - dev_err(>edev.dev, "EEPROM checksum is incorrect!\n"); - dev_err(>edev.dev, " ...register was 0x%04hx, calculated 0x%04hx\n", + dev_err(hw->dev, "EEPROM checksum is incorrect!\n"); + dev_err(hw->dev, " ...register was 0x%04hx, calculated 0x%04hx\n", checksum_reg, checksum); return -E1000_ERR_EEPROM; diff --git a/drivers/net/e1000/main.c b/drivers/net/e1000/main.c index 363730de0a..1f84cf2949 100644 --- a/drivers/net/e1000/main.c +++ b/drivers/net/e1000/main.c @@ -3226,7 +3226,7 @@ static int e1000_sw_init(struct eth_device *edev) /* identify the MAC */ result = e1000_set_mac_type(hw); if (result) { - dev_err(>edev.dev, "Unknown MAC Type\n"); + dev_err(hw->dev, "Unknown MAC Type\n"); return result; } -- 2.30.2
[PATCH] reset: add missing stub for of_reset_control_get()
Every other function in reset.h has a corresponding stub that is used when the option RESET_CONTROLLER is disabled in config. This allows for code that uses this function to still be compilable even when the reset controller subsystem is disabled. Signed-off-by: Denis Orlov --- include/linux/reset.h | 6 ++ 1 file changed, 6 insertions(+) diff --git a/include/linux/reset.h b/include/linux/reset.h index c1282a84c7..2d788547f4 100644 --- a/include/linux/reset.h +++ b/include/linux/reset.h @@ -48,6 +48,12 @@ static inline int reset_control_deassert(struct reset_control *rstc) return 0; } +static inline struct reset_control * +of_reset_control_get(struct device_node *node, const char *id) +{ + return NULL; +} + static inline struct reset_control * reset_control_get(struct device_d *dev, const char *id) { -- 2.30.2
[PATCH] ddr_spd: use unsigned type for crc bytes in DDR3/4 SPD check
Using signed char type for computed CRC bytes leads to them being sign extended on comparison with unsigned char values from SPD EEPROM struct. This happens as when being compared those values undergo integer promotion that converts them into ints, sign extending signed types. Having most significant byte set for any of computed CRC bytes thus results in the mismatch being erroneously detected. While at it, also remove redundant type casts. Signed-off-by: Denis Orlov --- common/ddr_spd.c | 20 ++-- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/common/ddr_spd.c b/common/ddr_spd.c index 52773178e7..dd3b8511e6 100644 --- a/common/ddr_spd.c +++ b/common/ddr_spd.c @@ -65,8 +65,8 @@ int ddr3_spd_check(const struct ddr3_spd_eeprom *spd) char *p = (char *)spd; int csum16; int len; - char crc_lsb; /* byte 126 */ - char crc_msb; /* byte 127 */ + unsigned char crc_lsb; /* byte 126 */ + unsigned char crc_msb; /* byte 127 */ /* * SPD byte0[7] - CRC coverage @@ -77,8 +77,8 @@ int ddr3_spd_check(const struct ddr3_spd_eeprom *spd) len = !(spd->info_size_crc & 0x80) ? 126 : 117; csum16 = crc_itu_t(0, p, len); - crc_lsb = (char) (csum16 & 0xff); - crc_msb = (char) (csum16 >> 8); + crc_lsb = csum16 & 0xff; + crc_msb = csum16 >> 8; if (spd->crc[0] == crc_lsb && spd->crc[1] == crc_msb) { return 0; @@ -96,14 +96,14 @@ int ddr4_spd_check(const struct ddr4_spd_eeprom *spd) char *p = (char *)spd; int csum16; int len; - char crc_lsb; /* byte 126 */ - char crc_msb; /* byte 127 */ + unsigned char crc_lsb; /* byte 126 */ + unsigned char crc_msb; /* byte 127 */ len = 126; csum16 = crc_itu_t(0, p, len); - crc_lsb = (char) (csum16 & 0xff); - crc_msb = (char) (csum16 >> 8); + crc_lsb = csum16 & 0xff; + crc_msb = csum16 >> 8; if (spd->crc[0] != crc_lsb || spd->crc[1] != crc_msb) { printf("SPD checksum unexpected.\n" @@ -117,8 +117,8 @@ int ddr4_spd_check(const struct ddr4_spd_eeprom *spd) len = 126; csum16 = crc_itu_t(0, p, len); - crc_lsb = (char) (csum16 & 0xff); - crc_msb = (char) (csum16 >> 8); + crc_lsb = csum16 & 0xff; + crc_msb = csum16 >> 8; if (spd->mod_section.uc[126] != crc_lsb || spd->mod_section.uc[127] != crc_msb) { -- 2.30.2
[PATCH] net: e1000: read EEPROM through EERD register on 8257x adapters
For some reason, we would only use EERD if Flash is used as non-volatile memory. However, looking at e1000e driver sources from Linux this is how they are reading NVM on those cards for both EEPROM and Flash. This fixes issues with reading EEPROM in driver on QEMU emulated 82574 PCIe card. Signed-off-by: Denis Orlov --- drivers/net/e1000/eeprom.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/e1000/eeprom.c b/drivers/net/e1000/eeprom.c index 27143bd6d0..c90faf3a58 100644 --- a/drivers/net/e1000/eeprom.c +++ b/drivers/net/e1000/eeprom.c @@ -495,6 +495,7 @@ int32_t e1000_init_eeprom_params(struct e1000_hw *hw) case e1000_82571: case e1000_82572: e1000_eeprom_uses_spi(eeprom, eecd); + eeprom->read = e1000_read_eeprom_eerd; break; case e1000_82573: @@ -502,7 +503,6 @@ int32_t e1000_init_eeprom_params(struct e1000_hw *hw) if (e1000_is_onboard_nvm_eeprom(hw)) { e1000_eeprom_uses_spi(eeprom, eecd); } else { - eeprom->read = e1000_read_eeprom_eerd; eeprom->type = e1000_eeprom_flash; eeprom->word_size = 2048; @@ -513,6 +513,7 @@ int32_t e1000_init_eeprom_params(struct e1000_hw *hw) eecd &= ~E1000_EECD_AUPDEN; e1000_write_reg(hw, E1000_EECD, eecd); } + eeprom->read = e1000_read_eeprom_eerd; break; case e1000_80003es2lan: -- 2.30.2
[PATCH] lib: string: remove duplicated function
We have two functions that are doing the same thing: 'strncasecmp' and 'strnicmp'. The only difference between them is that the latter is correctly handling the len argument of 0. So rename it into the former one ('strncasecmp', as it is the POSIX name for this function), deleting the other implementation. As no one is actually using 'strnicmp', no other code requires any fixes. This change is effectively forwarded from the Linux commits 'lib/string.c: remove duplicated function' (hash cd514e727b18ff4d189b8e268db13729a4175091) and 'lib/string.c: remove strnicmp()' (hash af3cd13501eb04ca61d017ff4406f1cbffafdc04). Signed-off-by: Denis Orlov --- include/linux/string.h | 3 --- lib/string.c | 48 +++--- 2 files changed, 17 insertions(+), 34 deletions(-) diff --git a/include/linux/string.h b/include/linux/string.h index 0c79d3e5cf..cd81ab1396 100644 --- a/include/linux/string.h +++ b/include/linux/string.h @@ -58,9 +58,6 @@ extern int strcmp(const char *,const char *); #ifndef __HAVE_ARCH_STRNCMP extern int strncmp(const char *,const char *,__kernel_size_t); #endif -#ifndef __HAVE_ARCH_STRNICMP -extern int strnicmp(const char *, const char *, __kernel_size_t); -#endif #ifndef __HAVE_ARCH_STRCASECMP extern int strcasecmp(const char *s1, const char *s2); #endif diff --git a/lib/string.c b/lib/string.c index 005f4532bb..8ea68044cc 100644 --- a/lib/string.c +++ b/lib/string.c @@ -24,14 +24,28 @@ #include #include -#ifndef __HAVE_ARCH_STRNICMP +#ifndef __HAVE_ARCH_STRCASECMP +int strcasecmp(const char *s1, const char *s2) +{ + int c1, c2; + + do { + c1 = tolower(*s1++); + c2 = tolower(*s2++); + } while (c1 == c2 && c1 != 0); + return c1 - c2; +} +EXPORT_SYMBOL(strcasecmp); +#endif + +#ifndef __HAVE_ARCH_STRNCASECMP /** - * strnicmp - Case insensitive, length-limited string comparison + * strncasecmp - Case insensitive, length-limited string comparison * @s1: One string * @s2: The other string * @len: the maximum number of characters to compare */ -int strnicmp(const char *s1, const char *s2, size_t len) +int strncasecmp(const char *s1, const char *s2, size_t len) { /* Yes, Virginia, it had better be unsigned */ unsigned char c1, c2; @@ -53,34 +67,6 @@ int strnicmp(const char *s1, const char *s2, size_t len) } while (--len); return (int)c1 - (int)c2; } -EXPORT_SYMBOL(strnicmp); -#endif - -#ifndef __HAVE_ARCH_STRCASECMP -int strcasecmp(const char *s1, const char *s2) -{ - int c1, c2; - - do { - c1 = tolower(*s1++); - c2 = tolower(*s2++); - } while (c1 == c2 && c1 != 0); - return c1 - c2; -} -EXPORT_SYMBOL(strcasecmp); -#endif - -#ifndef __HAVE_ARCH_STRNCASECMP -int strncasecmp(const char *s1, const char *s2, size_t n) -{ - int c1, c2; - - do { - c1 = tolower(*s1++); - c2 = tolower(*s2++); - } while ((--n > 0) && c1 == c2 && c1 != 0); - return c1 - c2; -} EXPORT_SYMBOL(strncasecmp); #endif -- 2.30.2
[PATCH 1/3] dma: use dma/cpu conversions correctly in dma_map/unmap_single
We should not treat dma handles as if they correspond one-to-one to the virtual addresses in common code. So make sure that dma handles are properly passed to the dma_sync_single_for_* functions. Otherwise, it just doesn't make much sense, as dma_sync funcs will receive proper dma handles when called directly, and a virtual address treated as one when called from dma_map funcs. Signed-off-by: Denis Orlov --- drivers/dma/map.c | 10 -- 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/dma/map.c b/drivers/dma/map.c index 114c0f7db3..fea04c38a3 100644 --- a/drivers/dma/map.c +++ b/drivers/dma/map.c @@ -23,17 +23,15 @@ static inline void *dma_to_cpu(struct device *dev, dma_addr_t addr) dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size, enum dma_data_direction dir) { - unsigned long addr = (unsigned long)ptr; + dma_addr_t ret = cpu_to_dma(dev, ptr); - dma_sync_single_for_device(addr, size, dir); + dma_sync_single_for_device(ret, size, dir); - return cpu_to_dma(dev, ptr); + return ret; } void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size, enum dma_data_direction dir) { - unsigned long addr = (unsigned long)dma_to_cpu(dev, dma_addr); - - dma_sync_single_for_cpu(addr, size, dir); + dma_sync_single_for_cpu(dma_addr, size, dir); } -- 2.30.2
[PATCH 0/3] MIPS: dma-default: fix dma_sync_single_for_*
This fixes a few issues with streaming DMA functions, which should make those work on real hardware. It also improves the code a bit, removing unnecessary cache flushing in some cases. Denis Orlov (3): dma: use dma/cpu conversions correctly in dma_map/unmap_single MIPS: dma-default: use virtual addresses when flushing caches MIPS: dma-default: do not flush caches in dma_sync_single_* excessively arch/mips/lib/dma-default.c | 36 +++- drivers/dma/map.c | 10 -- 2 files changed, 23 insertions(+), 23 deletions(-) -- 2.30.2
[PATCH 2/3] MIPS: dma-default: use virtual addresses when flushing caches
Cache flushing functions expect virtual addresses, so make sure those are properly converted from the physical ones in dma_sync_single_for_*. QEMU doesn't care as it ignores cache instructions, but without such change this code would result in TLB exceptions on real hardware. Signed-off-by: Denis Orlov --- arch/mips/lib/dma-default.c | 8 ++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/arch/mips/lib/dma-default.c b/arch/mips/lib/dma-default.c index 48176e5d28..f6c750b8ac 100644 --- a/arch/mips/lib/dma-default.c +++ b/arch/mips/lib/dma-default.c @@ -30,11 +30,15 @@ static inline void __dma_sync_mips(unsigned long addr, size_t size, void dma_sync_single_for_cpu(dma_addr_t address, size_t size, enum dma_data_direction dir) { - __dma_sync_mips(address, size, dir); + unsigned long virt = (unsigned long)phys_to_virt(address); + + __dma_sync_mips(virt, size, dir); } void dma_sync_single_for_device(dma_addr_t address, size_t size, enum dma_data_direction dir) { - __dma_sync_mips(address, size, dir); + unsigned long virt = (unsigned long)phys_to_virt(address); + + __dma_sync_mips(virt, size, dir); } -- 2.30.2
[PATCH 3/3] MIPS: dma-default: do not flush caches in dma_sync_single_* excessively
Change the logic to be different depending on whether we are doing synchronization for a cpu or a device. This gets rid of unnecessary cache flushing in some cases. While at it, also simplify code a bit, collapsing two cases with the same code in a switch statement in dma_sync_single_for_device(). The functional change itself is taken from Linux commit 'MIPS: make dma_sync_*_for_cpu a little less overzealous' (hash: cbf1449ba5aec9cf4c68b69f899391a8d42e9b8f). Signed-off-by: Denis Orlov --- arch/mips/lib/dma-default.c | 36 +--- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/arch/mips/lib/dma-default.c b/arch/mips/lib/dma-default.c index f6c750b8ac..0347d7a7db 100644 --- a/arch/mips/lib/dma-default.c +++ b/arch/mips/lib/dma-default.c @@ -6,39 +6,37 @@ #include #include -static inline void __dma_sync_mips(unsigned long addr, size_t size, - enum dma_data_direction direction) +void dma_sync_single_for_cpu(dma_addr_t address, size_t size, +enum dma_data_direction dir) { - switch (direction) { + unsigned long virt = (unsigned long)phys_to_virt(address); + + switch (dir) { case DMA_TO_DEVICE: - dma_flush_range(addr, addr + size); break; - case DMA_FROM_DEVICE: - dma_inv_range(addr, addr + size); - break; - case DMA_BIDIRECTIONAL: - dma_flush_range(addr, addr + size); + dma_inv_range(virt, virt + size); break; - default: BUG(); } } -void dma_sync_single_for_cpu(dma_addr_t address, size_t size, -enum dma_data_direction dir) -{ - unsigned long virt = (unsigned long)phys_to_virt(address); - - __dma_sync_mips(virt, size, dir); -} - void dma_sync_single_for_device(dma_addr_t address, size_t size, enum dma_data_direction dir) { unsigned long virt = (unsigned long)phys_to_virt(address); - __dma_sync_mips(virt, size, dir); + switch (dir) { + case DMA_FROM_DEVICE: + dma_inv_range(virt, virt + size); + break; + case DMA_TO_DEVICE: + case DMA_BIDIRECTIONAL: + dma_flush_range(virt, virt + size); + break; + default: + BUG(); + } } -- 2.30.2
[PATCH 2/3] MIPS: bootm: do not leak memory on error in of_overlay_load_firmware()
Signed-off-by: Denis Orlov --- arch/mips/lib/bootm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/lib/bootm.c b/arch/mips/lib/bootm.c index 95e9dc0d7d..69ce9b3904 100644 --- a/arch/mips/lib/bootm.c +++ b/arch/mips/lib/bootm.c @@ -69,7 +69,7 @@ static int do_bootm_elf(struct image_data *data) ret = of_overlay_load_firmware(); if (ret) - return ret; + goto bootm_free_fdt; shutdown_barebox(); -- 2.30.2
[PATCH 3/3] MIPS: bootm: remove unnecessary phys/virt conversions
They are not doing anything there - we should already have proper virtual addresses represented by those pointers. Signed-off-by: Denis Orlov --- arch/mips/lib/bootm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/mips/lib/bootm.c b/arch/mips/lib/bootm.c index 69ce9b3904..19d82ec375 100644 --- a/arch/mips/lib/bootm.c +++ b/arch/mips/lib/bootm.c @@ -62,7 +62,7 @@ static int do_bootm_elf(struct image_data *data) } pr_info("Starting application at 0x%08lx, dts 0x%08lx...\n", - phys_to_virt(data->os_address), data->of_root_node); + data->os_address, data->of_root_node); if (data->dryrun) goto bootm_free_fdt; @@ -75,7 +75,7 @@ static int do_bootm_elf(struct image_data *data) entry = (void *) (unsigned long) data->os_address; - entry(-2, phys_to_virt((unsigned long)fdt)); + entry(-2, fdt); pr_err("ELF application terminated\n"); ret = -EINVAL; -- 2.30.2
[PATCH 1/3] MIPS: bootm: do not free fdt pointer that contains an error
Also add a proper error message. Signed-off-by: Denis Orlov --- arch/mips/lib/bootm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/mips/lib/bootm.c b/arch/mips/lib/bootm.c index 655535737e..95e9dc0d7d 100644 --- a/arch/mips/lib/bootm.c +++ b/arch/mips/lib/bootm.c @@ -57,8 +57,8 @@ static int do_bootm_elf(struct image_data *data) fdt = bootm_get_devicetree(data); if (IS_ERR(fdt)) { - ret = PTR_ERR(fdt); - goto bootm_free_fdt; + pr_err("Failed to load dtb\n"); + return PTR_ERR(fdt); } pr_info("Starting application at 0x%08lx, dts 0x%08lx...\n", -- 2.30.2
[PATCH 0/3] MIPS: bootm: tiny fixes in do_bootm_elf()
Denis Orlov (3): MIPS: bootm: do not free fdt pointer that contains an error MIPS: bootm: do not leak memory on error in of_overlay_load_firmware() MIPS: bootm: remove unnecessary phys/virt conversions arch/mips/lib/bootm.c | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) -- 2.30.2
[PATCH] common: elf: use proper field to get segment memory size
For a program header, the value of 'p_filesz' may be less than the one of 'p_memsz', in which case the leftover amount of space should be filled with zeroes. This is done correctly when loading elf to memory. However, when we are requesting memory beforehand we do pass the value of 'p_filesz', instead of 'p_memsz', to 'request_sdram_region', resulting in potentially smaller amount of memory to be reserved. As 'p_memsz' is always greater or equal to 'p_filesz', use only the former for checking memory requirements in 'request_elf_segment'. Signed-off-by: Denis Orlov --- common/elf.c | 7 +++ 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/common/elf.c b/common/elf.c index eec62cad61..c9b3d7bb37 100644 --- a/common/elf.c +++ b/common/elf.c @@ -59,14 +59,13 @@ static int request_elf_segment(struct elf_image *elf, void *phdr) { void *dst = (void *) (phys_addr_t) elf_phdr_p_paddr(elf, phdr); int ret; - u64 p_filesz = elf_phdr_p_filesz(elf, phdr); u64 p_memsz = elf_phdr_p_memsz(elf, phdr); /* we care only about PT_LOAD segments */ if (elf_phdr_p_type(elf, phdr) != PT_LOAD) return 0; - if (!p_filesz) + if (!p_memsz) return 0; if (dst < elf->low_addr) @@ -74,9 +73,9 @@ static int request_elf_segment(struct elf_image *elf, void *phdr) if (dst + p_memsz > elf->high_addr) elf->high_addr = dst + p_memsz; - pr_debug("Requesting segment 0x%p (%llu bytes)\n", dst, p_filesz); + pr_debug("Requesting segment 0x%p (%llu bytes)\n", dst, p_memsz); - ret = elf_request_region(elf, (resource_size_t)dst, p_filesz, phdr); + ret = elf_request_region(elf, (resource_size_t)dst, p_memsz, phdr); if (ret) return ret; -- 2.30.2
Re: [RFC 1/2] dma: rework dma_sync_single interface
Hi! On Fri, 3 Mar 2023 at 13:06, Sascha Hauer wrote: > > Hi Denis, > > On Tue, Feb 28, 2023 at 01:32:47PM +0300, Denis Orlov wrote: > > -#ifndef dma_sync_single_for_device > > -static inline void dma_sync_single_for_device(dma_addr_t address, size_t > > size, > > - enum dma_data_direction dir) > > +#ifndef arch_sync_dma_for_device > > +void arch_sync_dma_for_device(void *vaddr, size_t size, > > + enum dma_data_direction dir); > > { > > - barrier_data((void *)address); > > + barrier_data(address); > > } > > #endif > > "static inline" is missing here. Also "address" should be "vaddr". Ouch, I will be sure to recheck the code before sending v2. > > With that fixed imx_v7_defconfig compiles successfully and from what I > can tell also works. > > I haven't looked into this patch yet. Passing a struct device to the > dma_sync functions is a step into the right direction for sure. To be short, the gist of the changes corresponds to removing the discrepancy between dma_map and dma_sync code that comes from dma_map doing dma/cpu conversions and dma_sync not doing them. To do this without resorting to code duplication, carry out such conversions in common dma_sync functions and call arch-specific ones for the syncing part. The common funcs also get a device pointer as the first argument to be able to apply this remapping. After the dma/cpu conversion we do get a virtual address, so make sure that arch-specific funcs explicitly take pointers as arguments. > > Ultimately both patches should be merged to avoid bisecting failures. Yeah, sure. Was going to do that anyway. I just didn’t want to dump all of the changes in one patch while sending this as an RFC. > > Sascha > > > -- > Pengutronix e.K. | | > Steuerwalder Str. 21 | http://www.pengutronix.de/ | > 31137 Hildesheim, Germany | Phone: +49-5121-206917-0| > Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- |
[RFC 2/2] dma: update dma_sync_single uses in drivers
With the previous commit that changes dma_sync_single_for_* API, every callsite that uses it needs to be updated. Driver code is now required to pass a corresponding pointer to device struct as the first argument. Some drivers don't seem to have an appropriate device handle handy, so just use NULL for those. This should not make any functional change, as there is no driver at the moment that requires non 1-to-1 dma mappings, and thus would actually utilize those device pointers. Signed-off-by: Denis Orlov --- arch/arm/mach-bcm283x/mbox.c| 4 ++-- drivers/crypto/caam/caam-blobgen.c | 28 ++-- drivers/crypto/caam/caamrng.c | 6 +++--- drivers/crypto/caam/rng_self_test.c | 6 +++--- drivers/mci/dove-sdhci.c| 8 drivers/mci/stm32_sdmmc2.c | 8 drivers/mci/tegra-sdmmc.c | 8 drivers/net/ag71xx.c| 8 drivers/net/arc_emac.c | 10 +- drivers/net/at91_ether.c| 8 drivers/net/bcmgenet.c | 4 ++-- drivers/net/cpsw.c | 8 drivers/net/davinci_emac.c | 8 drivers/net/designware.c| 10 +- drivers/net/designware_eqos.c | 4 ++-- drivers/net/e1000/main.c| 4 ++-- drivers/net/fec_imx.c | 4 ++-- drivers/net/fsl-fman.c | 7 --- drivers/net/macb.c | 20 ++-- drivers/net/mvneta.c| 8 drivers/net/orion-gbe.c | 8 drivers/net/rtl8169.c | 12 +++- drivers/usb/gadget/fsl_udc.c| 4 ++-- drivers/usb/host/ohci-hcd.c | 6 +++--- 24 files changed, 102 insertions(+), 99 deletions(-) diff --git a/arch/arm/mach-bcm283x/mbox.c b/arch/arm/mach-bcm283x/mbox.c index 4959a1a652..c432c1153f 100644 --- a/arch/arm/mach-bcm283x/mbox.c +++ b/arch/arm/mach-bcm283x/mbox.c @@ -66,7 +66,7 @@ static int bcm2835_mbox_call_raw(u32 chan, struct bcm2835_mbox_hdr *buffer, /* Send the request */ val = BCM2835_MBOX_PACK(chan, send); pr_debug("mbox: TX raw: 0x%08x\n", val); - dma_sync_single_for_device((unsigned long)send, buffer->buf_size, + dma_sync_single_for_device(NULL, (unsigned long)send, buffer->buf_size, DMA_BIDIRECTIONAL); writel(val, mbox_base + MAIL1_WRT); @@ -84,7 +84,7 @@ static int bcm2835_mbox_call_raw(u32 chan, struct bcm2835_mbox_hdr *buffer, /* Read the response */ val = readl(mbox_base + MAIL0_RD); pr_debug("mbox: RX raw: 0x%08x\n", val); - dma_sync_single_for_cpu((unsigned long)send, buffer->buf_size, + dma_sync_single_for_cpu(NULL, (unsigned long)send, buffer->buf_size, DMA_BIDIRECTIONAL); /* Validate the response */ diff --git a/drivers/crypto/caam/caam-blobgen.c b/drivers/crypto/caam/caam-blobgen.c index 5ab7ad3a6e..1ce636a716 100644 --- a/drivers/crypto/caam/caam-blobgen.c +++ b/drivers/crypto/caam/caam-blobgen.c @@ -129,14 +129,14 @@ static int caam_blob_decrypt(struct blobgen *bg, const char *modifier, jr_jobdesc_blob_decap(ctx, modifier_len, blobsize); - dma_sync_single_for_device((unsigned long)desc, desc_bytes(desc), + dma_sync_single_for_device(jrdev, (unsigned long)desc, desc_bytes(desc), DMA_TO_DEVICE); - dma_sync_single_for_device((unsigned long)modifier, modifier_len, + dma_sync_single_for_device(jrdev, (unsigned long)modifier, modifier_len, DMA_TO_DEVICE); - dma_sync_single_for_device((unsigned long)*plain, *plainsize, + dma_sync_single_for_device(jrdev, (unsigned long)*plain, *plainsize, DMA_FROM_DEVICE); - dma_sync_single_for_device((unsigned long)blob, blobsize, + dma_sync_single_for_device(jrdev, (unsigned long)blob, blobsize, DMA_TO_DEVICE); testres.err = 0; @@ -147,11 +147,11 @@ static int caam_blob_decrypt(struct blobgen *bg, const char *modifier, ret = testres.err; - dma_sync_single_for_cpu((unsigned long)modifier, modifier_len, + dma_sync_single_for_cpu(jrdev, (unsigned long)modifier, modifier_len, DMA_TO_DEVICE); - dma_sync_single_for_cpu((unsigned long)*plain, *plainsize, + dma_sync_single_for_cpu(jrdev, (unsigned long)*plain, *plainsize, DMA_FROM_DEVICE); - dma_sync_single_for_cpu((unsigned long)blob, blobsize, + dma_sync_single_for_cpu(jrdev, (unsigned long)blob, blobsize, DMA_TO_DEVICE); return ret; @@ -178,14 +178,14 @@ static int caam_blob_encrypt(struct blobgen *bg, const char *modifier, jr_jobdesc_blob_en
[RFC 1/2] dma: rework dma_sync_single interface
Currently, a lot of code is handling dma_addr_t values as if they unconditionally hold CPU addresses. However, this is not true for every architecture. For example, MIPS requires an explicit conversion from a physical address space to a virtual address that corresponds to some (currently used one in our case) address space segment for this pointer to be valid and usable. Another issue is that DMA ranges, specified in device trees, will not work this way. To get from a virtual address to a dma handle and vice versa we need to add/subtract some offset, which is calculated from "dma-ranges" property. As it seems, no driver actually uses this at the moment, but as there exists code that does this conversions, which is used in dma_map_single(), it seems reasonable to utilize it for dma_sync_single_for_*() too. I wonder if there are some actual use cases that would not be properly covered by this change, for example if there are dma/cpu conversions that we may have to do in architecture-specific code and which require virtual addresses. For those, we cannot have dma_sync_single_for_* functions that just call arch_sync_single_for_* only for the CPU cache syncronization part, i.e. we would have to do all dma/cpu conversions in arch-specific code, unlike how it is done in this patch. This would lead to some code duplication though. TODO: dma_alloc/free_coherent do need same kind of changes to utilise cpu/dma conversions properly Signed-off-by: Denis Orlov --- arch/arm/cpu/mmu-common.c| 9 +-- arch/arm/cpu/mmu.c | 17 +++-- arch/arm/cpu/mmu_64.c| 13 ++-- arch/arm/include/asm/dma.h | 12 ++-- arch/kvx/lib/dma-default.c | 16 +++-- arch/mips/lib/dma-default.c | 12 ++-- arch/riscv/cpu/dma.c | 23 +++--- arch/riscv/include/asm/dma.h | 4 +- arch/sandbox/include/asm/dma.h | 12 ++-- arch/x86/include/asm/dma.h | 12 ++-- drivers/dma/Makefile | 1 - drivers/dma/map.c| 39 --- drivers/soc/sifive/sifive_l2_cache.c | 2 +- drivers/soc/starfive/jh7100_dma.c| 2 +- include/dma.h| 101 +++ 15 files changed, 138 insertions(+), 137 deletions(-) delete mode 100644 drivers/dma/map.c diff --git a/arch/arm/cpu/mmu-common.c b/arch/arm/cpu/mmu-common.c index 488a189f1c..f523cd2660 100644 --- a/arch/arm/cpu/mmu-common.c +++ b/arch/arm/cpu/mmu-common.c @@ -13,14 +13,11 @@ #include #include "mmu.h" -void dma_sync_single_for_cpu(dma_addr_t address, size_t size, -enum dma_data_direction dir) +void arch_sync_dma_for_cpu(void *vaddr, size_t size, + enum dma_data_direction dir) { - /* -* FIXME: This function needs a device argument to support non 1:1 mappings -*/ if (dir != DMA_TO_DEVICE) - dma_inv_range((void *)address, size); + dma_inv_range(vaddr, size); } void *dma_alloc_map(size_t size, dma_addr_t *dma_handle, unsigned flags) diff --git a/arch/arm/cpu/mmu.c b/arch/arm/cpu/mmu.c index 6388e1bf14..c1615682fc 100644 --- a/arch/arm/cpu/mmu.c +++ b/arch/arm/cpu/mmu.c @@ -494,20 +494,19 @@ void *dma_alloc_writecombine(size_t size, dma_addr_t *dma_handle) return dma_alloc_map(size, dma_handle, ARCH_MAP_WRITECOMBINE); } -void dma_sync_single_for_device(dma_addr_t address, size_t size, - enum dma_data_direction dir) +void arch_sync_dma_for_device(void *vaddr, size_t size, + enum dma_data_direction dir) { - /* -* FIXME: This function needs a device argument to support non 1:1 mappings -*/ + unsigned long start = (unsigned long)vaddr; + unsigned long end = start + size; if (dir == DMA_FROM_DEVICE) { - __dma_inv_range(address, address + size); + __dma_inv_range(start, end); if (outer_cache.inv_range) - outer_cache.inv_range(address, address + size); + outer_cache.inv_range(start, end); } else { - __dma_clean_range(address, address + size); + __dma_clean_range(start, end); if (outer_cache.clean_range) - outer_cache.clean_range(address, address + size); + outer_cache.clean_range(start, end); } } diff --git a/arch/arm/cpu/mmu_64.c b/arch/arm/cpu/mmu_64.c index f43ac9a121..e5b0d55e71 100644 --- a/arch/arm/cpu/mmu_64.c +++ b/arch/arm/cpu/mmu_64.c @@ -249,15 +249,14 @@ void dma_flush_range(void *ptr, size_t size) v8_flush_dcache_range(start, end); } -void dma_sync_single_for_device(dma_addr_t address, size_t size, -enum dma_data_direction dir) +void arch_sync_dma_for_device(void *vaddr, size_t size, + enum dm
[RFC 0/2] dma: clean up streaming DMA API
This fixes some incoherence between dma_map/free_coherent() and dma_sync_single_for_*() functions. While the former do appropriate cpu/dma conversions, the latter do not. This also fixes streaming DMA for MIPS CPUs and cleans up the interface somewhat. I want to get some thoughts on whether those are the appropriate changes to make and if I missed something important. The changes are split in two parts for now so it would be easier to review them. The first commit is the main part. It contains interface changes and arch-specific code adjustments. The second one just updates the functions usage in drivers. Denis Orlov (2): dma: rework dma_sync_single interface dma: update dma_sync_single uses in drivers arch/arm/cpu/mmu-common.c| 9 +-- arch/arm/cpu/mmu.c | 17 +++-- arch/arm/cpu/mmu_64.c| 13 ++-- arch/arm/include/asm/dma.h | 12 ++-- arch/arm/mach-bcm283x/mbox.c | 4 +- arch/kvx/lib/dma-default.c | 16 +++-- arch/mips/lib/dma-default.c | 12 ++-- arch/riscv/cpu/dma.c | 23 +++--- arch/riscv/include/asm/dma.h | 4 +- arch/sandbox/include/asm/dma.h | 12 ++-- arch/x86/include/asm/dma.h | 12 ++-- drivers/crypto/caam/caam-blobgen.c | 28 drivers/crypto/caam/caamrng.c| 6 +- drivers/crypto/caam/rng_self_test.c | 6 +- drivers/dma/Makefile | 1 - drivers/dma/map.c| 39 --- drivers/mci/dove-sdhci.c | 8 +-- drivers/mci/stm32_sdmmc2.c | 8 +-- drivers/mci/tegra-sdmmc.c| 8 +-- drivers/net/ag71xx.c | 8 +-- drivers/net/arc_emac.c | 10 +-- drivers/net/at91_ether.c | 8 +-- drivers/net/bcmgenet.c | 4 +- drivers/net/cpsw.c | 8 +-- drivers/net/davinci_emac.c | 8 +-- drivers/net/designware.c | 10 +-- drivers/net/designware_eqos.c| 4 +- drivers/net/e1000/main.c | 4 +- drivers/net/fec_imx.c| 4 +- drivers/net/fsl-fman.c | 7 +- drivers/net/macb.c | 20 +++--- drivers/net/mvneta.c | 8 +-- drivers/net/orion-gbe.c | 8 +-- drivers/net/rtl8169.c| 12 ++-- drivers/soc/sifive/sifive_l2_cache.c | 2 +- drivers/soc/starfive/jh7100_dma.c| 2 +- drivers/usb/gadget/fsl_udc.c | 4 +- drivers/usb/host/ohci-hcd.c | 6 +- include/dma.h| 101 +++ 39 files changed, 240 insertions(+), 236 deletions(-) delete mode 100644 drivers/dma/map.c -- 2.30.2
[PATCH] nvme: parse partition table when registering a block device
Otherwise, we can not access file systems located on partitioned NVME drives. Signed-off-by: Denis Orlov --- drivers/nvme/host/core.c | 5 + 1 file changed, 5 insertions(+) diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index 79a5f9325e..bf9176ce09 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only #include +#include #include "nvme.h" @@ -372,6 +373,10 @@ static void nvme_alloc_ns(struct nvme_ctrl *ctrl, unsigned nsid) goto out_free_id; } + ret = parse_partition_table(>blk); + if (ret) + dev_warn(ctrl->dev, "No partition table found\n"); + return; out_free_id: kfree(id); -- 2.30.2
[PATCH 1/2] net: rtl8139: remove dependence on MIPS
This driver seems to work fine on ARM64 Virtual Machine in QEMU. Signed-off-by: Denis Orlov --- drivers/net/Kconfig | 1 - drivers/net/rtl8139.c | 2 -- 2 files changed, 3 deletions(-) diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 30de1f544c..86096c07e2 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -232,7 +232,6 @@ config DRIVER_NET_ORION config DRIVER_NET_RTL8139 bool "RealTek RTL-8139 PCI Ethernet driver" depends on PCI - depends on MIPS select PHYLIB help This is a driver for the Fast Ethernet PCI network cards based on diff --git a/drivers/net/rtl8139.c b/drivers/net/rtl8139.c index bea888f08d..617a60bfcb 100644 --- a/drivers/net/rtl8139.c +++ b/drivers/net/rtl8139.c @@ -10,8 +10,6 @@ #include #include -#include - #define RTL8139_DEBUG #undef RTL8139_DEBUG -- 2.30.2
[PATCH 2/2] net: rtl8139: fix ifdown/ifup issues
This moves PCI bus-mastering enable from 'init' to 'open', allowing to bring an interface up after bringing it down. Also add corresponding dma_free_coherent() calls into 'close', getting rid of memory leaks. Signed-off-by: Denis Orlov --- drivers/net/rtl8139.c | 8 +++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/net/rtl8139.c b/drivers/net/rtl8139.c index 617a60bfcb..1cd2ae14de 100644 --- a/drivers/net/rtl8139.c +++ b/drivers/net/rtl8139.c @@ -373,7 +373,6 @@ static int rtl8139_init_dev(struct eth_device *edev) struct rtl8139_priv *priv = edev->priv; rtl8139_chip_reset(priv); - pci_set_master(priv->pci_dev); return 0; } @@ -390,6 +389,8 @@ static int rtl8139_eth_open(struct eth_device *edev) rtl8139_init_ring(priv); rtl8139_hw_start(priv); + pci_set_master(priv->pci_dev); + ret = phy_device_connect(edev, >miibus, 0, NULL, 0, PHY_INTERFACE_MODE_NA); @@ -408,6 +409,11 @@ static void rtl8139_eth_halt(struct eth_device *edev) pci_clear_master(priv->pci_dev); + dma_free_coherent((void *)priv->tx_bufs, priv->tx_bufs_dma, + TX_BUF_TOT_LEN); + dma_free_coherent((void *)priv->rx_ring, priv->rx_ring_dma, + TX_BUF_TOT_LEN); + /* Green! Put the chip in low-power mode. */ RTL_W8(priv, Cfg9346, Cfg9346_Unlock); } -- 2.30.2
[PATCH] fixup! net: rtl8139: fix ifdown/ifup issues
Fixes a typo. Signed-off-by: Denis Orlov --- drivers/net/rtl8139.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/rtl8139.c b/drivers/net/rtl8139.c index 1cd2ae14de..5c91c10fea 100644 --- a/drivers/net/rtl8139.c +++ b/drivers/net/rtl8139.c @@ -412,7 +412,7 @@ static void rtl8139_eth_halt(struct eth_device *edev) dma_free_coherent((void *)priv->tx_bufs, priv->tx_bufs_dma, TX_BUF_TOT_LEN); dma_free_coherent((void *)priv->rx_ring, priv->rx_ring_dma, - TX_BUF_TOT_LEN); + RX_BUF_TOT_LEN); /* Green! Put the chip in low-power mode. */ RTL_W8(priv, Cfg9346, Cfg9346_Unlock); -- 2.30.2
[PATCH 1/2] net: e1000: properly map dma allocations
From: Antony Pavlov Signed-off-by: Antony Pavlov Signed-off-by: Denis Orlov --- drivers/net/e1000/e1000.h | 2 ++ drivers/net/e1000/main.c | 8 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h index 558a4ac271..d440d7540a 100644 --- a/drivers/net/e1000/e1000.h +++ b/drivers/net/e1000/e1000.h @@ -2183,7 +2183,9 @@ struct e1000_hw { struct mii_bus miibus; struct e1000_tx_desc *tx_base; + dma_addr_t tx_base_phys; struct e1000_rx_desc *rx_base; + dma_addr_t rx_base_phys; unsigned char *packet; dma_addr_t packet_dma; diff --git a/drivers/net/e1000/main.c b/drivers/net/e1000/main.c index e00bc48417..c259d72f27 100644 --- a/drivers/net/e1000/main.c +++ b/drivers/net/e1000/main.c @@ -3267,7 +3267,7 @@ static void e1000_configure_tx(struct e1000_hw *hw) unsigned long tctl; unsigned long tipg, tarc; uint32_t ipgr1, ipgr2; - const unsigned long tx_base = (unsigned long)hw->tx_base; + const unsigned long tx_base = (unsigned long)hw->tx_base_phys; e1000_write_reg(hw, E1000_TDBAL, lower_32_bits(tx_base)); e1000_write_reg(hw, E1000_TDBAH, upper_32_bits(tx_base)); @@ -3386,7 +3386,7 @@ static void e1000_setup_rctl(struct e1000_hw *hw) static void e1000_configure_rx(struct e1000_hw *hw) { unsigned long rctl, ctrl_ext; - const unsigned long rx_base = (unsigned long)hw->rx_base; + const unsigned long rx_base = (unsigned long)hw->rx_base_phys; hw->rx_tail = 0; /* make sure receives are disabled while setting up the descriptors */ @@ -3595,8 +3595,8 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *id) hw = xzalloc(sizeof(*hw)); - hw->tx_base = dma_alloc_coherent(16 * sizeof(*hw->tx_base), DMA_ADDRESS_BROKEN); - hw->rx_base = dma_alloc_coherent(16 * sizeof(*hw->rx_base), DMA_ADDRESS_BROKEN); + hw->tx_base = dma_alloc_coherent(16 * sizeof(*hw->tx_base), >tx_base_phys); + hw->rx_base = dma_alloc_coherent(16 * sizeof(*hw->rx_base), >rx_base_phys); edev = >edev; -- 2.30.2
[PATCH 0/2] make e1000 work on MIPS
With these changes, e1000 driver now works on MIPS Malta in QEMU with the corresponding network controller attached: -netdev user,tftp=/tftpboot,id=net0 -device e1000,netdev=net0 Antony Pavlov (1): net: e1000: properly map dma allocations Denis Orlov (1): dma: use virt/phys conversions when no dma_offset is specified drivers/dma/map.c | 25 ++--- drivers/net/e1000/e1000.h | 2 ++ drivers/net/e1000/main.c | 8 3 files changed, 16 insertions(+), 19 deletions(-) -- 2.30.2
[PATCH 2/2] dma: use virt/phys conversions when no dma_offset is specified
The code was assuming that in such cases we can just use cpu addresses as physical ones. This is incorrect on MIPS, the only platform that has its own virt_to_phys/phys_to_virt functions defined. This fixes issues with DMA mappings on MIPS, with e1000 PCI ethernet card now working on Malta in QEMU. Signed-off-by: Denis Orlov --- drivers/dma/map.c | 25 ++--- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/drivers/dma/map.c b/drivers/dma/map.c index a00abf6421..13dbf2840f 100644 --- a/drivers/dma/map.c +++ b/drivers/dma/map.c @@ -3,25 +3,20 @@ #include -static inline dma_addr_t cpu_to_dma(struct device *dev, - unsigned long cpu_addr) +static inline dma_addr_t cpu_to_dma(struct device *dev, void *cpu_addr) { - dma_addr_t dma_addr = cpu_addr; + if (dev && dev->dma_offset) + return (unsigned long)cpu_addr - dev->dma_offset; - if (dev) - dma_addr -= dev->dma_offset; - - return dma_addr; + return virt_to_phys(cpu_addr); } -static inline unsigned long dma_to_cpu(struct device *dev, dma_addr_t addr) +static inline void *dma_to_cpu(struct device *dev, dma_addr_t addr) { - unsigned long cpu_addr = addr; - - if (dev) - cpu_addr += dev->dma_offset; + if (dev && dev->dma_offset) + return (void *)(addr + dev->dma_offset); - return cpu_addr; + return phys_to_virt(addr); } dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size, @@ -31,13 +26,13 @@ dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size, dma_sync_single_for_device(addr, size, dir); - return cpu_to_dma(dev, addr); + return cpu_to_dma(dev, ptr); } void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size, enum dma_data_direction dir) { - unsigned long addr = dma_to_cpu(dev, dma_addr); + unsigned long addr = (unsigned long)dma_to_cpu(dev, dma_addr); dma_sync_single_for_cpu(addr, size, dir); } -- 2.30.2
[PATCH 0/4] MIPS: dma: random fixes and improvements
Denis Orlov (4): MIPS: dma: fix nullptr handling in dma_free_coherent MIPS: dma: remove unnecessary ifdefs MIPS: dma: add arch-specific dma_alloc() implementation MIPS: dma: simplify source structure arch/mips/include/asm/dma-mapping.h | 40 --- arch/mips/include/asm/dma.h | 43 - arch/mips/lib/dma-default.c | 8 -- 3 files changed, 42 insertions(+), 49 deletions(-) delete mode 100644 arch/mips/include/asm/dma-mapping.h -- 2.30.2
[PATCH 1/4] MIPS: dma: fix nullptr handling in dma_free_coherent
It is not an error to pass a null pointer to free() and as such it seems that dma_free_coherent() should be able to handle this situation too. Currently, if CONFIG_MMU option is enabled, we would convert this null pointer into a pointer to the beginning of CKSEG0 memory segment before passing it to free(), actually trying to deallocate stuff. Signed-off-by: Denis Orlov --- arch/mips/include/asm/dma-mapping.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/include/asm/dma-mapping.h b/arch/mips/include/asm/dma-mapping.h index 8e6ea08168..9f6ec03e3b 100644 --- a/arch/mips/include/asm/dma-mapping.h +++ b/arch/mips/include/asm/dma-mapping.h @@ -31,7 +31,7 @@ static inline void *dma_alloc_coherent(size_t size, dma_addr_t *dma_handle) static inline void dma_free_coherent(void *vaddr, dma_addr_t dma_handle, size_t size) { - if (IS_ENABLED(CONFIG_MMU)) + if (IS_ENABLED(CONFIG_MMU) && vaddr) free((void *)CKSEG0ADDR(vaddr)); else free(vaddr); -- 2.30.2
[PATCH 3/4] MIPS: dma: add arch-specific dma_alloc() implementation
DMA allocations should be aligned on a cache line size, at least on cache non-coherent MIPS systems. Instead of using some hardcoded value for an alignment from a generic implementation (which may be wrong for us), we can get cache info from 'current_cpu_data' variable, so use it. Signed-off-by: Denis Orlov --- arch/mips/include/asm/dma.h | 12 1 file changed, 12 insertions(+) diff --git a/arch/mips/include/asm/dma.h b/arch/mips/include/asm/dma.h index e0b4689172..49eeaac1a2 100644 --- a/arch/mips/include/asm/dma.h +++ b/arch/mips/include/asm/dma.h @@ -6,6 +6,18 @@ #ifndef __ASM_DMA_H #define __ASM_DMA_H +#include +#include +#include + +#define dma_alloc dma_alloc +static inline void *dma_alloc(size_t size) +{ + unsigned long max_linesz = max(current_cpu_data.dcache.linesz, + current_cpu_data.scache.linesz); + return xmemalign(max_linesz, ALIGN(size, max_linesz)); +} + #include "asm/dma-mapping.h" #endif /* __ASM_DMA_H */ -- 2.30.2
[PATCH 2/4] MIPS: dma: remove unnecessary ifdefs
We do not support any MIPS CPUs that are not MIPS32/MIPS64, so there is no reason to check for those. Signed-off-by: Denis Orlov --- arch/mips/lib/dma-default.c | 8 1 file changed, 8 deletions(-) diff --git a/arch/mips/lib/dma-default.c b/arch/mips/lib/dma-default.c index fbe627c24c..48176e5d28 100644 --- a/arch/mips/lib/dma-default.c +++ b/arch/mips/lib/dma-default.c @@ -6,8 +6,6 @@ #include #include -#if defined(CONFIG_CPU_MIPS32) || \ - defined(CONFIG_CPU_MIPS64) static inline void __dma_sync_mips(unsigned long addr, size_t size, enum dma_data_direction direction) { @@ -28,12 +26,6 @@ static inline void __dma_sync_mips(unsigned long addr, size_t size, BUG(); } } -#else -static inline void __dma_sync_mips(void *addr, size_t size, - enum dma_data_direction direction) -{ -} -#endif void dma_sync_single_for_cpu(dma_addr_t address, size_t size, enum dma_data_direction dir) -- 2.30.2
[PATCH 4/4] MIPS: dma: simplify source structure
There is no reason to keep code from 'dma-mapping.h' in a separate file, so merge it into 'dma.h'. Signed-off-by: Denis Orlov --- arch/mips/include/asm/dma-mapping.h | 40 - arch/mips/include/asm/dma.h | 31 +- 2 files changed, 30 insertions(+), 41 deletions(-) delete mode 100644 arch/mips/include/asm/dma-mapping.h diff --git a/arch/mips/include/asm/dma-mapping.h b/arch/mips/include/asm/dma-mapping.h deleted file mode 100644 index 9f6ec03e3b..00 --- a/arch/mips/include/asm/dma-mapping.h +++ /dev/null @@ -1,40 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#ifndef _ASM_DMA_MAPPING_H -#define _ASM_DMA_MAPPING_H - -#include -#include -#include -#include -#include -#include - -#define dma_alloc_coherent dma_alloc_coherent -static inline void *dma_alloc_coherent(size_t size, dma_addr_t *dma_handle) -{ - void *ret; - - ret = xmemalign(PAGE_SIZE, size); - - memset(ret, 0, size); - - if (dma_handle) - *dma_handle = CPHYSADDR(ret); - - dma_flush_range((unsigned long)ret, (unsigned long)(ret + size)); - - return (void *)CKSEG1ADDR(ret); -} - -#define dma_free_coherent dma_free_coherent -static inline void dma_free_coherent(void *vaddr, dma_addr_t dma_handle, -size_t size) -{ - if (IS_ENABLED(CONFIG_MMU) && vaddr) - free((void *)CKSEG0ADDR(vaddr)); - else - free(vaddr); -} - -#endif /* _ASM_DMA_MAPPING_H */ diff --git a/arch/mips/include/asm/dma.h b/arch/mips/include/asm/dma.h index 49eeaac1a2..62d9c7c548 100644 --- a/arch/mips/include/asm/dma.h +++ b/arch/mips/include/asm/dma.h @@ -7,8 +7,12 @@ #define __ASM_DMA_H #include +#include #include +#include #include +#include +#include #define dma_alloc dma_alloc static inline void *dma_alloc(size_t size) @@ -18,6 +22,31 @@ static inline void *dma_alloc(size_t size) return xmemalign(max_linesz, ALIGN(size, max_linesz)); } -#include "asm/dma-mapping.h" +#define dma_alloc_coherent dma_alloc_coherent +static inline void *dma_alloc_coherent(size_t size, dma_addr_t *dma_handle) +{ + void *ret; + + ret = xmemalign(PAGE_SIZE, size); + + memset(ret, 0, size); + + if (dma_handle) + *dma_handle = CPHYSADDR(ret); + + dma_flush_range((unsigned long)ret, (unsigned long)(ret + size)); + + return (void *)CKSEG1ADDR(ret); +} + +#define dma_free_coherent dma_free_coherent +static inline void dma_free_coherent(void *vaddr, dma_addr_t dma_handle, +size_t size) +{ + if (IS_ENABLED(CONFIG_MMU) && vaddr) + free((void *)CKSEG0ADDR(vaddr)); + else + free(vaddr); +} #endif /* __ASM_DMA_H */ -- 2.30.2
Re: [PATCH] Revert "dma: use dma/cpu conversions correctly in dma_map/unmap_single"
Hi! > > On 31.05.23 12:23, Sascha Hauer wrote: > > This reverts commit d13d870986eeecc58d8652268557e4a159b9d4c4. > > > > While the patch itself is correct, it at least breaks USB on the > > Raspberry Pi 3b. > > > > With this patch dma_sync_single_for_device() is passed the DMA address. > > This is correct as even the prototype suggests that it should get a > > dma_addr_t. Unfortunately this is not what the function implements and > > also not what the users expect. Most if not all users simply pass a CPU > > pointer casted to unsigned long. dma_sync_single_for_device() on ARM > > then takes the DMA address as a CPU pointer and does cache maintenance > > on it. > > > > Before we can merge this patch again dma_sync_single_for_device() must > > get a struct device * argument and (on ARM) the cpu_to_dma() conversion > > must be reverted before doing cache maintenance. > > @Denis, could you give some background on your patch? I assume this was > for MIPS? Did this patch fix breakage for you? In what driver? Maybe > a follow-up patch that fixes your particular breakage while not breaking > ARM could be found until that wart is cleaned up for good. I'm okay with this patch being reverted, sorry for any inconvenience. Will try to come up with a better one in the meantime. It appears that MIPS was *always* somewhat broken in this regard. Without this patch, we end up calling dma_sync_single_for_device() with a virtual address, and dma_sync_single_for_cpu() with a physical one. As on MIPS phys/virt addresses do not map 1:1 to each other, we can't really do anything sensible on the MIPS side in this case. Either map or unmap calls will be broken. On actual boards this will result in address errors with any driver that does DMA mappings. I originally sent an RFC with the whole streaming DMA interface rework, but I was a bit hesitant if such changes are actually needed. It occured to me that they are useful in theory, however, nothing in barebox seemed to require it at the moment. So I just resorted to smaller changes that were enough to fix MIPS, but I must have totally forgotten to check if other archs are fine with those changes applied. I don't like having to do cpu_to_dma() in common code just to call dma_to_cpu() on the arch side. But it seems like we have to do it in the most generic case. > > Cheers, > Ahmad > > > > --- > > drivers/dma/map.c | 10 ++ > > 1 file changed, 6 insertions(+), 4 deletions(-) > > > > diff --git a/drivers/dma/map.c b/drivers/dma/map.c > > index fea04c38a3..114c0f7db3 100644 > > --- a/drivers/dma/map.c > > +++ b/drivers/dma/map.c > > @@ -23,15 +23,17 @@ static inline void *dma_to_cpu(struct device *dev, > > dma_addr_t addr) > > dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size, > > enum dma_data_direction dir) > > { > > - dma_addr_t ret = cpu_to_dma(dev, ptr); > > + unsigned long addr = (unsigned long)ptr; > > > > - dma_sync_single_for_device(ret, size, dir); > > + dma_sync_single_for_device(addr, size, dir); > > > > - return ret; > > + return cpu_to_dma(dev, ptr); > > } > > > > void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size, > > enum dma_data_direction dir) > > { > > - dma_sync_single_for_cpu(dma_addr, size, dir); > > + unsigned long addr = (unsigned long)dma_to_cpu(dev, dma_addr); > > + > > + dma_sync_single_for_cpu(addr, size, dir); > > } > > -- > Pengutronix e.K. | | > Steuerwalder Str. 21 | http://www.pengutronix.de/ | > 31137 Hildesheim, Germany | Phone: +49-5121-206917-0| > Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- | >
[PATCH 1/2] dma: rework dma_sync_single_for_*() interface
Currently, a lot of code handles dma_addr_t values as if they actually hold CPU addresses. However, this is not always true. For example, MIPS architecture requires an explicit conversion from the physical address space to some virtual address space segment to get a valid CPU-side pointer. Another issue is that DMA ranges that may be specified in a device tree will not work this way. To get from a virtual address to a dma handle and vice versa we need to add/subtract some offset, which is calculated from "dma-ranges" property. Only dma_map_single() was doing this, but dma_sync_single_for_*() also should. Improve the interface by adding 'struct device' as the first argument to the dma_sync_single_for_*(). This allows to do cpu_to_dma/dma_to_cpu() conversions in common code and call into arch-specific code with proper cpu-side addresses. To make things more clear, make the virtual address argument of those arch-side functions be properly represented with a void* type. Apply the required changes in device drivers that use the affected functions, making them pass the appropriate device pointer. Signed-off-by: Denis Orlov --- arch/arm/cpu/dma_32.c | 17 +++--- arch/arm/cpu/dma_64.c | 13 +++-- arch/arm/cpu/mmu-common.c | 9 ++-- arch/arm/include/asm/dma.h | 12 ++--- arch/arm/mach-bcm283x/mbox.c| 4 +- arch/kvx/lib/dma-default.c | 16 +++--- arch/mips/lib/dma-default.c | 18 +++ arch/riscv/cpu/dma.c| 23 + arch/sandbox/include/asm/dma.h | 12 ++--- arch/x86/include/asm/dma.h | 12 ++--- drivers/crypto/caam/caam-blobgen.c | 28 +- drivers/crypto/caam/caamrng.c | 6 +-- drivers/crypto/caam/rng_self_test.c | 6 +-- drivers/dma/Makefile| 1 - drivers/dma/map.c | 39 -- drivers/mci/dove-sdhci.c| 8 +-- drivers/mci/stm32_sdmmc2.c | 8 +-- drivers/mci/tegra-sdmmc.c | 8 +-- drivers/net/ag71xx.c| 8 +-- drivers/net/arc_emac.c | 10 ++-- drivers/net/at91_ether.c| 11 ++-- drivers/net/bcmgenet.c | 4 +- drivers/net/cpsw.c | 8 +-- drivers/net/davinci_emac.c | 8 +-- drivers/net/designware.c| 10 ++-- drivers/net/designware_eqos.c | 6 ++- drivers/net/e1000/main.c| 4 +- drivers/net/fec_imx.c | 4 +- drivers/net/fsl-fman.c | 7 +-- drivers/net/macb.c | 20 drivers/net/mvneta.c| 8 +-- drivers/net/orion-gbe.c | 8 +-- drivers/net/r8169_main.c| 10 ++-- drivers/usb/gadget/udc/fsl_udc.c| 8 +-- drivers/usb/host/ohci-hcd.c | 7 +-- include/dma.h | 80 ++--- 36 files changed, 236 insertions(+), 225 deletions(-) delete mode 100644 drivers/dma/map.c diff --git a/arch/arm/cpu/dma_32.c b/arch/arm/cpu/dma_32.c index a66aa26b9b..842ea7033a 100644 --- a/arch/arm/cpu/dma_32.c +++ b/arch/arm/cpu/dma_32.c @@ -1,20 +1,19 @@ #include #include -void dma_sync_single_for_device(dma_addr_t address, size_t size, - enum dma_data_direction dir) +void arch_sync_dma_for_device(void *vaddr, size_t size, + enum dma_data_direction dir) { - /* -* FIXME: This function needs a device argument to support non 1:1 mappings -*/ + unsigned long start = (unsigned long)vaddr; + unsigned long end = start + size; if (dir == DMA_FROM_DEVICE) { - __dma_inv_range(address, address + size); + __dma_inv_range(start, end); if (outer_cache.inv_range) - outer_cache.inv_range(address, address + size); + outer_cache.inv_range(start, end); } else { - __dma_clean_range(address, address + size); + __dma_clean_range(start, end); if (outer_cache.clean_range) - outer_cache.clean_range(address, address + size); + outer_cache.clean_range(start, end); } } diff --git a/arch/arm/cpu/dma_64.c b/arch/arm/cpu/dma_64.c index b4ae736c9b..74d7167860 100644 --- a/arch/arm/cpu/dma_64.c +++ b/arch/arm/cpu/dma_64.c @@ -2,15 +2,14 @@ #include #include -void dma_sync_single_for_device(dma_addr_t address, size_t size, -enum dma_data_direction dir) +void arch_sync_dma_for_device(void *vaddr, size_t size, + enum dma_data_direction dir) { - /* -* FIXME: This function needs a device argument to support non 1:1 mappings -*/ + unsigned long start = (unsigned long)vaddr; + unsigned long end = start + size - 1; if (dir == DMA_FROM_DEVICE) - v8_inv_dcache_range(address, address
[PATCH v2 0/2] dma: rework streaming DMA interface
This fixes issues with streaming DMA on MIPS and more or less properly fixes support for non 1-to-1 mappings via 'dma-ranges' device tree property. It needs to be tested properly on non-MIPS architectures as I only have tested the compilation for some of those. The differences from RFC include merging two parts of the patch and dropping changes not really related to the matter at hand. Denis Orlov (2): dma: rework dma_sync_single_for_*() interface net: macb: remove const from dev pointer in macb_device arch/arm/cpu/dma_32.c | 17 +++--- arch/arm/cpu/dma_64.c | 13 +++-- arch/arm/cpu/mmu-common.c | 9 ++-- arch/arm/include/asm/dma.h | 12 ++--- arch/arm/mach-bcm283x/mbox.c| 4 +- arch/kvx/lib/dma-default.c | 16 +++--- arch/mips/lib/dma-default.c | 18 +++ arch/riscv/cpu/dma.c| 23 + arch/sandbox/include/asm/dma.h | 12 ++--- arch/x86/include/asm/dma.h | 12 ++--- drivers/crypto/caam/caam-blobgen.c | 28 +- drivers/crypto/caam/caamrng.c | 6 +-- drivers/crypto/caam/rng_self_test.c | 6 +-- drivers/dma/Makefile| 1 - drivers/dma/map.c | 39 -- drivers/mci/dove-sdhci.c| 8 +-- drivers/mci/stm32_sdmmc2.c | 8 +-- drivers/mci/tegra-sdmmc.c | 8 +-- drivers/net/ag71xx.c| 8 +-- drivers/net/arc_emac.c | 10 ++-- drivers/net/at91_ether.c| 11 ++-- drivers/net/bcmgenet.c | 4 +- drivers/net/cpsw.c | 8 +-- drivers/net/davinci_emac.c | 8 +-- drivers/net/designware.c| 10 ++-- drivers/net/designware_eqos.c | 6 ++- drivers/net/e1000/main.c| 4 +- drivers/net/fec_imx.c | 4 +- drivers/net/fsl-fman.c | 7 +-- drivers/net/macb.c | 22 drivers/net/mvneta.c| 8 +-- drivers/net/orion-gbe.c | 8 +-- drivers/net/r8169_main.c| 10 ++-- drivers/usb/gadget/udc/fsl_udc.c| 8 +-- drivers/usb/host/ohci-hcd.c | 7 +-- include/dma.h | 80 ++--- 36 files changed, 237 insertions(+), 226 deletions(-) delete mode 100644 drivers/dma/map.c -- 2.41.0
[PATCH 2/2] net: macb: remove const from dev pointer in macb_device
Otherwise, it leads to a bunch of warnings on passing those pointers to dma_*() functions. As every other driver seem to be having non-const dev pointers in their private structs, do the same here. Signed-off-by: Denis Orlov --- drivers/net/macb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/macb.c b/drivers/net/macb.c index 4b89c59580..128ada7268 100644 --- a/drivers/net/macb.c +++ b/drivers/net/macb.c @@ -75,7 +75,7 @@ struct macb_device { int phy_addr; struct clk *pclk, *hclk, *txclk, *rxclk; - const struct device *dev; + struct device *dev; struct eth_device netdev; phy_interface_t interface; -- 2.41.0
[PATCH] net: r8169: fix builds on archs without system.h header
Some architectures do lack header, which breaks building RTL8169 for them. However, it doesn't even seem to be needed there. From a quick glance at archs that do have one such header, its contents are quite platform-specific. Getting rid of this include fixes building the driver, so do just that. Signed-off-by: Denis Orlov --- drivers/net/r8169_main.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/r8169_main.c b/drivers/net/r8169_main.c index 5b448fa029..2225c26190 100644 --- a/drivers/net/r8169_main.c +++ b/drivers/net/r8169_main.c @@ -17,7 +17,6 @@ #include #include #include -#include #include "r8169.h" #include "r8169_firmware.h" -- 2.41.0
Re: [PATCH 2/3] test: mips: add QEMU Malta 64le labgrid config
On Fri, 9 Jun 2023 at 10:21, Ahmad Fatoum wrote: > > On 09.06.23 09:14, Denis Orlov wrote: > > Hello Ahmad, > > > > On Fri, 9 Jun 2023 at 09:36, Ahmad Fatoum wrote: > >> > >> On 07.06.23 06:59, Denis Orlov wrote: > >>> Signed-off-by: Denis Orlov > >>> --- > >>> test/mips/qemu-malta64el_defconfig.yaml | 22 ++ > >>> 1 file changed, 22 insertions(+) > >>> create mode 100644 test/mips/qemu-malta64el_defconfig.yaml > >>> > >>> diff --git a/test/mips/qemu-malta64el_defconfig.yaml > >>> b/test/mips/qemu-malta64el_defconfig.yaml > >>> new file mode 100644 > >>> index 00..22562d5b7a > >>> --- /dev/null > >>> +++ b/test/mips/qemu-malta64el_defconfig.yaml > >>> @@ -0,0 +1,22 @@ > >>> +targets: > >>> + main: > >>> +drivers: > >>> + QEMUDriver: > >>> +qemu_bin: qemu > >>> +machine: malta > >>> +cpu: 5KEf > >>> +memory: 256M > >>> +bios: barebox-qemu-malta.img.swapped > >>> +extra_args: '' > >>> + BareboxDriver: > >>> +prompt: 'barebox@[^:]+:[^ ]+ ' > >>> +bootstring: 'commandline:' > >>> + BareboxTestStrategy: {} > >>> +features: > >>> + - virtio-pci > >> > >> Did you test virtio PCI? I don't see it enabled in the defconfig. > > > > Nope, I didn't. I must have copied this from the 32-bit malta config > > file. However, I see that its defconfig also lacks VIRTIO_PCI, so should > > those be removed from both labgrid configs? > > > > Besides, judging from the virtio PCI Kconfig option depends, there seem > > to be some issues with virtio PCI on MIPS without CONFIG_MMU set. Is the > > lack of VIRTIO_PCI option in 32-bit malta defconfig related to that? > > Ah, right. test/emulate.pl reads virtio-pci feature to decide what Virt I/O > transport to use. Maybe the MMU incompatibility is fixed now with your > recent DMA rework or maybe we still have 1:1 mapping assumptions in the > virtio code itself. If you could give it a quick test with CONFIG_MMU=n > and see if it works, that would be great. Something like this should do it: > > /usr/bin/qemu-system-mips64el -M malta -cpu 5KEf -m 256M \ >-bios barebox-qemu-malta.img.swapped -serial mon:stdio -trace > file=/dev/null \ >-drive > if=none,file=/src/barebox-rockchip/somealigned.img,format=raw,id=hd0 \ >-device virtio-blk-pci,disable-legacy=on,disable-modern=off,drive=hd0 > > (Above was generated by ./test/emulate.pl $config -n --blk=somealigned.img) > > You should see a /dev/virtioblk* device if everything is enabled and working. Yeah, it seems that this works on both CONFIG_MMU=y and CONFIG_MMU=n now. The drive mounts successfully and I am able to look at its contents with "ls". So, does this mean that we should enable the VIRTIO_PCI option in malta defconfigs? > > Cheers, > Ahmad > > > > > Regards, > > Denis > > > >> > >>> +images: > >>> + barebox-qemu-malta.img.swapped: !template > >>> "$LG_BUILDDIR/images/barebox-qemu-malta.img.swapped" > >>> +tools: > >>> + qemu: /usr/bin/qemu-system-mips64el > >>> +imports: > >>> + - ../strategy.py > >> > >> -- > >> Pengutronix e.K. | | > >> Steuerwalder Str. 21 | http://www.pengutronix.de/ | > >> 31137 Hildesheim, Germany | Phone: +49-5121-206917-0| > >> Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- | > >> > > > > -- > Pengutronix e.K. | | > Steuerwalder Str. 21 | http://www.pengutronix.de/ | > 31137 Hildesheim, Germany | Phone: +49-5121-206917-0| > Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- | >
Re: [PATCH 2/3] test: mips: add QEMU Malta 64le labgrid config
On Fri, 9 Jun 2023 at 12:28, Ahmad Fatoum wrote: > > On 09.06.23 11:17, Denis Orlov wrote: > > On Fri, 9 Jun 2023 at 10:21, Ahmad Fatoum wrote: > >> > >> On 09.06.23 09:14, Denis Orlov wrote: > >>> Hello Ahmad, > >>> > >>> On Fri, 9 Jun 2023 at 09:36, Ahmad Fatoum wrote: > >>>> > >>>> On 07.06.23 06:59, Denis Orlov wrote: > >>>>> Signed-off-by: Denis Orlov > >>>>> --- > >>>>> test/mips/qemu-malta64el_defconfig.yaml | 22 ++ > >>>>> 1 file changed, 22 insertions(+) > >>>>> create mode 100644 test/mips/qemu-malta64el_defconfig.yaml > >>>>> > >>>>> diff --git a/test/mips/qemu-malta64el_defconfig.yaml > >>>>> b/test/mips/qemu-malta64el_defconfig.yaml > >>>>> new file mode 100644 > >>>>> index 00..22562d5b7a > >>>>> --- /dev/null > >>>>> +++ b/test/mips/qemu-malta64el_defconfig.yaml > >>>>> @@ -0,0 +1,22 @@ > >>>>> +targets: > >>>>> + main: > >>>>> +drivers: > >>>>> + QEMUDriver: > >>>>> +qemu_bin: qemu > >>>>> +machine: malta > >>>>> +cpu: 5KEf > >>>>> +memory: 256M > >>>>> +bios: barebox-qemu-malta.img.swapped > >>>>> +extra_args: '' > >>>>> + BareboxDriver: > >>>>> +prompt: 'barebox@[^:]+:[^ ]+ ' > >>>>> +bootstring: 'commandline:' > >>>>> + BareboxTestStrategy: {} > >>>>> +features: > >>>>> + - virtio-pci > >>>> > >>>> Did you test virtio PCI? I don't see it enabled in the defconfig. > >>> > >>> Nope, I didn't. I must have copied this from the 32-bit malta config > >>> file. However, I see that its defconfig also lacks VIRTIO_PCI, so should > >>> those be removed from both labgrid configs? > >>> > >>> Besides, judging from the virtio PCI Kconfig option depends, there seem > >>> to be some issues with virtio PCI on MIPS without CONFIG_MMU set. Is the > >>> lack of VIRTIO_PCI option in 32-bit malta defconfig related to that? > >> > >> Ah, right. test/emulate.pl reads virtio-pci feature to decide what Virt I/O > >> transport to use. Maybe the MMU incompatibility is fixed now with your > >> recent DMA rework or maybe we still have 1:1 mapping assumptions in the > >> virtio code itself. If you could give it a quick test with CONFIG_MMU=n > >> and see if it works, that would be great. Something like this should do it: > >> > >> /usr/bin/qemu-system-mips64el -M malta -cpu 5KEf -m 256M \ > >>-bios barebox-qemu-malta.img.swapped -serial mon:stdio -trace > >> file=/dev/null \ > >>-drive > >> if=none,file=/src/barebox-rockchip/somealigned.img,format=raw,id=hd0 \ > >>-device virtio-blk-pci,disable-legacy=on,disable-modern=off,drive=hd0 > >> > >> (Above was generated by ./test/emulate.pl $config -n --blk=somealigned.img) > >> > >> You should see a /dev/virtioblk* device if everything is enabled and > >> working. > > > > Yeah, it seems that this works on both CONFIG_MMU=y and CONFIG_MMU=n now. > > The drive mounts successfully and I am able to look at its contents with > > "ls". So, does this mean that we should enable the VIRTIO_PCI option in > > malta defconfigs? > > Even for 32-bit? Ye, then we can drop the depends line in VIRTIO_PCI and > enable it in the MIPS defconfigs. Yep, 32-bit with CONFIG_MMU=n works too. I will send a patch later today. Should CONFIG_DISK and CONFIG_VIRTIO_BLK also be enabled in those by default? > > Thanks for testing! > Ahmad > > > > >> > >> Cheers, > >> Ahmad > >> > >>> > >>> Regards, > >>> Denis > >>> > >>>> > >>>>> +images: > >>>>> + barebox-qemu-malta.img.swapped: !template > >>>>> "$LG_BUILDDIR/images/barebox-qemu-malta.img.swapped" > >>>>> +tools: > >>>>> + qemu: /usr/bin/qemu-system-mips64el > >>>>> +imports: > >>>>> + - ../strategy.py > >>>> > >>>> -- > >>>> Pengutronix e.K. | > >>>> | > >>>> Steuerwalder Str. 21 | http://www.pengutronix.de/ > >>>> | > >>>> 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 > >>>> | > >>>> Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- > >>>> | > >>>> > >>> > >> > >> -- > >> Pengutronix e.K. | | > >> Steuerwalder Str. 21 | http://www.pengutronix.de/ | > >> 31137 Hildesheim, Germany | Phone: +49-5121-206917-0| > >> Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- | > >> > > > > -- > Pengutronix e.K. | | > Steuerwalder Str. 21 | http://www.pengutronix.de/ | > 31137 Hildesheim, Germany | Phone: +49-5121-206917-0| > Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- | >
[PATCH 1/3] include: const: make UL/ULL() macros commonly available
Import the definitions from Linux. Some code actually used those already, defining them locally. As these are not needed now that there are common ones available, remove the duplicate definitions. While at it, also update _BITUL/_BITULL() definitions to align more with the latest Linux sources. Signed-off-by: Denis Orlov --- arch/arm/include/asm/memory.h| 5 - arch/arm/include/asm/pgtable64.h | 2 -- arch/kvx/include/asm/sfr_defs.h | 2 -- include/linux/const.h| 10 -- 4 files changed, 8 insertions(+), 11 deletions(-) diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h index 2b454fa673..23fbbd8438 100644 --- a/arch/arm/include/asm/memory.h +++ b/arch/arm/include/asm/memory.h @@ -6,11 +6,6 @@ #include #include -/* - * Allow for constants defined here to be used from assembly code - * by prepending the UL suffix only with actual C code compilation. - */ -#define UL(x) _AC(x, UL) static inline int arm_add_mem_device(const char* name, resource_size_t start, resource_size_t size) diff --git a/arch/arm/include/asm/pgtable64.h b/arch/arm/include/asm/pgtable64.h index dbec61753b..21dac30cfe 100644 --- a/arch/arm/include/asm/pgtable64.h +++ b/arch/arm/include/asm/pgtable64.h @@ -4,8 +4,6 @@ #ifndef __ASM_PGTABLE64_H #define __ASM_PGTABLE64_H -#define UL(x) _AC(x, UL) - #define UNUSED_DESC0x6EbAAD0BBADbA6E0 #define VA_START 0x0 diff --git a/arch/kvx/include/asm/sfr_defs.h b/arch/kvx/include/asm/sfr_defs.h index 2b7598e0aa..7f6fbd206b 100644 --- a/arch/kvx/include/asm/sfr_defs.h +++ b/arch/kvx/include/asm/sfr_defs.h @@ -8,8 +8,6 @@ #include -#define _ULL(X) _AC(X, ULL) - /* Register file indices */ #define KVX_SFR_PC 0 /* Program Counter $pc $s0 */ #define KVX_SFR_PS 1 /* Processor State $ps $s1 */ diff --git a/include/linux/const.h b/include/linux/const.h index 07f886d271..07414f95de 100644 --- a/include/linux/const.h +++ b/include/linux/const.h @@ -23,7 +23,13 @@ #define _AT(T,X) ((T)(X)) #endif -#define _BITUL(x) (_AC(1,UL) << (x)) -#define _BITULL(x) (_AC(1,ULL) << (x)) +#define _UL(x) (_AC(x, UL)) +#define _ULL(x)(_AC(x, ULL)) + +#define _BITUL(x) (_UL(1) << (x)) +#define _BITULL(x) (_ULL(1) << (x)) + +#define UL(x) (_UL(x)) +#define ULL(x) (_ULL(x)) #endif /* !(_LINUX_CONST_H) */ -- 2.41.0
[PATCH 0/3] include: bitops/const: partial update from Linux
This updates some of the definitions in those files, mainly to make BIT*/GENMASK() macros usable in assembly code. Denis Orlov (3): include: const: make UL/ULL() macros commonly available include: bitops: allow BIT* macros to be used in assembly code include: bitops: import more BITS_TO_* defines from linux arch/arm/include/asm/memory.h| 5 - arch/arm/include/asm/pgtable64.h | 2 -- arch/kvx/include/asm/sfr_defs.h | 2 -- include/linux/bitops.h | 24 +--- include/linux/const.h| 10 -- 5 files changed, 25 insertions(+), 18 deletions(-) -- 2.41.0
[PATCH 3/3] include: bitops: import more BITS_TO_* defines from linux
Those seem quite useful, e.g. when defining bitmasks. Signed-off-by: Denis Orlov --- include/linux/bitops.h | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/include/linux/bitops.h b/include/linux/bitops.h index d9a5a81a9c..a5f6ac6545 100644 --- a/include/linux/bitops.h +++ b/include/linux/bitops.h @@ -14,7 +14,11 @@ #define BIT_ULL_MASK(nr) (ULL(1) << ((nr) % BITS_PER_LONG_LONG)) #define BIT_ULL_WORD(nr) ((nr) / BITS_PER_LONG_LONG) #define BITS_PER_BYTE 8 -#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long)) +#define BITS_PER_TYPE(type)(sizeof(type) * BITS_PER_BYTE) +#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_TYPE(long)) +#define BITS_TO_U64(nr)DIV_ROUND_UP(nr, BITS_PER_TYPE(u64)) +#define BITS_TO_U32(nr)DIV_ROUND_UP(nr, BITS_PER_TYPE(u32)) +#define BITS_TO_BYTES(nr) DIV_ROUND_UP(nr, BITS_PER_TYPE(char)) #endif /* -- 2.41.0
[PATCH 2/3] include: bitops: allow BIT* macros to be used in assembly code
Use UL/ULL() macros for those so that corresponding suffixes only appear when we are compiling C code. Hide all the other functions/macros that we can't use in assembly with '#ifndef __ASSEMBLY__'. Signed-off-by: Denis Orlov --- include/linux/bitops.h | 18 -- 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/include/linux/bitops.h b/include/linux/bitops.h index eb5ff37f2f..d9a5a81a9c 100644 --- a/include/linux/bitops.h +++ b/include/linux/bitops.h @@ -2,14 +2,16 @@ #ifndef _LINUX_BITOPS_H #define _LINUX_BITOPS_H + #include +#include #ifdef __KERNEL__ -#define BIT(nr)(1UL << (nr)) -#define BIT_ULL(nr)(1ULL << (nr)) -#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG)) +#define BIT(nr)(UL(1) << (nr)) +#define BIT_ULL(nr)(ULL(1) << (nr)) +#define BIT_MASK(nr) (UL(1) << ((nr) % BITS_PER_LONG)) #define BIT_WORD(nr) ((nr) / BITS_PER_LONG) -#define BIT_ULL_MASK(nr) (1ULL << ((nr) % BITS_PER_LONG_LONG)) +#define BIT_ULL_MASK(nr) (ULL(1) << ((nr) % BITS_PER_LONG_LONG)) #define BIT_ULL_WORD(nr) ((nr) / BITS_PER_LONG_LONG) #define BITS_PER_BYTE 8 #define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long)) @@ -21,11 +23,14 @@ * GENMASK_ULL(39, 21) gives us the 64bit vector 0x00e0. */ #define GENMASK(h, l) \ - (((~0UL) << (l)) & (~0UL >> (BITS_PER_LONG - 1 - (h + (((~UL(0)) - (UL(1) << (l)) + 1) & \ +(~UL(0) >> (BITS_PER_LONG - 1 - (h #define GENMASK_ULL(h, l) \ - (((~0ULL) << (l)) & (~0ULL >> (BITS_PER_LONG_LONG - 1 - (h + (((~ULL(0)) - (ULL(1) << (l)) + 1) & \ +(~ULL(0) >> (BITS_PER_LONG_LONG - 1 - (h +#ifndef __ASSEMBLY__ /* * Include this here because some architectures need generic_ffs/fls in * scope @@ -237,5 +242,6 @@ extern unsigned long find_last_bit(const unsigned long *addr, unsigned long size); #endif +#endif /* !(__ASSEMBLY__) */ #endif /* __KERNEL__ */ #endif -- 2.41.0
Re: [PATCH 3/3] ci: add a job for testing 64BIT MIPS with labgrid
On Fri, 9 Jun 2023 at 09:38, Ahmad Fatoum wrote: > > On 07.06.23 06:59, Denis Orlov wrote: > > Signed-off-by: Denis Orlov > > https://mirrors.edge.kernel.org/pub/tools/crosstool/files/bin/x86_64/13.1.0/ > has a dedicated mips64 toolchain. Given that you don't touch the > Containerfile, > I assume this means that the normal toolchain can compile both 32- and 64-bit? Well, it seems so, judging by the fact that I had run CI successfully on my GitHub repo. I guess the main difference between mips and mips64 toolchains is the default compile configuration values. On debian there are also many different MIPS compilers (mips-linux-gnu-, mipsel-linux-gnu-, mips64-linux-gnuabi64-, mips64el-linux-gnuabi64-, and others) available, however I am compiling barebox/Linux successfully with the mips-linux-gnu- one when the correct target endianness/ABI options are being passed. Maybe there are other differences, but I don't know of them. Regards, Denis > > If so, > > Reviewed-by: Ahmad Fatoum > > > --- > > .github/workflows/test-labgrid-pytest.yml | 4 > > 1 file changed, 4 insertions(+) > > > > diff --git a/.github/workflows/test-labgrid-pytest.yml > > b/.github/workflows/test-labgrid-pytest.yml > > index 2c74150066..674e4251d1 100644 > > --- a/.github/workflows/test-labgrid-pytest.yml > > +++ b/.github/workflows/test-labgrid-pytest.yml > > @@ -26,6 +26,10 @@ jobs: > > lgenv: test/mips/qemu-malta_defconfig.yaml > > defconfig: qemu-malta_defconfig > > > > + - ARCH: mips > > +lgenv: test/mips/qemu-malta64el_defconfig.yaml > > +defconfig: qemu-malta64el_defconfig > > + > >- ARCH: x86 > > lgenv: test/x86/efi_defconfig.yaml > > defconfig: efi_defconfig > > -- > Pengutronix e.K. | | > Steuerwalder Str. 21 | http://www.pengutronix.de/ | > 31137 Hildesheim, Germany | Phone: +49-5121-206917-0| > Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- | >
Re: [PATCH 2/3] test: mips: add QEMU Malta 64le labgrid config
Hello Ahmad, On Fri, 9 Jun 2023 at 09:36, Ahmad Fatoum wrote: > > On 07.06.23 06:59, Denis Orlov wrote: > > Signed-off-by: Denis Orlov > > --- > > test/mips/qemu-malta64el_defconfig.yaml | 22 ++ > > 1 file changed, 22 insertions(+) > > create mode 100644 test/mips/qemu-malta64el_defconfig.yaml > > > > diff --git a/test/mips/qemu-malta64el_defconfig.yaml > > b/test/mips/qemu-malta64el_defconfig.yaml > > new file mode 100644 > > index 00..22562d5b7a > > --- /dev/null > > +++ b/test/mips/qemu-malta64el_defconfig.yaml > > @@ -0,0 +1,22 @@ > > +targets: > > + main: > > +drivers: > > + QEMUDriver: > > +qemu_bin: qemu > > +machine: malta > > +cpu: 5KEf > > +memory: 256M > > +bios: barebox-qemu-malta.img.swapped > > +extra_args: '' > > + BareboxDriver: > > +prompt: 'barebox@[^:]+:[^ ]+ ' > > +bootstring: 'commandline:' > > + BareboxTestStrategy: {} > > +features: > > + - virtio-pci > > Did you test virtio PCI? I don't see it enabled in the defconfig. Nope, I didn't. I must have copied this from the 32-bit malta config file. However, I see that its defconfig also lacks VIRTIO_PCI, so should those be removed from both labgrid configs? Besides, judging from the virtio PCI Kconfig option depends, there seem to be some issues with virtio PCI on MIPS without CONFIG_MMU set. Is the lack of VIRTIO_PCI option in 32-bit malta defconfig related to that? Regards, Denis > > > +images: > > + barebox-qemu-malta.img.swapped: !template > > "$LG_BUILDDIR/images/barebox-qemu-malta.img.swapped" > > +tools: > > + qemu: /usr/bin/qemu-system-mips64el > > +imports: > > + - ../strategy.py > > -- > Pengutronix e.K. | | > Steuerwalder Str. 21 | http://www.pengutronix.de/ | > 31137 Hildesheim, Germany | Phone: +49-5121-206917-0| > Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- | >
[PATCH 0/3] Add CI for MIPS64
This adds a necessary defconfig and labgrid configuration file together with the corresponding CI job for building and testing the MIPS image with 64BIT option set. I've decided against giving the defconfig a generic name such as mips64_defconfig. For now, only Malta running in QEMU is really supported, so naming it as that seems more fitting for me. And if more MIPS64 boards will get support in the future, then this defconfig might be renamed appropriately. Denis Orlov (3): MIPS: add qemu-malta64el_defconfig test: mips: add QEMU Malta 64le labgrid config ci: add a job for testing 64BIT MIPS with labgrid .github/workflows/test-labgrid-pytest.yml | 4 + arch/mips/configs/qemu-malta64el_defconfig | 87 ++ test/mips/qemu-malta64el_defconfig.yaml| 22 ++ 3 files changed, 113 insertions(+) create mode 100644 arch/mips/configs/qemu-malta64el_defconfig create mode 100644 test/mips/qemu-malta64el_defconfig.yaml -- 2.41.0
[PATCH 2/3] test: mips: add QEMU Malta 64le labgrid config
Signed-off-by: Denis Orlov --- test/mips/qemu-malta64el_defconfig.yaml | 22 ++ 1 file changed, 22 insertions(+) create mode 100644 test/mips/qemu-malta64el_defconfig.yaml diff --git a/test/mips/qemu-malta64el_defconfig.yaml b/test/mips/qemu-malta64el_defconfig.yaml new file mode 100644 index 00..22562d5b7a --- /dev/null +++ b/test/mips/qemu-malta64el_defconfig.yaml @@ -0,0 +1,22 @@ +targets: + main: +drivers: + QEMUDriver: +qemu_bin: qemu +machine: malta +cpu: 5KEf +memory: 256M +bios: barebox-qemu-malta.img.swapped +extra_args: '' + BareboxDriver: +prompt: 'barebox@[^:]+:[^ ]+ ' +bootstring: 'commandline:' + BareboxTestStrategy: {} +features: + - virtio-pci +images: + barebox-qemu-malta.img.swapped: !template "$LG_BUILDDIR/images/barebox-qemu-malta.img.swapped" +tools: + qemu: /usr/bin/qemu-system-mips64el +imports: + - ../strategy.py -- 2.41.0
[PATCH 1/3] MIPS: add qemu-malta64el_defconfig
This defconfig will compile barebox for Malta board and MIPS64 5KEc/5KEf CPUs, emulatable in QEMU. The analogous 32-bit defconfig uses big endian CPU as the default one. So, for the sake of variety, and to improve the coverage of options, set the CPU as little endian for this one. Signed-off-by: Denis Orlov --- arch/mips/configs/qemu-malta64el_defconfig | 87 ++ 1 file changed, 87 insertions(+) create mode 100644 arch/mips/configs/qemu-malta64el_defconfig diff --git a/arch/mips/configs/qemu-malta64el_defconfig b/arch/mips/configs/qemu-malta64el_defconfig new file mode 100644 index 00..5fb090a646 --- /dev/null +++ b/arch/mips/configs/qemu-malta64el_defconfig @@ -0,0 +1,87 @@ +CONFIG_BOARD_QEMU_MALTA=y +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_CPU_MIPS64_R2=y +CONFIG_64BIT=y +CONFIG_IMAGE_COMPRESSION_XZKERN=y +CONFIG_BAREBOX_MAX_IMAGE_SIZE=0x40 +CONFIG_STACK_SIZE=0x7000 +CONFIG_EXPERIMENTAL=y +CONFIG_BAUDRATE=38400 +CONFIG_HUSH_FANCY_PROMPT=y +CONFIG_CMDLINE_EDITING=y +CONFIG_AUTO_COMPLETE=y +CONFIG_MENU=y +CONFIG_BOOTM_SHOW_TYPE=y +CONFIG_CONSOLE_ALLOW_COLOR=y +CONFIG_PARTITION=y +CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW=y +CONFIG_CMD_DMESG=y +CONFIG_LONGHELP=y +CONFIG_CMD_IOMEM=y +CONFIG_CMD_IMD=y +CONFIG_CMD_MEMINFO=y +CONFIG_CMD_GO=y +CONFIG_CMD_LOADB=y +CONFIG_CMD_LOADY=y +CONFIG_CMD_RESET=y +CONFIG_CMD_PARTITION=y +CONFIG_CMD_EXPORT=y +CONFIG_CMD_DEFAULTENV=y +CONFIG_CMD_LOADENV=y +CONFIG_CMD_PRINTENV=y +CONFIG_CMD_SAVEENV=y +CONFIG_CMD_MD5SUM=y +CONFIG_CMD_SHA1SUM=y +CONFIG_CMD_SHA256SUM=y +CONFIG_CMD_UNCOMPRESS=y +CONFIG_CMD_SLEEP=y +CONFIG_CMD_DHCP=y +CONFIG_CMD_MIITOOL=y +CONFIG_CMD_PING=y +CONFIG_CMD_TFTP=y +CONFIG_CMD_ECHO_E=y +CONFIG_CMD_EDIT=y +CONFIG_CMD_LOGIN=y +CONFIG_CMD_MENU=y +CONFIG_CMD_MENU_MANAGEMENT=y +CONFIG_CMD_PASSWD=y +CONFIG_CMD_FBTEST=y +CONFIG_CMD_READLINE=y +CONFIG_CMD_TIMEOUT=y +CONFIG_CMD_CRC=y +CONFIG_CMD_CRC_CMP=y +CONFIG_CMD_FLASH=y +CONFIG_CMD_GPIO=y +CONFIG_CMD_I2C=y +CONFIG_CMD_OF_NODE=y +CONFIG_CMD_OF_PROPERTY=y +CONFIG_CMD_OFTREE=y +CONFIG_CMD_TIME=y +CONFIG_NET=y +CONFIG_NET_NFS=y +CONFIG_NET_NETCONSOLE=y +CONFIG_OFDEVICE=y +CONFIG_OF_BAREBOX_DRIVERS=y +CONFIG_DRIVER_NET_RTL8139=y +# CONFIG_SPI is not set +CONFIG_I2C=y +CONFIG_I2C_GPIO=y +CONFIG_MTD=y +CONFIG_DRIVER_CFI=y +# CONFIG_DRIVER_CFI_AMD is not set +# CONFIG_DRIVER_CFI_BANK_WIDTH_1 is not set +# CONFIG_DRIVER_CFI_BANK_WIDTH_2 is not set +CONFIG_CFI_BUFFER_WRITE=y +CONFIG_VIDEO=y +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_DRIVER_VIDEO_BOCHS_PCI=y +CONFIG_GPIO_MALTA_FPGA_I2C=y +CONFIG_PCI=y +CONFIG_PCI_DEBUG=y +CONFIG_SYSCON_REBOOT_MODE=y +CONFIG_POWER_RESET_SYSCON=y +CONFIG_FS_CRAMFS=y +CONFIG_FS_TFTP=y +CONFIG_FS_FAT=y +CONFIG_FS_FAT_WRITE=y +CONFIG_FS_FAT_LFN=y -- 2.41.0
[PATCH 3/3] ci: add a job for testing 64BIT MIPS with labgrid
Signed-off-by: Denis Orlov --- .github/workflows/test-labgrid-pytest.yml | 4 1 file changed, 4 insertions(+) diff --git a/.github/workflows/test-labgrid-pytest.yml b/.github/workflows/test-labgrid-pytest.yml index 2c74150066..674e4251d1 100644 --- a/.github/workflows/test-labgrid-pytest.yml +++ b/.github/workflows/test-labgrid-pytest.yml @@ -26,6 +26,10 @@ jobs: lgenv: test/mips/qemu-malta_defconfig.yaml defconfig: qemu-malta_defconfig + - ARCH: mips +lgenv: test/mips/qemu-malta64el_defconfig.yaml +defconfig: qemu-malta64el_defconfig + - ARCH: x86 lgenv: test/x86/efi_defconfig.yaml defconfig: efi_defconfig -- 2.41.0
[PATCH 15/17] MIPS: add 64-bit support for optimized string functions
This adds macro definitions and a bit of code that allow to properly utilise doubleword instructions on mips64. These changes are taken directly from Linux sources. Also switch some o32-specific register definitions to generic ones for this code to actually compile for n64 ABI. While at it, this also removes an unused macro define. Signed-off-by: Denis Orlov --- arch/mips/Kconfig | 1 - arch/mips/lib/memcpy.S | 37 - 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index ab8c8cf176..de2f539cc1 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -376,7 +376,6 @@ config NMON_HELP config MIPS_OPTIMIZED_STRING_FUNCTIONS bool "use assembler optimized string functions" - depends on !64BIT default y help Say yes here to use assembler optimized memcpy / memset functions. diff --git a/arch/mips/lib/memcpy.S b/arch/mips/lib/memcpy.S index cee0319dcf..5c01dbdcd3 100644 --- a/arch/mips/lib/memcpy.S +++ b/arch/mips/lib/memcpy.S @@ -20,7 +20,26 @@ #define src a1 #define len a2 -#define LOADK lw /* No exception */ +#ifdef CONFIG_64BIT + +#define LOAD(reg, addr)ld reg, addr +#define LOADL(reg, addr) ldl reg, addr +#define LOADR(reg, addr) ldr reg, addr +#define STOREL(reg, addr) sdl reg, addr +#define STORER(reg, addr) sdr reg, addr +#define STORE(reg, addr) sd reg, addr +#define ADDdaddu +#define SUBdsubu +#define SRLdsrl +#define SRAdsra +#define SLLdsll +#define SLLV dsllv +#define SRLV dsrlv +#define NBYTES 8 +#define LOG_NBYTES 3 + +#else + #define LOAD(reg, addr)lw reg, addr #define LOADL(reg, addr) lwl reg, addr #define LOADR(reg, addr) lwr reg, addr @@ -37,6 +56,8 @@ #define NBYTES 4 #define LOG_NBYTES 2 +#endif /* CONFIG_64BIT */ + #define LOADB(reg, addr) lb reg, addr #define STOREB(reg, addr) sb reg, addr @@ -101,8 +122,8 @@ LEAF(memcpy)/* a0=dst a1=src a2=len */ LOAD(t2, UNIT(2)(src)) LOAD(t3, UNIT(3)(src)) SUB len, len, 8*NBYTES - LOAD(t4, UNIT(4)(src)) - LOAD(t7, UNIT(5)(src)) + LOAD(ta0, UNIT(4)(src)) + LOAD(ta3, UNIT(5)(src)) STORE(t0, UNIT(0)(dst)) STORE(t1, UNIT(1)(dst)) LOAD(t0, UNIT(6)(src)) @@ -111,8 +132,8 @@ LEAF(memcpy)/* a0=dst a1=src a2=len */ ADD dst, dst, 8*NBYTES STORE(t2, UNIT(-6)(dst)) STORE(t3, UNIT(-5)(dst)) - STORE(t4, UNIT(-4)(dst)) - STORE(t7, UNIT(-3)(dst)) + STORE(ta0, UNIT(-4)(dst)) + STORE(ta3, UNIT(-3)(dst)) STORE(t0, UNIT(-2)(dst)) STORE(t1, UNIT(-1)(dst)) bne len, rem, 1b @@ -263,6 +284,12 @@ LEAF(memcpy) /* a0=dst a1=src a2=len */ COPY_BYTE(0) COPY_BYTE(1) +#ifdef CONFIG_64BIT + COPY_BYTE(2) + COPY_BYTE(3) + COPY_BYTE(4) + COPY_BYTE(5) +#endif LOADB(t0, NBYTES-2(src)) SUB len, len, 1 jr ra -- 2.41.0
[PATCH 05/17] MIPS: pbl: use o32/n64 compatible register definitions
This allows to compile PBL code with n64 ABI, which we use when CONFIG_64BIT is set. Signed-off-by: Denis Orlov --- arch/mips/include/asm/pbl_macros.h | 28 ++-- arch/mips/include/asm/pbl_nmon.h | 10 +- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/arch/mips/include/asm/pbl_macros.h b/arch/mips/include/asm/pbl_macros.h index c62910ff60..e60af38442 100644 --- a/arch/mips/include/asm/pbl_macros.h +++ b/arch/mips/include/asm/pbl_macros.h @@ -30,9 +30,9 @@ .set noreorder li t9, \addr li t8, \val - lw t7, 0(t9) - or t7, t8 - sw t7, 0(t9) + lw ta3, 0(t9) + or ta3, t8 + sw ta3, 0(t9) .setpop .endm @@ -41,10 +41,10 @@ .set noreorder li t9, \addr li t8, \clr - lw t7, 0(t9) + lw ta3, 0(t9) not t8, t8 - and t7, t8 - sw t7, 0(t9) + and ta3, t8 + sw ta3, 0(t9) .setpop .endm @@ -123,15 +123,15 @@ #define WSIZE 4 copy_loop: /* copy from source address [a0] */ - lw t4, WSIZE * 0(a0) - lw t5, WSIZE * 1(a0) - lw t6, WSIZE * 2(a0) - lw t7, WSIZE * 3(a0) + lw ta0, WSIZE * 0(a0) + lw ta1, WSIZE * 1(a0) + lw ta2, WSIZE * 2(a0) + lw ta3, WSIZE * 3(a0) /* copy to target address [a1] */ - sw t4, WSIZE * 0(a1) - sw t5, WSIZE * 1(a1) - sw t6, WSIZE * 2(a1) - sw t7, WSIZE * 3(a1) + sw ta0, WSIZE * 0(a1) + sw ta1, WSIZE * 1(a1) + sw ta2, WSIZE * 2(a1) + sw ta3, WSIZE * 3(a1) addia0, WSIZE * 4 subut3, a0, a2 blezt3, copy_loop diff --git a/arch/mips/include/asm/pbl_nmon.h b/arch/mips/include/asm/pbl_nmon.h index 0e4ec39967..7c8ec9d204 100644 --- a/arch/mips/include/asm/pbl_nmon.h +++ b/arch/mips/include/asm/pbl_nmon.h @@ -39,12 +39,12 @@ .setpush .setreorder - movet6, a0 - li t5, 32 + moveta2, a0 + li ta1, 32 202: - addit5, t5, -4 - srlva0, t6, t5 + addita1, ta1, -4 + srlva0, ta2, ta1 /* output one hex digit */ andia0, a0, 15 @@ -57,7 +57,7 @@ debug_ll_outc_a0 - bgtzt5, 202b + bgtzta1, 202b .setpop #endif /* CONFIG_DEBUG_LL */ -- 2.41.0
[PATCH 00/17] MIPS: fix and improve 64BIT support
The existing 64BIT support for MIPS was somewhat incomplete with no board having MIPS64 CPUs specified to be available as targets. Define Malta as supporting those and fix all the compilation and linking errors. Make some optional features available with 64BIT too. Denis Orlov (17): MIPS: malta: allow to choose MIPS64 target CPU in config MIPS: malta: use CKSEG instead of KSEG macros MIPS: reloc: fix relocation with CONFIG_64BIT enabled MIPS: o32: provide ta0..ta3 register definitions MIPS: pbl: use o32/n64 compatible register definitions MIPS: pbl: fix linking errors with CONFIG_64BIT MIPS: use MIPS32/MIPS64 generic instruction macros MIPS: malta: fix GT64120 base virtual address on 64BIT MIPS: fix addresses of exception vectors in 64-bit mode MIPS: fix *ADDR macro usage warnings on CONFIG_64BIT MIPS: Makefile: sign-extend TEXT_BASE value on CONFIG_64BIT MIPS: enable 64-bit kernel segment addressing on CONFIG_64BIT MIPS: traps: fix passing wrong sp when returning from exception MIPS: pbl_macros: use generic load/store macros in copy_to_link_location MIPS: add 64-bit support for optimized string functions MIPS: make setjmp/longjmp/initjmp available in 64BIT builds MIPS: main_entry-pbl: fix conversion warnings on CONFIG_64BIT arch/mips/Kconfig | 6 +- arch/mips/Makefile| 14 +++-- arch/mips/boards/qemu-malta/lowlevel.S| 4 +- arch/mips/boot/main_entry-pbl.c | 11 ++-- arch/mips/boot/main_entry.c | 2 +- arch/mips/boot/start.S| 4 +- arch/mips/include/asm/asm.h | 10 +-- arch/mips/include/asm/debug_ll_ns16550.h | 6 +- arch/mips/include/asm/dma.h | 16 ++--- arch/mips/include/asm/io.h| 2 +- arch/mips/include/asm/pbl_macros.h| 62 +++ arch/mips/include/asm/pbl_nmon.h | 10 +-- arch/mips/include/asm/regdef.h| 6 ++ arch/mips/include/asm/setjmp.h| 2 +- arch/mips/lib/genex.S | 8 +-- arch/mips/lib/memcpy.S| 37 +-- arch/mips/lib/reloc.c | 7 +-- arch/mips/lib/setjmp.S| 48 +++--- arch/mips/lib/traps.c | 2 +- .../mach-malta/include/mach/mach-gt64120.h| 2 +- arch/mips/mach-malta/pci.c| 2 +- 21 files changed, 156 insertions(+), 105 deletions(-) -- 2.41.0
[PATCH 10/17] MIPS: fix *ADDR macro usage warnings on CONFIG_64BIT
Fixes "warning: cast from pointer to integer of different size" messages. Signed-off-by: Denis Orlov --- arch/mips/include/asm/dma.h | 16 +--- arch/mips/include/asm/io.h | 2 +- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/arch/mips/include/asm/dma.h b/arch/mips/include/asm/dma.h index 62d9c7c548..d7570cce71 100644 --- a/arch/mips/include/asm/dma.h +++ b/arch/mips/include/asm/dma.h @@ -25,18 +25,20 @@ static inline void *dma_alloc(size_t size) #define dma_alloc_coherent dma_alloc_coherent static inline void *dma_alloc_coherent(size_t size, dma_addr_t *dma_handle) { - void *ret; + void *ptr; + unsigned long virt; - ret = xmemalign(PAGE_SIZE, size); + ptr = xmemalign(PAGE_SIZE, size); + memset(ptr, 0, size); - memset(ret, 0, size); + virt = (unsigned long)ptr; if (dma_handle) - *dma_handle = CPHYSADDR(ret); + *dma_handle = CPHYSADDR(virt); - dma_flush_range((unsigned long)ret, (unsigned long)(ret + size)); + dma_flush_range(virt, virt + size); - return (void *)CKSEG1ADDR(ret); + return (void *)CKSEG1ADDR(virt); } #define dma_free_coherent dma_free_coherent @@ -44,7 +46,7 @@ static inline void dma_free_coherent(void *vaddr, dma_addr_t dma_handle, size_t size) { if (IS_ENABLED(CONFIG_MMU) && vaddr) - free((void *)CKSEG0ADDR(vaddr)); + free((void *)CKSEG0ADDR((unsigned long)vaddr)); else free(vaddr); } diff --git a/arch/mips/include/asm/io.h b/arch/mips/include/asm/io.h index a3acbd7017..9c856c7b15 100644 --- a/arch/mips/include/asm/io.h +++ b/arch/mips/include/asm/io.h @@ -30,7 +30,7 @@ void dma_inv_range(unsigned long, unsigned long); #define virt_to_phys virt_to_phys static inline unsigned long virt_to_phys(const void *address) { - return (unsigned long)CPHYSADDR(address); + return CPHYSADDR((unsigned long)address); } /* -- 2.41.0
[PATCH 09/17] MIPS: fix addresses of exception vectors in 64-bit mode
Do not (accidentally?) truncate addresses when setting them in the handler array. Signed-off-by: Denis Orlov --- arch/mips/boot/main_entry.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/boot/main_entry.c b/arch/mips/boot/main_entry.c index 2c18bc81c3..d061a0e987 100644 --- a/arch/mips/boot/main_entry.c +++ b/arch/mips/boot/main_entry.c @@ -22,7 +22,7 @@ unsigned long exception_handlers[32]; static void set_except_vector(int n, void *addr) { - unsigned handler = (unsigned long) addr; + unsigned long handler = (unsigned long) addr; exception_handlers[n] = handler; } -- 2.41.0
[PATCH 12/17] MIPS: enable 64-bit kernel segment addressing on CONFIG_64BIT
This allows using addresses from XKPHYS segment. This is needed as we access hardware registers through this segment in 64BIT configuration, but this also lets us peek/poke bigger memory address space using commands that work with memory on 64BIT. With this commit, malta with 64-bit CPU finally boots into 64BIT barebox in QEMU. Signed-off-by: Denis Orlov --- arch/mips/boot/start.S | 2 ++ arch/mips/include/asm/pbl_macros.h | 11 +++ 2 files changed, 13 insertions(+) diff --git a/arch/mips/boot/start.S b/arch/mips/boot/start.S index 5f134f9ae9..30828ad9ef 100644 --- a/arch/mips/boot/start.S +++ b/arch/mips/boot/start.S @@ -26,6 +26,8 @@ EXPORT(_start) mips_disable_interrupts + mips64_enable_64bit_addressing + copy_to_link_location _start stack_setup diff --git a/arch/mips/include/asm/pbl_macros.h b/arch/mips/include/asm/pbl_macros.h index 1fba690c8c..ce169a1554 100644 --- a/arch/mips/include/asm/pbl_macros.h +++ b/arch/mips/include/asm/pbl_macros.h @@ -152,6 +152,17 @@ .setpop .endm + .macro mips64_enable_64bit_addressing +#ifdef CONFIG_64BIT + .setpush + .setnoreorder + mfc0k0, CP0_STATUS + or k0, ST0_KX + mtc0k0, CP0_STATUS + .setpop +#endif + .endm + .macro mips_barebox_10h .setpush .setnoreorder -- 2.41.0
[PATCH 07/17] MIPS: use MIPS32/MIPS64 generic instruction macros
Use PTR_* for various arithmetic operations on pointers, and also use PTR_LA instead of simple 'la' instruction, as it will correctly handle loading 64-bit addresses from non-32-bit-compatible virtual memory segments. This fixes "la used to load 64-bit address; recommend using dla instead" warnings when compiling assembly code with CONFIG_64BIT. Signed-off-by: Denis Orlov --- arch/mips/boot/start.S | 2 +- arch/mips/include/asm/asm.h | 10 +- arch/mips/include/asm/debug_ll_ns16550.h | 6 +++--- arch/mips/include/asm/pbl_macros.h | 22 +++--- arch/mips/lib/genex.S| 8 5 files changed, 24 insertions(+), 24 deletions(-) diff --git a/arch/mips/boot/start.S b/arch/mips/boot/start.S index c1cd2d9dd5..5f134f9ae9 100644 --- a/arch/mips/boot/start.S +++ b/arch/mips/boot/start.S @@ -34,7 +34,7 @@ EXPORT(_start) movea0, s0 movea1, s1 movea2, s2 - la v0, relocate_code + PTR_LA v0, relocate_code jal v0 nop diff --git a/arch/mips/include/asm/asm.h b/arch/mips/include/asm/asm.h index 69931662ff..c699542a55 100644 --- a/arch/mips/include/asm/asm.h +++ b/arch/mips/include/asm/asm.h @@ -94,10 +94,10 @@ EXPORT(symbol) copy_to_link_location symbol; \ stack_setup;\ \ - la a0, __dtb_ ## dtb##_start; \ - la a1, __dtb_ ## dtb##_end;\ - li a2, ram_size; \ - la v0, pbl_main_entry; \ + PTR_LA a0, __dtb_ ## dtb##_start; \ + PTR_LA a1, __dtb_ ## dtb##_end;\ + PTR_LI a2, ram_size; \ + PTR_LA v0, pbl_main_entry; \ jal v0; \ nop; \ \ @@ -122,7 +122,7 @@ EXPORT(symbol) /* Call some code from .text section. \ * It is needed to keep same linker script for \ * all images. */ \ - la v0, mips_dead_end; \ + PTR_LA v0, mips_dead_end; \ jal v0; \ nop; diff --git a/arch/mips/include/asm/debug_ll_ns16550.h b/arch/mips/include/asm/debug_ll_ns16550.h index 703bfaee77..7cfd844cb6 100644 --- a/arch/mips/include/asm/debug_ll_ns16550.h +++ b/arch/mips/include/asm/debug_ll_ns16550.h @@ -60,7 +60,7 @@ static inline void PUTC_LL(char ch) .macro debug_ll_ns16550_init divisor=DEBUG_LL_UART_DIVISOR #ifdef CONFIG_DEBUG_LL - la t0, DEBUG_LL_UART_ADDR + PTR_LA t0, DEBUG_LL_UART_ADDR li t1, UART_LCR_DLAB /* DLAB on */ sb t1, UART_LCR(t0)/* Write it out */ @@ -83,7 +83,7 @@ static inline void PUTC_LL(char ch) .setpush .setreorder - la t0, DEBUG_LL_UART_ADDR + PTR_LA t0, DEBUG_LL_UART_ADDR 201: lbu t1, UART_LSR(t0)/* get line status */ andit1, t1, UART_LSR_THRE /* check for transmitter empty */ @@ -126,7 +126,7 @@ static inline void PUTC_LL(char ch) .setpush .setreorder - la t0, DEBUG_LL_UART_ADDR + PTR_LA t0, DEBUG_LL_UART_ADDR /* get line status and check for data present */ lbu t1, UART_LSR(t0) diff --git a/arch/mips/include/asm/pbl_macros.h b/arch/mips/include/asm/pbl_macros.h index e60af38442..1fba690c8c 100644 --- a/arch/mips/include/asm/pbl_macros.h +++ b/arch/mips/include/asm/pbl_macros.h @@ -73,7 +73,7 @@ .macro pbl_probe_mem ret1 ret2 addr .setpush .setnoreorder - la \ret1, \addr + PTR_LA \ret1, \addr sw zero, 0(\ret1) li \ret2, 0x12345678 sw \ret2, 0(\ret1) @@ -97,7 +97,7 @@ move\temp, ra # preserve ra beforehand bal 255f nop -255: addiu \rd, ra, \label - 255b # label is assumed to be +255: PTR_ADDIU \rd, ra, \label - 255b # label is assumed to be movera, \temp # within pc +/- 32KB .setpop .endm @@ -110,15 +110,15 @@ ADR a0, \start_addr, t1 /* a0 <- pc-relative position of start_addr */ - la a1, \start_addr /* a1 <- link (RAM) start_addr address */ + PTR_LA a1, \start_addr /* a1 <- link (RAM) start_addr address */ beq a0, a1, copy_loop_exit nop - la t0, \start_addr - la t1, __bss_start - subut2, t1, t0 /
[PATCH 11/17] MIPS: Makefile: sign-extend TEXT_BASE value on CONFIG_64BIT
The code that uses TEXT_BASE will fail on reading truncated 32-bit address if running with 64BIT enabled. As we only support running from compatibility segments (i.e. no 'proper' 64-bit base addresses), simply make sure the value is sign-extended when passing it as a define. Signed-off-by: Denis Orlov --- arch/mips/Makefile | 8 +++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/arch/mips/Makefile b/arch/mips/Makefile index bad6e574c4..65a00379ab 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -57,7 +57,13 @@ cflags-$(CONFIG_CPU_MIPS64_R1) += $(call cc-option,-march=mips64,-mips64 -U_MIPS cflags-$(CONFIG_CPU_MIPS64_R2) += $(call cc-option,-march=mips64r2,-mips64r2 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS64) -Wa,-mips64r2 -Wa,--trap cflags-$(CONFIG_CPU_GS232) += $(call cc-option,-march=mips32r2,-mips32r2 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS32) -Wa,-mips32r2 -Wa,--trap -KBUILD_CPPFLAGS += -DTEXT_BASE=$(CONFIG_TEXT_BASE) +ifdef CONFIG_64BIT +MIPS_TEXT_BASE = $(subst 0x,0x,$(CONFIG_TEXT_BASE)) +else +MIPS_TEXT_BASE = $(CONFIG_TEXT_BASE) +endif + +KBUILD_CPPFLAGS += -DTEXT_BASE=$(MIPS_TEXT_BASE) ifndef CONFIG_MODULES # Add cleanup flags -- 2.41.0
[PATCH 14/17] MIPS: pbl_macros: use generic load/store macros in copy_to_link_location
This may speed up this code a little on MIPS64, however this also allows us to get rid of unnecessary macro definition there, simplifying the code a tiny bit. Signed-off-by: Denis Orlov --- arch/mips/include/asm/pbl_macros.h | 21 ++--- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/arch/mips/include/asm/pbl_macros.h b/arch/mips/include/asm/pbl_macros.h index ce169a1554..f8629d3f2c 100644 --- a/arch/mips/include/asm/pbl_macros.h +++ b/arch/mips/include/asm/pbl_macros.h @@ -120,22 +120,21 @@ PTR_SUBUt2, t1, t0 /* t2 <- size of pbl */ PTR_ADDUa2, a0, t2 /* a2 <- source end address */ -#define WSIZE 4 copy_loop: /* copy from source address [a0] */ - lw ta0, WSIZE * 0(a0) - lw ta1, WSIZE * 1(a0) - lw ta2, WSIZE * 2(a0) - lw ta3, WSIZE * 3(a0) + LONG_L ta0, LONGSIZE * 0(a0) + LONG_L ta1, LONGSIZE * 1(a0) + LONG_L ta2, LONGSIZE * 2(a0) + LONG_L ta3, LONGSIZE * 3(a0) /* copy to target address [a1] */ - sw ta0, WSIZE * 0(a1) - sw ta1, WSIZE * 1(a1) - sw ta2, WSIZE * 2(a1) - sw ta3, WSIZE * 3(a1) - PTR_ADDIa0, WSIZE * 4 + LONG_S ta0, LONGSIZE * 0(a1) + LONG_S ta1, LONGSIZE * 1(a1) + LONG_S ta2, LONGSIZE * 2(a1) + LONG_S ta3, LONGSIZE * 3(a1) + PTR_ADDIa0, LONGSIZE * 4 PTR_SUBUt3, a0, a2 blezt3, copy_loop -PTR_ADDI a1, WSIZE * 4 +PTR_ADDI a1, LONGSIZE * 4 copy_loop_exit: -- 2.41.0
[PATCH 17/17] MIPS: main_entry-pbl: fix conversion warnings on CONFIG_64BIT
Fix "cast from pointer to integer of different size" warnings by casting pointers into unsigned long values when calculating sizes. While at it, simplify code a bit, removing unnecessary variables and instead giving another variable a more comprehensible name. Signed-off-by: Denis Orlov --- arch/mips/boot/main_entry-pbl.c | 11 --- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/arch/mips/boot/main_entry-pbl.c b/arch/mips/boot/main_entry-pbl.c index 02ddd5ec24..f75ec03851 100644 --- a/arch/mips/boot/main_entry-pbl.c +++ b/arch/mips/boot/main_entry-pbl.c @@ -36,7 +36,7 @@ static void barebox_uncompress(void *compressed_start, unsigned int len) void __section(.text_entry) pbl_main_entry(void *fdt, void *fdt_end, u32 ram_size) { - u32 pg_start, pg_end, pg_len, fdt_len; + u32 piggy_len, fdt_len; void *fdt_new; void (*barebox)(void *fdt, u32 fdt_len, u32 ram_size); @@ -45,13 +45,10 @@ void __section(.text_entry) pbl_main_entry(void *fdt, void *fdt_end, /* clear bss */ memset(__bss_start, 0, __bss_stop - __bss_start); - pg_start = (u32)_data; - pg_end = (u32)_data_end; - pg_len = pg_end - pg_start; + piggy_len = (unsigned long)_data_end - (unsigned long)_data; + barebox_uncompress(_data, piggy_len); - barebox_uncompress(_data, pg_len); - - fdt_len = (u32)fdt_end - (u32)fdt; + fdt_len = (unsigned long)fdt_end - (unsigned long)fdt; fdt_new = (void *)PAGE_ALIGN_DOWN(TEXT_BASE - MALLOC_SIZE - STACK_SIZE - fdt_len); memcpy(fdt_new, fdt, fdt_len); -- 2.41.0
[PATCH 04/17] MIPS: o32: provide ta0..ta3 register definitions
This allows to write generic assembly code that will compile under both o32 and n64 ABIs, as otherwise the register definitions would conflict. Taken from Linux kernel sources, commit 'MIPS: O32: Provide definition of registers ta0 .. ta3.' (3ba1e543ab4b02640d396098f2f6a199560d5f2d). Signed-off-by: Denis Orlov --- arch/mips/include/asm/regdef.h | 6 ++ 1 file changed, 6 insertions(+) diff --git a/arch/mips/include/asm/regdef.h b/arch/mips/include/asm/regdef.h index 1300251661..df87582e8e 100644 --- a/arch/mips/include/asm/regdef.h +++ b/arch/mips/include/asm/regdef.h @@ -3,6 +3,8 @@ * Copyright (C) 1985 MIPS Computer Systems, Inc. * Copyright (C) 1994, 95, 99, 2003 by Ralf Baechle * Copyright (C) 1990 - 1992, 1999 Silicon Graphics, Inc. + * Copyright (C) 2011 Wind River Systems, + * written by Ralf Baechle */ #ifndef _ASM_REGDEF_H #define _ASM_REGDEF_H @@ -27,9 +29,13 @@ #define t2 $10 #define t3 $11 #define t4 $12 +#define ta0 $12 #define t5 $13 +#define ta1 $13 #define t6 $14 +#define ta2 $14 #define t7 $15 +#define ta3 $15 #define s0 $16 /* callee saved */ #define s1 $17 #define s2 $18 -- 2.41.0
[PATCH 03/17] MIPS: reloc: fix relocation with CONFIG_64BIT enabled
Use CKSEG instead of KSEG, allowing it to compile on 64BIT configurations. Also make sure that we do not truncate target relocation address by writing it into a 32-bit wide variable. Signed-off-by: Denis Orlov --- arch/mips/lib/reloc.c | 7 +++ 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/arch/mips/lib/reloc.c b/arch/mips/lib/reloc.c index b084a88be7..3c845a9663 100644 --- a/arch/mips/lib/reloc.c +++ b/arch/mips/lib/reloc.c @@ -108,8 +108,7 @@ static void apply_reloc(unsigned int type, void *addr, long off) void relocate_code(void *fdt, u32 fdt_size, u32 ram_size) { - unsigned long addr, length, bss_len; - u32 relocaddr, new_stack; + unsigned long addr, length, bss_len, relocaddr, new_stack; uint8_t *buf; unsigned int type; long off; @@ -121,9 +120,9 @@ void relocate_code(void *fdt, u32 fdt_size, u32 ram_size) length = __bss_stop - __image_start; relocaddr = ALIGN_DOWN(ram_size - length, SZ_64K); if (IS_ENABLED(CONFIG_MMU)) { - relocaddr = KSEG0ADDR(relocaddr); + relocaddr = CKSEG0ADDR(relocaddr); } else { - relocaddr = KSEG1ADDR(relocaddr); + relocaddr = CKSEG1ADDR(relocaddr); } new_stack = relocaddr - MALLOC_SIZE - 16; -- 2.41.0
[PATCH 01/17] MIPS: malta: allow to choose MIPS64 target CPU in config
QEMU is able to emulate malta machine with a variety of MIPS CPUs, including MIPS64 ones, so allow to compile barebox for such configurations. Signed-off-by: Denis Orlov --- arch/mips/Kconfig | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 70d85690da..ab8c8cf176 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -70,8 +70,11 @@ config MACH_MIPS_MALTA select CSRC_R4K_LIB select DRIVER_SERIAL_NS16550 select SYS_HAS_CPU_MIPS32_R1 + select SYS_HAS_CPU_MIPS64_R1 select SYS_HAS_CPU_MIPS32_R2 + select SYS_HAS_CPU_MIPS64_R2 select SYS_SUPPORTS_32BIT_KERNEL + select SYS_SUPPORTS_64BIT_KERNEL select SYS_SUPPORTS_BIG_ENDIAN select SYS_SUPPORTS_LITTLE_ENDIAN select HAS_DEBUG_LL -- 2.41.0
[PATCH 08/17] MIPS: malta: fix GT64120 base virtual address on 64BIT
Use CKSEG1ADDR for it to be properly converted to the 64-bit sign-extended address when building with CONFIG_64BIT set. Signed-off-by: Denis Orlov --- arch/mips/mach-malta/include/mach/mach-gt64120.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/mach-malta/include/mach/mach-gt64120.h b/arch/mips/mach-malta/include/mach/mach-gt64120.h index e7d230655c..20ac4d94d6 100644 --- a/arch/mips/mach-malta/include/mach/mach-gt64120.h +++ b/arch/mips/mach-malta/include/mach/mach-gt64120.h @@ -12,6 +12,6 @@ #define MIPS_GT_BASE 0x1be0 -#define GT64120_BASE0xbbe0 +#define GT64120_BASECKSEG1ADDR(MIPS_GT_BASE) #endif /* _ASM_MACH_MIPS_MACH_GT64120_DEP_H */ -- 2.41.0
[PATCH 06/17] MIPS: pbl: fix linking errors with CONFIG_64BIT
For some reasons, object file format was not passed to the linker when linking PBL, leading for a bunch of "ABI is incompatible with that of the selected emulation" errors. Fix it, and also remove duplicate flags being passed when linking barebox proper. Signed-off-by: Denis Orlov --- arch/mips/Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 345e703d33..bad6e574c4 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -45,8 +45,8 @@ mips-ldflags-y += $(shell $(CC) -dumpmachine |grep -q 'mips.*el-.*' || echo -EL endif KBUILD_LDFLAGS += $(mips-ldflags-y) -m $(ld-emul) -LDFLAGS_barebox += $(mips-ldflags-y) -LDFLAGS_pbl += $(mips-ldflags-y) +LDFLAGS_barebox += $(KBUILD_LDFLAGS) +LDFLAGS_pbl += $(KBUILD_LDFLAGS) # # CPU-dependent compiler/assembler options for optimization. @@ -100,7 +100,7 @@ KBUILD_CFLAGS += $(cflags-y) lds-$(CONFIG_GENERIC_LINKER_SCRIPT) := arch/mips/lib/barebox.lds -cmd_barebox__ ?= $(LD) $(KBUILD_LDFLAGS) $(LDFLAGS_barebox) -o $@ \ +cmd_barebox__ ?= $(LD) $(LDFLAGS_barebox) -o $@ \ -T $(BAREBOX_LDS) \ --whole-archive $(BAREBOX_OBJS) --no-whole-archive\ $(filter-out $(BAREBOX_LDS) $(BAREBOX_OBJS) FORCE ,$^); \ -- 2.41.0
[PATCH 02/17] MIPS: malta: use CKSEG instead of KSEG macros
KSEG macro is not available when compiling with CONFIG_64BIT enabled, so use CKSEG instead. Signed-off-by: Denis Orlov --- arch/mips/boards/qemu-malta/lowlevel.S | 4 ++-- arch/mips/mach-malta/pci.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/mips/boards/qemu-malta/lowlevel.S b/arch/mips/boards/qemu-malta/lowlevel.S index 98821e0426..541d62fc2a 100644 --- a/arch/mips/boards/qemu-malta/lowlevel.S +++ b/arch/mips/boards/qemu-malta/lowlevel.S @@ -56,14 +56,14 @@ __start: */ /* move GT64120 registers to 0x1be0 */ - li t1, KSEG1ADDR(GT_DEF_BASE) + li t1, CKSEG1ADDR(GT_DEF_BASE) li t0, GT_LD(MIPS_GT_BASE) sw t0, GT_ISD_OFS(t1) /* * setup MEM-to-PCI0 mapping */ - li t1, KSEG1ADDR(MIPS_GT_BASE) + li t1, CKSEG1ADDR(MIPS_GT_BASE) /* setup PCI0 io window */ li t0, GT_LD(0x1800) diff --git a/arch/mips/mach-malta/pci.c b/arch/mips/mach-malta/pci.c index 113b94fe23..0ab239f509 100644 --- a/arch/mips/mach-malta/pci.c +++ b/arch/mips/mach-malta/pci.c @@ -136,7 +136,7 @@ static int gt64xxx_pci0_pcibios_write(struct pci_bus *bus, unsigned int devfn, static resource_size_t gt64xxx_res_start(struct pci_bus *bus, resource_size_t res_addr) { - return KSEG0ADDR(res_addr); + return CKSEG0ADDR(res_addr); } struct pci_ops gt64xxx_pci0_ops = { -- 2.41.0
[PATCH 16/17] MIPS: make setjmp/longjmp/initjmp available in 64BIT builds
Make the code compatible with 64-bit configurations by storing saved register values with unsigned long type and using generic macros in assembly code. Signed-off-by: Denis Orlov --- arch/mips/Kconfig | 2 +- arch/mips/include/asm/setjmp.h | 2 +- arch/mips/lib/setjmp.S | 48 +- 3 files changed, 26 insertions(+), 26 deletions(-) diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index de2f539cc1..e05ee2d7f1 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -10,6 +10,7 @@ config MIPS select HAVE_PBL_MULTI_IMAGES select HAS_DMA select ARCH_HAS_DATA_ABORT_MASK + select ARCH_HAS_SJLJ select ELF default y @@ -305,7 +306,6 @@ choice config 32BIT bool "32-bit barebox" depends on CPU_SUPPORTS_32BIT_KERNEL && SYS_SUPPORTS_32BIT_KERNEL - select ARCH_HAS_SJLJ help Select this option if you want to build a 32-bit barebox. diff --git a/arch/mips/include/asm/setjmp.h b/arch/mips/include/asm/setjmp.h index 81f4d4c15f..39e01e27df 100644 --- a/arch/mips/include/asm/setjmp.h +++ b/arch/mips/include/asm/setjmp.h @@ -19,7 +19,7 @@ typedef struct __jmp_buf_internal_tag { void *__sp; /* Callee-saved registers s0 through s7. */ - int __regs[8]; + unsigned long __regs[8]; /* The frame pointer. */ void *__fp; diff --git a/arch/mips/lib/setjmp.S b/arch/mips/lib/setjmp.S index b09a7c5529..42a2ec15a9 100644 --- a/arch/mips/lib/setjmp.S +++ b/arch/mips/lib/setjmp.S @@ -6,34 +6,34 @@ /* int setjmp (jmp_buf); */ LEAF(setjmp) - sw ra, (0 * 4)(a0) - sw sp, (1 * 4)(a0) - sw s0, (2 * 4)(a0) - sw s1, (3 * 4)(a0) - sw s2, (4 * 4)(a0) - sw s3, (5 * 4)(a0) - sw s4, (6 * 4)(a0) - sw s5, (7 * 4)(a0) - sw s6, (8 * 4)(a0) - sw s7, (9 * 4)(a0) - sw fp, (10 * 4)(a0) + REG_S ra, (0 * SZREG)(a0) + REG_S sp, (1 * SZREG)(a0) + REG_S s0, (2 * SZREG)(a0) + REG_S s1, (3 * SZREG)(a0) + REG_S s2, (4 * SZREG)(a0) + REG_S s3, (5 * SZREG)(a0) + REG_S s4, (6 * SZREG)(a0) + REG_S s5, (7 * SZREG)(a0) + REG_S s6, (8 * SZREG)(a0) + REG_S s7, (9 * SZREG)(a0) + REG_S fp, (10 * SZREG)(a0) movev0, zero j ra END(setjmp) /* volatile void longjmp (jmp_buf, int); */ LEAF(longjmp) - lw ra, (0 * 4)(a0) - lw sp, (1 * 4)(a0) - lw s0, (2 * 4)(a0) - lw s1, (3 * 4)(a0) - lw s2, (4 * 4)(a0) - lw s3, (5 * 4)(a0) - lw s4, (6 * 4)(a0) - lw s5, (7 * 4)(a0) - lw s6, (8 * 4)(a0) - lw s7, (9 * 4)(a0) - lw fp, (10 * 4)(a0) + REG_L ra, (0 * SZREG)(a0) + REG_L sp, (1 * SZREG)(a0) + REG_L s0, (2 * SZREG)(a0) + REG_L s1, (3 * SZREG)(a0) + REG_L s2, (4 * SZREG)(a0) + REG_L s3, (5 * SZREG)(a0) + REG_L s4, (6 * SZREG)(a0) + REG_L s5, (7 * SZREG)(a0) + REG_L s6, (8 * SZREG)(a0) + REG_L s7, (9 * SZREG)(a0) + REG_L fp, (10 * SZREG)(a0) bne a1, zero, 1f li a1, 1 1: @@ -43,8 +43,8 @@ END(longjmp) /* int initjmp(jmp_buf jmp, void __noreturn (*func)(void), void *stack_top); */ LEAF(initjmp) - sw a1, (0 * 4)(a0) - sw a2, (1 * 4)(a0) + REG_S a1, (0 * SZREG)(a0) + REG_S a2, (1 * SZREG)(a0) movev0, zero j ra END(initjmp) -- 2.41.0
[PATCH 13/17] MIPS: traps: fix passing wrong sp when returning from exception
This code seems to have been working on 32-bit builds by accident. However it totally broke on 64 bits, resulting in "restoring" some garbage into registers. The reason the code worked on 32 bits is this. When we are entering the barebox_exc_handler() function, we are passing in a register the current stack pointer as an argument (which corresponds to the regs parameter). On o32 ABI the space for arguments passed in registers is reserved on the stack by the caller. So, when we are taking the address of regs in the body of the function, we have to put this argument on the stack, into the first reserved slot. However, this slot is located exactly at the current 'sp' and thus the address of regs happens to be the same as its value! On n64 ABI, however, the arguments passed in registers are saved onto the stack on the callee side, so we end up with the wrong value being used as the stack pointer. Signed-off-by: Denis Orlov --- arch/mips/lib/traps.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/lib/traps.c b/arch/mips/lib/traps.c index ff0a54af8e..45694fe7ef 100644 --- a/arch/mips/lib/traps.c +++ b/arch/mips/lib/traps.c @@ -173,7 +173,7 @@ void barebox_exc_handler(struct pt_regs *regs) "move\t$29, %0\n\t" "j\tret_from_exception" :/* no outputs */ - :"r" ()); + :"r" (regs)); /* Unreached */ -- 2.41.0
[PATCH 2/2] MIPS: enable more options in malta defconfigs
This mainly enables virtio stuff, but also turns on EXT4 and GPT support. The latter two simplify things somewhat, allowing to mount appropriate images, and are enabled in generic defconfigs for other archs. Signed-off-by: Denis Orlov --- arch/mips/configs/qemu-malta64el_defconfig | 10 +- arch/mips/configs/qemu-malta_defconfig | 10 +- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/arch/mips/configs/qemu-malta64el_defconfig b/arch/mips/configs/qemu-malta64el_defconfig index 5fb090a646..6091e6d030 100644 --- a/arch/mips/configs/qemu-malta64el_defconfig +++ b/arch/mips/configs/qemu-malta64el_defconfig @@ -13,7 +13,7 @@ CONFIG_AUTO_COMPLETE=y CONFIG_MENU=y CONFIG_BOOTM_SHOW_TYPE=y CONFIG_CONSOLE_ALLOW_COLOR=y -CONFIG_PARTITION=y +CONFIG_PARTITION_DISK_EFI=y CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW=y CONFIG_CMD_DMESG=y CONFIG_LONGHELP=y @@ -62,6 +62,7 @@ CONFIG_NET_NFS=y CONFIG_NET_NETCONSOLE=y CONFIG_OFDEVICE=y CONFIG_OF_BAREBOX_DRIVERS=y +CONFIG_VIRTIO_CONSOLE=y CONFIG_DRIVER_NET_RTL8139=y # CONFIG_SPI is not set CONFIG_I2C=y @@ -72,15 +73,22 @@ CONFIG_DRIVER_CFI=y # CONFIG_DRIVER_CFI_BANK_WIDTH_1 is not set # CONFIG_DRIVER_CFI_BANK_WIDTH_2 is not set CONFIG_CFI_BUFFER_WRITE=y +CONFIG_DISK=y +CONFIG_VIRTIO_BLK=y CONFIG_VIDEO=y CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_DRIVER_VIDEO_BOCHS_PCI=y +CONFIG_VIRTIO_INPUT=y +CONFIG_HWRNG=y +CONFIG_HW_RANDOM_VIRTIO=y CONFIG_GPIO_MALTA_FPGA_I2C=y CONFIG_PCI=y CONFIG_PCI_DEBUG=y CONFIG_SYSCON_REBOOT_MODE=y CONFIG_POWER_RESET_SYSCON=y +CONFIG_VIRTIO_PCI=y CONFIG_FS_CRAMFS=y +CONFIG_FS_EXT4=y CONFIG_FS_TFTP=y CONFIG_FS_FAT=y CONFIG_FS_FAT_WRITE=y diff --git a/arch/mips/configs/qemu-malta_defconfig b/arch/mips/configs/qemu-malta_defconfig index ab3abb7a2a..6cbc4efa86 100644 --- a/arch/mips/configs/qemu-malta_defconfig +++ b/arch/mips/configs/qemu-malta_defconfig @@ -10,7 +10,7 @@ CONFIG_AUTO_COMPLETE=y CONFIG_MENU=y CONFIG_BOOTM_SHOW_TYPE=y CONFIG_CONSOLE_ALLOW_COLOR=y -CONFIG_PARTITION=y +CONFIG_PARTITION_DISK_EFI=y CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW=y CONFIG_CMD_DMESG=y CONFIG_LONGHELP=y @@ -59,6 +59,7 @@ CONFIG_NET_NFS=y CONFIG_NET_NETCONSOLE=y CONFIG_OFDEVICE=y CONFIG_OF_BAREBOX_DRIVERS=y +CONFIG_VIRTIO_CONSOLE=y CONFIG_DRIVER_NET_RTL8139=y # CONFIG_SPI is not set CONFIG_I2C=y @@ -69,15 +70,22 @@ CONFIG_DRIVER_CFI=y # CONFIG_DRIVER_CFI_BANK_WIDTH_1 is not set # CONFIG_DRIVER_CFI_BANK_WIDTH_2 is not set CONFIG_CFI_BUFFER_WRITE=y +CONFIG_DISK=y +CONFIG_VIRTIO_BLK=y CONFIG_VIDEO=y CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_DRIVER_VIDEO_BOCHS_PCI=y +CONFIG_VIRTIO_INPUT=y +CONFIG_HWRNG=y +CONFIG_HW_RANDOM_VIRTIO=y CONFIG_GPIO_MALTA_FPGA_I2C=y CONFIG_PCI=y CONFIG_PCI_DEBUG=y CONFIG_SYSCON_REBOOT_MODE=y CONFIG_POWER_RESET_SYSCON=y +CONFIG_VIRTIO_PCI=y CONFIG_FS_CRAMFS=y +CONFIG_FS_EXT4=y CONFIG_FS_TFTP=y CONFIG_FS_FAT=y CONFIG_FS_FAT_WRITE=y -- 2.41.0