[PATCH 0/1] MIPS: fix optimised memset returning garbage

2022-03-10 Thread Denis Orlov
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

2022-03-10 Thread Denis Orlov
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

2022-03-10 Thread Denis Orlov
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()

2022-03-01 Thread Denis Orlov
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

2022-03-01 Thread Denis Orlov
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()

2022-03-29 Thread Denis Orlov
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()

2022-04-26 Thread Denis Orlov
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

2022-05-16 Thread Denis Orlov
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

2022-05-20 Thread Denis Orlov
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

2022-07-20 Thread Denis Orlov
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

2022-07-20 Thread Denis Orlov
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

2022-07-20 Thread Denis Orlov
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()

2022-07-20 Thread Denis Orlov
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()

2022-07-20 Thread Denis Orlov
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

2022-07-20 Thread Denis Orlov
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

2022-07-20 Thread Denis Orlov
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

2022-07-20 Thread Denis Orlov
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

2022-05-04 Thread Denis Orlov
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()

2022-05-04 Thread Denis Orlov
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

2022-05-04 Thread Denis Orlov
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

2022-05-04 Thread Denis Orlov
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()

2022-05-04 Thread Denis Orlov
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

2022-05-04 Thread Denis Orlov
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()

2022-05-04 Thread Denis Orlov
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()

2022-05-04 Thread Denis Orlov
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

2022-05-04 Thread Denis Orlov
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

2022-05-04 Thread Denis Orlov
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*

2022-05-04 Thread Denis Orlov
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

2022-05-04 Thread Denis Orlov
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

2022-05-04 Thread Denis Orlov
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()

2022-05-04 Thread Denis Orlov
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

2022-05-04 Thread Denis Orlov
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

2022-05-04 Thread Denis Orlov
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

2022-05-05 Thread Denis Orlov
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

2022-10-31 Thread Denis Orlov
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()

2022-10-31 Thread Denis Orlov
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

2023-01-13 Thread Denis Orlov
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

2023-01-13 Thread Denis Orlov
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

2023-03-16 Thread Denis Orlov
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

2023-03-13 Thread Denis Orlov
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_*

2023-03-13 Thread Denis Orlov
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

2023-03-13 Thread Denis Orlov
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

2023-03-13 Thread Denis Orlov
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()

2023-03-15 Thread Denis Orlov
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

2023-03-15 Thread Denis Orlov
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

2023-03-15 Thread Denis Orlov
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()

2023-03-15 Thread Denis Orlov
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

2023-03-15 Thread Denis Orlov
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

2023-03-06 Thread Denis Orlov
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

2023-02-28 Thread Denis Orlov
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

2023-02-28 Thread Denis Orlov
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

2023-02-28 Thread Denis Orlov
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

2023-02-09 Thread Denis Orlov
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

2023-02-08 Thread Denis Orlov
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

2023-02-08 Thread Denis Orlov
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

2023-02-08 Thread Denis Orlov
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

2023-02-10 Thread Denis Orlov
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

2023-02-10 Thread Denis Orlov
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

2023-02-10 Thread Denis Orlov
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

2023-02-10 Thread Denis Orlov
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

2023-02-10 Thread Denis Orlov
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

2023-02-10 Thread Denis Orlov
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

2023-02-10 Thread Denis Orlov
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

2023-02-10 Thread Denis Orlov
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"

2023-05-31 Thread Denis Orlov
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

2023-06-04 Thread Denis Orlov
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

2023-06-04 Thread Denis Orlov
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

2023-06-04 Thread Denis Orlov
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

2023-06-04 Thread Denis Orlov
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

2023-06-09 Thread Denis Orlov
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

2023-06-09 Thread Denis Orlov
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

2023-06-08 Thread Denis Orlov
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

2023-06-08 Thread Denis Orlov
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

2023-06-08 Thread Denis Orlov
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

2023-06-08 Thread Denis Orlov
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

2023-06-09 Thread Denis Orlov
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

2023-06-09 Thread Denis Orlov
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

2023-06-06 Thread Denis Orlov
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

2023-06-06 Thread Denis Orlov
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

2023-06-06 Thread Denis Orlov
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

2023-06-06 Thread Denis Orlov
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

2023-06-05 Thread Denis Orlov
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

2023-06-05 Thread Denis Orlov
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

2023-06-05 Thread Denis Orlov
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

2023-06-05 Thread Denis Orlov
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

2023-06-05 Thread Denis Orlov
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

2023-06-05 Thread Denis Orlov
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

2023-06-05 Thread Denis Orlov
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

2023-06-05 Thread Denis Orlov
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

2023-06-05 Thread Denis Orlov
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

2023-06-05 Thread Denis Orlov
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

2023-06-05 Thread Denis Orlov
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

2023-06-05 Thread Denis Orlov
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

2023-06-05 Thread Denis Orlov
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

2023-06-05 Thread Denis Orlov
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

2023-06-05 Thread Denis Orlov
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

2023-06-05 Thread Denis Orlov
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

2023-06-05 Thread Denis Orlov
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

2023-06-05 Thread Denis Orlov
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

2023-06-10 Thread Denis Orlov
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




  1   2   >