[U-Boot] [PATCH v3] ata: ahci allow 64-bit DMA for SATA

2019-10-14 Thread Roman Kapl
Allow 64-bit DMA on AHCI. If not supported by the host controller, at
least print a message and fail.

Signed-off-by: Roman Kapl 
---
v1 -> v2: v1 was a mistake
v2 -> v3: suppress warning on 32-bit phys addr platforms by using the
   upper/lower 32 bits macros

 drivers/ata/ahci.c | 14 +++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index 21a89eba5a..d10f9f0bf8 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -50,6 +50,8 @@ struct ahci_uc_priv *probe_ent = NULL;
 #define WAIT_MS_FLUSH  5000
 #define WAIT_MS_LINKUP 200
 
+#define AHCI_CAP_S64A BIT(31)
+
 __weak void __iomem *ahci_port_base(void __iomem *base, u32 port)
 {
return base + 0x100 + (port * 0x80);
@@ -503,9 +505,15 @@ static int ahci_fill_sg(struct ahci_uc_priv *uc_priv, u8 
port,
}
 
for (i = 0; i < sg_count; i++) {
-   ahci_sg->addr =
-   cpu_to_le32((unsigned long) buf + i * MAX_DATA_BYTE_COUNT);
-   ahci_sg->addr_hi = 0;
+   /* We assume virt=phys */
+   phys_addr_t pa = (unsigned long)buf + i * MAX_DATA_BYTE_COUNT;
+
+   ahci_sg->addr = cpu_to_le32(lower_32_bits(pa));
+   ahci_sg->addr_hi = cpu_to_le32(upper_32_bits(pa));
+   if (ahci_sg->addr_hi && !(uc_priv->cap & AHCI_CAP_S64A)) {
+   printf("Error: DMA address too high\n");
+   return -1;
+   }
ahci_sg->flags_size = cpu_to_le32(0x3f &
  (buf_len < MAX_DATA_BYTE_COUNT
   ? (buf_len - 1)
-- 
2.22.0

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH v2] ata: ahci allow 64-bit DMA for SATA

2019-08-28 Thread Roman Kapl
Allow 64-bit DMA on AHCI. If not supported by the host controller, at
least print a message and fail.

Signed-off-by: Roman Kapl 
---

Please disregard the previous patch, I've send a wrong version that does not
even compile.

 drivers/ata/ahci.c | 14 +++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index 9a08575053..fd4df60a17 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -50,6 +50,8 @@ struct ahci_uc_priv *probe_ent = NULL;
 #define WAIT_MS_FLUSH  5000
 #define WAIT_MS_LINKUP 200
 
+#define AHCI_CAP_S64A (1u << 31)
+
 __weak void __iomem *ahci_port_base(void __iomem *base, u32 port)
 {
return base + 0x100 + (port * 0x80);
@@ -503,9 +505,15 @@ static int ahci_fill_sg(struct ahci_uc_priv *uc_priv, u8 
port,
}
 
for (i = 0; i < sg_count; i++) {
-   ahci_sg->addr =
-   cpu_to_le32((unsigned long) buf + i * MAX_DATA_BYTE_COUNT);
-   ahci_sg->addr_hi = 0;
+   /* We assume virt=phys */
+   phys_addr_t pa = (unsigned long)buf + i * MAX_DATA_BYTE_COUNT;
+
+   ahci_sg->addr = cpu_to_le32(pa & U32_MAX);
+   ahci_sg->addr_hi = cpu_to_le32((pa >> 32) & U32_MAX);
+   if (ahci_sg->addr_hi && !(uc_priv->cap & AHCI_CAP_S64A)) {
+   printf("Error: DMA address too high\n");
+   return -1;
+   }
ahci_sg->flags_size = cpu_to_le32(0x3f &
  (buf_len < MAX_DATA_BYTE_COUNT
   ? (buf_len - 1)
-- 
2.22.0

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH] ata: ahci allow 64-bit DMA for SATA

2019-08-28 Thread Roman Kapl
Allow 64-bit DMA on AHCI. If not supported by the host controller, at
least print a message and fail.

Signed-off-by: Roman Kapl 
---
 drivers/ata/ahci.c | 12 +---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index 9a08575053..02007ad4bd 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -503,9 +503,15 @@ static int ahci_fill_sg(struct ahci_uc_priv *uc_priv, u8 
port,
}
 
for (i = 0; i < sg_count; i++) {
-   ahci_sg->addr =
-   cpu_to_le32((unsigned long) buf + i * MAX_DATA_BYTE_COUNT);
-   ahci_sg->addr_hi = 0;
+   /* We assume virt=phys */
+   phys_addr_t pa = (unsigned long)buf + i * MAX_DATA_BYTE_COUNT;
+
+   ahci_sg->addr = cpu_to_le32(pa & U32_MAX);
+   ahci_sg->addr_hi = cpu_to_le32((pa >> 32) & U32_MAX);
+   if (ahci_sg->addr_hi && !(uc_priv->cap & AHCI_CAP_S64A)) {
+   printf("Error: DMA address too high\n");
+   return -1;
+   }
ahci_sg->flags_size = cpu_to_le32(0x3f &
  (buf_len < MAX_DATA_BYTE_COUNT
   ? (buf_len - 1)
-- 
2.22.0

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH] tpm: wait for valid status

2019-05-16 Thread Roman Kapl
The TPM specification says that the EXPECT_DATA bit is not valid until
the VALID bit is set. Wait for that bit to be set. Fixes problems with
Ifineon SPI TPM.

Signed-off-by: Roman Kapl 
---
 drivers/tpm/tpm2_tis_spi.c | 12 ++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/tpm/tpm2_tis_spi.c b/drivers/tpm/tpm2_tis_spi.c
index 8878130bd7..7186c179d1 100644
--- a/drivers/tpm/tpm2_tis_spi.c
+++ b/drivers/tpm/tpm2_tis_spi.c
@@ -295,6 +295,14 @@ static int tpm_tis_spi_wait_for_stat(struct udevice *dev, 
u8 mask,
return -ETIMEDOUT;
 }
 
+static u8 tpm_tis_spi_valid_status(struct udevice *dev, u8 *status)
+{
+   struct tpm_chip *chip = dev_get_priv(dev);
+
+   return tpm_tis_spi_wait_for_stat(dev, TPM_STS_VALID,
+   chip->timeout_c, status);
+}
+
 static int tpm_tis_spi_get_burstcount(struct udevice *dev)
 {
struct tpm_chip *chip = dev_get_priv(dev);
@@ -455,7 +463,7 @@ static int tpm_tis_spi_send(struct udevice *dev, const u8 
*buf, size_t len)
i += size;
}
 
-   ret = tpm_tis_spi_status(dev, );
+   ret = tpm_tis_spi_valid_status(dev, );
if (ret)
goto out_err;
 
@@ -469,7 +477,7 @@ static int tpm_tis_spi_send(struct udevice *dev, const u8 
*buf, size_t len)
if (ret)
goto out_err;
 
-   ret = tpm_tis_spi_status(dev, );
+   ret = tpm_tis_spi_valid_status(dev, );
if (ret)
goto out_err;
 
-- 
2.20.1.390.gb5101f9297

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH] cmd: date: Do not overwrite arguments

2019-02-08 Thread Roman Kapl
Arguments are const and belong to the caller. Calling date in a hush
loop will yield different results from the second invocation.

Signed-off-by: Roman Kapl 
---
 cmd/date.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/cmd/date.c b/cmd/date.c
index 1115b6c8d6..7fa950a902 100644
--- a/cmd/date.c
+++ b/cmd/date.c
@@ -159,18 +159,18 @@ int mk_date (const char *datestr, struct rtc_time *tmp)
int len, val;
char *ptr;
 
-   ptr = strchr (datestr,'.');
-   len = strlen (datestr);
+   ptr = strchr(datestr, '.');
+   len = strlen(datestr);
 
/* Set seconds */
if (ptr) {
int sec;
 
-   *ptr++ = '\0';
+   ptr++;
if ((len - (ptr - datestr)) != 2)
return (-1);
 
-   len = strlen (datestr);
+   len -= 3;
 
if (cnvrt2 (ptr, ))
return (-1);
-- 
2.20.1.390.gb5101f9297

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH] hashtable: fix environment variable corruption

2019-01-30 Thread Roman Kapl
Only first previously deleted entry was recognized, leading hsearch_r
to think that there was no previously deleted entry. It then conluded
that a free entry was found, even if there were no free entries and it
overwrote a random entry.

This patch makes sure all deleted or free entries are always found and
also introduces constants for the 0 and -1 numbers. Unit tests to excersise a
simple hash table usage and catch the corruption were added.

To trash your environment, simply run this loop:

setenv i 0
while true; do
setenv v_$i $i
setenv v_$i
setexpr i $i + 1
done

Signed-off-by: Roman Kapl 
---

Note: The hash-table will still degenerate into a linear search in the
case above, maybe re-hashing should be done with an appropriate
trigger.


 lib/hashtable.c  |  13 --
 test/env/Makefile|   1 +
 test/env/hashtable.c | 125 +++
 3 files changed, 136 insertions(+), 3 deletions(-)
 create mode 100644 test/env/hashtable.c

diff --git a/lib/hashtable.c b/lib/hashtable.c
index 50ff40a397..0d288d12d9 100644
--- a/lib/hashtable.c
+++ b/lib/hashtable.c
@@ -40,6 +40,9 @@
 #defineCONFIG_ENV_MAX_ENTRIES 512
 #endif
 
+#define USED_FREE 0
+#define USED_DELETED -1
+
 #include 
 #include 
 #include 
@@ -303,7 +306,7 @@ int hsearch_r(ENTRY item, ACTION action, ENTRY ** retval,
 */
unsigned hval2;
 
-   if (htab->table[idx].used == -1
+   if (htab->table[idx].used == USED_DELETED
&& !first_deleted)
first_deleted = idx;
 
@@ -335,13 +338,17 @@ int hsearch_r(ENTRY item, ACTION action, ENTRY ** retval,
if (idx == hval)
break;
 
+   if (htab->table[idx].used == USED_DELETED
+   && !first_deleted)
+   first_deleted = idx;
+
/* If entry is found use it. */
ret = _compare_and_overwrite_entry(item, action, retval,
htab, flag, hval, idx);
if (ret != -1)
return ret;
}
-   while (htab->table[idx].used);
+   while (htab->table[idx].used != USED_FREE);
}
 
/* An empty bucket has been found. */
@@ -433,7 +440,7 @@ static void _hdelete(const char *key, struct hsearch_data 
*htab, ENTRY *ep,
free(ep->data);
ep->callback = NULL;
ep->flags = 0;
-   htab->table[idx].used = -1;
+   htab->table[idx].used = USED_DELETED;
 
--htab->filled;
 }
diff --git a/test/env/Makefile b/test/env/Makefile
index d71a11b6e2..5c8eae31b0 100644
--- a/test/env/Makefile
+++ b/test/env/Makefile
@@ -4,3 +4,4 @@
 
 obj-y += cmd_ut_env.o
 obj-y += attr.o
+obj-y += hashtable.o
diff --git a/test/env/hashtable.c b/test/env/hashtable.c
new file mode 100644
index 00..8c87e65457
--- /dev/null
+++ b/test/env/hashtable.c
@@ -0,0 +1,125 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * (C) Copyright 2019
+ * Roman Kapl, SYSGO, r...@sysgo.com
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define SIZE 32
+#define ITERATIONS 1
+
+static int htab_fill(struct unit_test_state *uts,
+struct hsearch_data *htab, size_t size)
+{
+   size_t i;
+   ENTRY item;
+   ENTRY *ritem;
+   char key[20];
+
+   for (i = 0; i < size; i++) {
+   sprintf(key, "%d", (int)i);
+   item.callback = NULL;
+   item.data = key;
+   item.flags = 0;
+   item.key = key;
+   ut_asserteq(1, hsearch_r(item, ENTER, , htab, 0));
+   }
+
+   return 0;
+}
+
+static int htab_check_fill(struct unit_test_state *uts,
+  struct hsearch_data *htab, size_t size)
+{
+   size_t i;
+   ENTRY item;
+   ENTRY *ritem;
+   char key[20];
+
+   for (i = 0; i < size; i++) {
+   sprintf(key, "%d", (int)i);
+   item.callback = NULL;
+   item.flags = 0;
+   item.data = key;
+   item.key = key;
+   hsearch_r(item, FIND, , htab, 0);
+   ut_assert(ritem);
+   ut_asserteq_str(key, ritem->key);
+   ut_asserteq_str(key, ritem->data);
+   }
+
+   return 0;
+}
+
+static int htab_create_delete(struct unit_test_state *uts,
+ struct hsearch_data *htab, size_t iterations)
+{
+   size_t i;
+   ENTRY item;
+   ENTRY *ritem;
+   char key[20];
+
+   for (i = 0; i < iterations; i++) {
+   sprintf(key, "cd-%d", (int)i);
+   item.callback = NULL;
+   item.flags = 0;
+   item.data = key;
+   i