[PATCH v4 0/7] efi_loader: secure boot: support intermediate certificates in signature

2020-07-17 Thread AKASHI Takahiro
Summary
===
under the current implementation of secure boot merged in v2020.07,
UEFI subsystem verifies a signature using certificates that are coming
from signature dtabase, i.e. "db."

In real world, an image is signed by a signer, but its certificate
can also be signed by another CA and, if it is not self-signed, the latter
will be signed by yet another CA and so on. This is called a certificate
chain and any certificates in the middle of chain is called "intermediate"
certificates.

With this patch set applied on top of the current implementation,
UEFI subsystem will get capable of verifying intermediate certificates
being contained in a signature and authenticating an image in a chain
of trusted certificates.

Please note that we don't support RFC6131, or timestamp protocol, and so
if any certificate in the chain is found in the revocation list, i.e. dbx,
the image will unconditionally be disqualified from being loaded or run.

Patch structure
===
Patch#1-#5: preparatory patches
Patch#6: main part
Patch#7: pytest

Prerequisite

All the required patches have been merged.
You can fetch the whole workable repository from here[1].

One patch[2] to sbsigntools must also be applied so that we wil be able
to sign an image with intermediate certificates. It is required here for
testing.

Test

- The added new pytest (test_signed_intca.py) passed locally.
- Travis CI passed, except the new pytest added here due to a new
  feature in sbsigntools as mentioned above.
  (the latest vesion is still running though.)

Misc

- checkpatch.pl makes several warnings against pkcs7_verify.c, but
  we will ignore them as it is a file imported from linux code.

[1] https://git.linaro.org/people/takahiro.akashi/u-boot.git efi/secboot
[2] https://groups.io/g/sbsigntools/message/23

v4 (July 17, 2020)
* rebased to Heinrich's efi-2020-10-rc4
* remove a already-merged patch
* (no functional change)
* modify conftest.py to align it with recent changes Heinrich made
  (patch#7)

v3 (Jul 10, 2020)
* rebased to Heinrich's (current) efi-2020-10-rc1 along with
  my follow-up patches
* add sanity checks in public_key_verify_signature() (Patch#2)
* smplify include headers in pkcs7_verify.c (Patch#4)
* fix timestamp issues in Test Case 2 and 3 (Patch#8)

v2 (June 16, 2020)
* add function descriptions (Patch#2, #6 and #7)
* pylint and autopep8 against pytest (Patch#8)

v1 (June 9, 2020)
* initial release
* on top of v2020.07-rc4

AKASHI Takahiro (7):
  lib: crypto: add public_key_verify_signature()
  lib: crypto: enable x509_check_for_self_signed()
  lib: crypto: import pkcs7_verify.c from linux
  lib: crypto: add pkcs7_digest()
  lib: crypto: export and enhance pkcs7_verify_one()
  efi_loader: signature: rework for intermediate certificates support
  test/py: efi_secboot: add test for intermediate certificates

 include/crypto/pkcs7.h|   9 +-
 include/crypto/public_key.h   |   2 +-
 include/efi_loader.h  |   8 +-
 lib/crypto/Kconfig|   3 +
 lib/crypto/Makefile   |   1 +
 lib/crypto/pkcs7_verify.c | 654 ++
 lib/crypto/public_key.c   |  70 +-
 lib/crypto/x509_cert_parser.c |   2 -
 lib/crypto/x509_public_key.c  |  33 +-
 lib/efi_loader/Kconfig|   1 +
 lib/efi_loader/efi_image_loader.c |   2 +-
 lib/efi_loader/efi_signature.c| 385 +--
 lib/efi_loader/efi_variable.c |   5 +-
 test/py/tests/test_efi_secboot/conftest.py| 134 +++-
 test/py/tests/test_efi_secboot/defs.py|   8 +-
 test/py/tests/test_efi_secboot/openssl.cnf|  48 ++
 .../test_efi_secboot/test_signed_intca.py | 135 
 17 files changed, 1266 insertions(+), 234 deletions(-)
 create mode 100644 lib/crypto/pkcs7_verify.c
 create mode 100644 test/py/tests/test_efi_secboot/openssl.cnf
 create mode 100644 test/py/tests/test_efi_secboot/test_signed_intca.py

-- 
2.27.0



[PATCH v4 1/7] lib: crypto: add public_key_verify_signature()

2020-07-17 Thread AKASHI Takahiro
This function will be called from x509_check_for_self_signed() and
pkcs7_verify_one(), which will be imported from linux in a later patch.

While it does exist in linux code and has a similar functionality of
rsa_verify(), it calls further linux-specific interfaces inside.
That could lead to more files being imported from linux.

So simply re-implement it here instead of re-using the code.

Signed-off-by: AKASHI Takahiro 
---
 include/crypto/public_key.h |  2 +-
 lib/crypto/public_key.c | 70 -
 2 files changed, 70 insertions(+), 2 deletions(-)

diff --git a/include/crypto/public_key.h b/include/crypto/public_key.h
index 436a1ee1ee64..3ba90fcc3483 100644
--- a/include/crypto/public_key.h
+++ b/include/crypto/public_key.h
@@ -82,9 +82,9 @@ extern int decrypt_blob(struct kernel_pkey_params *, const 
void *, void *);
 extern int create_signature(struct kernel_pkey_params *, const void *, void *);
 extern int verify_signature(const struct key *,
const struct public_key_signature *);
+#endif /* __UBOOT__ */
 
 int public_key_verify_signature(const struct public_key *pkey,
const struct public_key_signature *sig);
-#endif /* !__UBOOT__ */
 
 #endif /* _LINUX_PUBLIC_KEY_H */
diff --git a/lib/crypto/public_key.c b/lib/crypto/public_key.c
index e12ebbb3d0c5..71a0e0356beb 100644
--- a/lib/crypto/public_key.c
+++ b/lib/crypto/public_key.c
@@ -25,7 +25,10 @@
 #include 
 #endif
 #include 
-#ifndef __UBOOT__
+#ifdef __UBOOT__
+#include 
+#include 
+#else
 #include 
 #endif
 
@@ -80,6 +83,71 @@ void public_key_signature_free(struct public_key_signature 
*sig)
 }
 EXPORT_SYMBOL_GPL(public_key_signature_free);
 
+/**
+ * public_key_verify_signature - Verify a signature using a public key.
+ *
+ * @pkey:  Public key
+ * @sig:   Signature
+ *
+ * Verify a signature, @sig, using a RSA public key, @pkey.
+ *
+ * Return: 0 - verified, non-zero error code - otherwise
+ */
+int public_key_verify_signature(const struct public_key *pkey,
+   const struct public_key_signature *sig)
+{
+   struct image_sign_info info;
+   struct image_region region;
+   int ret;
+
+   pr_devel("==>%s()\n", __func__);
+
+   if (!pkey || !sig)
+   return -EINVAL;
+
+   if (pkey->key_is_private)
+   return -EINVAL;
+
+   memset(&info, '\0', sizeof(info));
+   info.padding = image_get_padding_algo("pkcs-1.5");
+   /*
+* Note: image_get_[checksum|crypto]_algo takes a string
+* argument like ","
+* TODO: support other hash algorithms
+*/
+   if (strcmp(sig->pkey_algo, "rsa") || (sig->s_size * 8) != 2048) {
+   pr_warn("Encryption is not RSA2048: %s%d\n",
+   sig->pkey_algo, sig->s_size * 8);
+   return -ENOPKG;
+   }
+   if (!strcmp(sig->hash_algo, "sha1")) {
+   info.checksum = image_get_checksum_algo("sha1,rsa2048");
+   info.name = "sha1,rsa2048";
+   } else if (!strcmp(sig->hash_algo, "sha256")) {
+   info.checksum = image_get_checksum_algo("sha256,rsa2048");
+   info.name = "sha256,rsa2048";
+   } else {
+   pr_warn("unknown msg digest algo: %s\n", sig->hash_algo);
+   return -ENOPKG;
+   }
+   info.crypto = image_get_crypto_algo(info.name);
+   if (unlikely(IS_ERR(info.checksum) || IS_ERR(info.crypto)))
+   return -ENOPKG;
+
+   info.key = pkey->key;
+   info.keylen = pkey->keylen;
+
+   region.data = sig->digest;
+   region.size = sig->digest_size;
+
+   if (rsa_verify_with_pkey(&info, sig->digest, sig->s, sig->s_size))
+   ret = -EKEYREJECTED;
+   else
+   ret = 0;
+
+   pr_devel("<==%s() = %d\n", __func__, ret);
+   return ret;
+}
 #else
 /*
  * Destroy a public key algorithm key.
-- 
2.27.0



[PATCH v4 4/7] lib: crypto: add pkcs7_digest()

2020-07-17 Thread AKASHI Takahiro
This function was nullified when the file, pkcs7_verify.c, was imported
because it calls further linux-specific interfaces inside, hence that
could lead to more files being imported from linux.

We need this function in pkcs7_verify_one() and so simply re-implement it
here instead of re-using the code.

Signed-off-by: AKASHI Takahiro 
---
 lib/crypto/pkcs7_verify.c | 92 +--
 1 file changed, 89 insertions(+), 3 deletions(-)

diff --git a/lib/crypto/pkcs7_verify.c b/lib/crypto/pkcs7_verify.c
index a893fa3b586b..a32e841cb22b 100644
--- a/lib/crypto/pkcs7_verify.c
+++ b/lib/crypto/pkcs7_verify.c
@@ -7,10 +7,12 @@
 
 #define pr_fmt(fmt) "PKCS7: "fmt
 #ifdef __UBOOT__
+#include 
 #include 
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #else
@@ -26,15 +28,99 @@
 #endif
 
 /*
- * Digest the relevant parts of the PKCS#7 data
+ * pkcs7_digest - Digest the relevant parts of the PKCS#7 data
+ * @pkcs7: PKCS7 Signed Data
+ * @sinfo: PKCS7 Signed Info
+ *
+ * Digest the relevant parts of the PKCS#7 data, @pkcs7, using signature
+ * information in @sinfo. But if there are authentication attributes,
+ * i.e. signed image case, the digest must be calculated against
+ * the authentication attributes.
+ *
+ * Return: 0 - on success, non-zero error code - otherwise
  */
 #ifdef __UBOOT__
 static int pkcs7_digest(struct pkcs7_message *pkcs7,
struct pkcs7_signed_info *sinfo)
 {
-   return 0;
+   struct public_key_signature *sig = sinfo->sig;
+   struct image_region regions[2];
+   int ret = 0;
+
+   /* The digest was calculated already. */
+   if (sig->digest)
+   return 0;
+
+   if (!sinfo->sig->hash_algo)
+   return -ENOPKG;
+   if (!strcmp(sinfo->sig->hash_algo, "sha256"))
+   sig->digest_size = SHA256_SUM_LEN;
+   else if (!strcmp(sinfo->sig->hash_algo, "sha1"))
+   sig->digest_size = SHA1_SUM_LEN;
+   else
+   return -ENOPKG;
+
+   sig->digest = calloc(1, sig->digest_size);
+   if (!sig->digest) {
+   pr_warn("Sig %u: Out of memory\n", sinfo->index);
+   return -ENOMEM;
+   }
+
+   regions[0].data = pkcs7->data;
+   regions[0].size = pkcs7->data_len;
+
+   /* Digest the message [RFC2315 9.3] */
+   hash_calculate(sinfo->sig->hash_algo, regions, 1, sig->digest);
+
+   /* However, if there are authenticated attributes, there must be a
+* message digest attribute amongst them which corresponds to the
+* digest we just calculated.
+*/
+   if (sinfo->authattrs) {
+   u8 tag;
+
+   if (!sinfo->msgdigest) {
+   pr_warn("Sig %u: No messageDigest\n", sinfo->index);
+   ret = -EKEYREJECTED;
+   goto error;
+   }
+
+   if (sinfo->msgdigest_len != sig->digest_size) {
+   pr_debug("Sig %u: Invalid digest size (%u)\n",
+sinfo->index, sinfo->msgdigest_len);
+   ret = -EBADMSG;
+   goto error;
+   }
+
+   if (memcmp(sig->digest, sinfo->msgdigest,
+  sinfo->msgdigest_len) != 0) {
+   pr_debug("Sig %u: Message digest doesn't match\n",
+sinfo->index);
+   ret = -EKEYREJECTED;
+   goto error;
+   }
+
+   /* We then calculate anew, using the authenticated attributes
+* as the contents of the digest instead.  Note that we need to
+* convert the attributes from a CONT.0 into a SET before we
+* hash it.
+*/
+   memset(sig->digest, 0, sig->digest_size);
+
+   tag = 0x31;
+   regions[0].data = &tag;
+   regions[0].size = 1;
+   regions[1].data = sinfo->authattrs;
+   regions[1].size = sinfo->authattrs_len;
+
+   hash_calculate(sinfo->sig->hash_algo, regions, 2, sig->digest);
+
+   ret = 0;
+   }
+error:
+   return ret;
 }
-#else
+#else /* !__UBOOT__ */
 static int pkcs7_digest(struct pkcs7_message *pkcs7,
struct pkcs7_signed_info *sinfo)
 {
-- 
2.27.0



[PATCH v4 2/7] lib: crypto: enable x509_check_for_self_signed()

2020-07-17 Thread AKASHI Takahiro
When the file, x509_public_key.c, was imported from linux code in
commit b4adf627d5b7 ("lib: crypto: add x509 parser"),
x509_check_for_self_signed() was commented out for simplicity.

Now it need be enabled in order to make pkcs7_verify_one(), which will be
imported in a later patch, functional.

Signed-off-by: AKASHI Takahiro 
---
 lib/crypto/x509_cert_parser.c |  2 --
 lib/crypto/x509_public_key.c  | 33 +
 2 files changed, 25 insertions(+), 10 deletions(-)

diff --git a/lib/crypto/x509_cert_parser.c b/lib/crypto/x509_cert_parser.c
index 5f984b9dfdae..eb24349460c2 100644
--- a/lib/crypto/x509_cert_parser.c
+++ b/lib/crypto/x509_cert_parser.c
@@ -142,12 +142,10 @@ struct x509_certificate *x509_cert_parse(const void 
*data, size_t datalen)
}
cert->id = kid;
 
-#ifndef __UBOOT__
/* Detect self-signed certificates */
ret = x509_check_for_self_signed(cert);
if (ret < 0)
goto error_decode;
-#endif
 
kfree(ctx);
return cert;
diff --git a/lib/crypto/x509_public_key.c b/lib/crypto/x509_public_key.c
index 571af9a0adf9..91810a864049 100644
--- a/lib/crypto/x509_public_key.c
+++ b/lib/crypto/x509_public_key.c
@@ -8,6 +8,7 @@
 #define pr_fmt(fmt) "X.509: "fmt
 #ifdef __UBOOT__
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -18,6 +19,7 @@
 #include 
 #ifdef __UBOOT__
 #include 
+#include 
 #else
 #include 
 #include 
@@ -35,7 +37,9 @@
 int x509_get_sig_params(struct x509_certificate *cert)
 {
struct public_key_signature *sig = cert->sig;
-#ifndef __UBOOT__
+#ifdef __UBOOT__
+   struct image_region region;
+#else
struct crypto_shash *tfm;
struct shash_desc *desc;
size_t desc_size;
@@ -63,12 +67,25 @@ int x509_get_sig_params(struct x509_certificate *cert)
sig->s_size = cert->raw_sig_size;
 
 #ifdef __UBOOT__
-   /*
-* Note:
-* This part (filling sig->digest) should be implemented if
-* x509_check_for_self_signed() is enabled x509_cert_parse().
-* Currently, this check won't affect UEFI secure boot.
-*/
+   if (!sig->hash_algo)
+   return -ENOPKG;
+   if (!strcmp(sig->hash_algo, "sha256"))
+   sig->digest_size = SHA256_SUM_LEN;
+   else if (!strcmp(sig->hash_algo, "sha1"))
+   sig->digest_size = SHA1_SUM_LEN;
+   else
+   return -ENOPKG;
+
+   sig->digest = calloc(1, sig->digest_size);
+   if (!sig->digest)
+   return -ENOMEM;
+
+   region.data = cert->tbs;
+   region.size = cert->tbs_size;
+   hash_calculate(sig->hash_algo, ®ion, 1, sig->digest);
+
+   /* TODO: is_hash_blacklisted()? */
+
ret = 0;
 #else
/* Allocate the hashing algorithm we're going to need and find out how
@@ -118,7 +135,6 @@ error:
return ret;
 }
 
-#ifndef __UBOOT__
 /*
  * Check for self-signedness in an X.509 cert and if found, check the signature
  * immediately if we can.
@@ -175,6 +191,7 @@ not_self_signed:
return 0;
 }
 
+#ifndef __UBOOT__
 /*
  * Attempt to parse a data blob for a key as an X509 certificate.
  */
-- 
2.27.0



[PATCH v4 6/7] efi_loader: signature: rework for intermediate certificates support

2020-07-17 Thread AKASHI Takahiro
In this commit, efi_signature_verify(with_sigdb) will be re-implemented
using pcks7_verify_one() in order to support certificates chain, where
the signer's certificate will be signed by an intermediate CA (certificate
authority) and the latter's certificate will also be signed by another CA
and so on.

What we need to do here is to search for certificates in a signature,
build up a chain of certificates and verify one by one. pkcs7_verify_one()
handles most of these steps except the last one.

pkcs7_verify_one() returns, if succeeded, the last certificate to verify,
which can be either a self-signed one or one that should be signed by one
of certificates in "db". Re-worked efi_signature_verify() will take care
of this step.

Signed-off-by: AKASHI Takahiro 
---
 include/efi_loader.h  |   8 +-
 lib/efi_loader/Kconfig|   1 +
 lib/efi_loader/efi_image_loader.c |   2 +-
 lib/efi_loader/efi_signature.c| 385 ++
 lib/efi_loader/efi_variable.c |   5 +-
 5 files changed, 188 insertions(+), 213 deletions(-)

diff --git a/include/efi_loader.h b/include/efi_loader.h
index 98944640bee7..df8dc377257c 100644
--- a/include/efi_loader.h
+++ b/include/efi_loader.h
@@ -773,10 +773,10 @@ bool efi_signature_lookup_digest(struct efi_image_regions 
*regs,
 bool efi_signature_verify_one(struct efi_image_regions *regs,
  struct pkcs7_message *msg,
  struct efi_signature_store *db);
-bool efi_signature_verify_with_sigdb(struct efi_image_regions *regs,
-struct pkcs7_message *msg,
-struct efi_signature_store *db,
-struct efi_signature_store *dbx);
+bool efi_signature_verify(struct efi_image_regions *regs,
+ struct pkcs7_message *msg,
+ struct efi_signature_store *db,
+ struct efi_signature_store *dbx);
 bool efi_signature_check_signers(struct pkcs7_message *msg,
 struct efi_signature_store *dbx);
 
diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig
index 6017ffe9a600..bad1a29ba804 100644
--- a/lib/efi_loader/Kconfig
+++ b/lib/efi_loader/Kconfig
@@ -205,6 +205,7 @@ config EFI_SECURE_BOOT
select ASYMMETRIC_PUBLIC_KEY_SUBTYPE
select X509_CERTIFICATE_PARSER
select PKCS7_MESSAGE_PARSER
+   select PKCS7_VERIFY
default n
help
  Select this option to enable EFI secure boot support.
diff --git a/lib/efi_loader/efi_image_loader.c 
b/lib/efi_loader/efi_image_loader.c
index d81ae8c93a52..d930811141af 100644
--- a/lib/efi_loader/efi_image_loader.c
+++ b/lib/efi_loader/efi_image_loader.c
@@ -642,7 +642,7 @@ static bool efi_image_authenticate(void *efi, size_t 
efi_size)
}
 
/* try white-list */
-   if (efi_signature_verify_with_sigdb(regs, msg, db, dbx))
+   if (efi_signature_verify(regs, msg, db, dbx))
continue;
 
debug("Signature was not verified by \"db\"\n");
diff --git a/lib/efi_loader/efi_signature.c b/lib/efi_loader/efi_signature.c
index 8413d83e343b..ac28c80c1293 100644
--- a/lib/efi_loader/efi_signature.c
+++ b/lib/efi_loader/efi_signature.c
@@ -10,7 +10,9 @@
 #include 
 #include 
 #include 
+#include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -61,143 +63,6 @@ static bool efi_hash_regions(struct image_region *regs, int 
count,
return true;
 }
 
-/**
- * efi_hash_msg_content - calculate a hash value of contentInfo
- * @msg:   Signature
- * @hash:  Pointer to a pointer to buffer holding a hash value
- * @size:  Size of buffer to be returned
- *
- * Calculate a sha256 value of contentInfo in @msg and return a value in @hash.
- *
- * Return: true on success, false on error
- */
-static bool efi_hash_msg_content(struct pkcs7_message *msg, void **hash,
-size_t *size)
-{
-   struct image_region regtmp;
-
-   regtmp.data = msg->data;
-   regtmp.size = msg->data_len;
-
-   return efi_hash_regions(®tmp, 1, hash, size);
-}
-
-/**
- * efi_signature_verify - verify a signature with a certificate
- * @regs:  List of regions to be authenticated
- * @signed_info:   Pointer to PKCS7's signed_info
- * @cert:  x509 certificate
- *
- * Signature pointed to by @signed_info against image pointed to by @regs
- * is verified by a certificate pointed to by @cert.
- * @signed_info holds a signature, including a message digest which is to be
- * compared with a hash value calculated from @regs.
- *
- * Return: true if signature is verified, false if not
- */
-static bool efi_signature_verify(struct efi_image_regions *regs,
-struct pkcs7_message *msg,
-struct pkcs7_signed_info *ps_info,
-  

[PATCH v4 3/7] lib: crypto: import pkcs7_verify.c from linux

2020-07-17 Thread AKASHI Takahiro
The file, pkcs7_verify.c, will now be imported from linux code
(crypto/asymmetric_keys/pkcs7_verify.c)
and modified to fit into U-Boot environment.

In particular, pkcs7_verify_one() function will be used in a later patch
to rework signature verification logic aiming to support intermediate
certificates in "chain of trust."

Signed-off-by: AKASHI Takahiro 
---
 lib/crypto/Kconfig|   3 +
 lib/crypto/Makefile   |   1 +
 lib/crypto/pkcs7_verify.c | 521 ++
 3 files changed, 525 insertions(+)
 create mode 100644 lib/crypto/pkcs7_verify.c

diff --git a/lib/crypto/Kconfig b/lib/crypto/Kconfig
index 2b221b915aa6..6369bafac07b 100644
--- a/lib/crypto/Kconfig
+++ b/lib/crypto/Kconfig
@@ -49,4 +49,7 @@ config PKCS7_MESSAGE_PARSER
  This option provides support for parsing PKCS#7 format messages for
  signature data and provides the ability to verify the signature.
 
+config PKCS7_VERIFY
+   bool
+
 endif # ASYMMETRIC_KEY_TYPE
diff --git a/lib/crypto/Makefile b/lib/crypto/Makefile
index 8267fee0a7b8..f3a414525d2a 100644
--- a/lib/crypto/Makefile
+++ b/lib/crypto/Makefile
@@ -44,6 +44,7 @@ obj-$(CONFIG_PKCS7_MESSAGE_PARSER) += pkcs7_message.o
 pkcs7_message-y := \
pkcs7.asn1.o \
pkcs7_parser.o
+obj-$(CONFIG_PKCS7_VERIFY) += pkcs7_verify.o
 
 $(obj)/pkcs7_parser.o: $(obj)/pkcs7.asn1.h
 $(obj)/pkcs7.asn1.o: $(obj)/pkcs7.asn1.c $(obj)/pkcs7.asn1.h
diff --git a/lib/crypto/pkcs7_verify.c b/lib/crypto/pkcs7_verify.c
new file mode 100644
index ..a893fa3b586b
--- /dev/null
+++ b/lib/crypto/pkcs7_verify.c
@@ -0,0 +1,521 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/* Verify the signature on a PKCS#7 message.
+ *
+ * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowe...@redhat.com)
+ */
+
+#define pr_fmt(fmt) "PKCS7: "fmt
+#ifdef __UBOOT__
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#else
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "pkcs7_parser.h"
+#endif
+
+/*
+ * Digest the relevant parts of the PKCS#7 data
+ */
+#ifdef __UBOOT__
+static int pkcs7_digest(struct pkcs7_message *pkcs7,
+   struct pkcs7_signed_info *sinfo)
+{
+   return 0;
+}
+#else
+static int pkcs7_digest(struct pkcs7_message *pkcs7,
+   struct pkcs7_signed_info *sinfo)
+{
+   struct public_key_signature *sig = sinfo->sig;
+   struct crypto_shash *tfm;
+   struct shash_desc *desc;
+   size_t desc_size;
+   int ret;
+
+   kenter(",%u,%s", sinfo->index, sinfo->sig->hash_algo);
+
+   /* The digest was calculated already. */
+   if (sig->digest)
+   return 0;
+
+   if (!sinfo->sig->hash_algo)
+   return -ENOPKG;
+
+   /* Allocate the hashing algorithm we're going to need and find out how
+* big the hash operational data will be.
+*/
+   tfm = crypto_alloc_shash(sinfo->sig->hash_algo, 0, 0);
+   if (IS_ERR(tfm))
+   return (PTR_ERR(tfm) == -ENOENT) ? -ENOPKG : PTR_ERR(tfm);
+
+   desc_size = crypto_shash_descsize(tfm) + sizeof(*desc);
+   sig->digest_size = crypto_shash_digestsize(tfm);
+
+   ret = -ENOMEM;
+   sig->digest = kmalloc(sig->digest_size, GFP_KERNEL);
+   if (!sig->digest)
+   goto error_no_desc;
+
+   desc = kzalloc(desc_size, GFP_KERNEL);
+   if (!desc)
+   goto error_no_desc;
+
+   desc->tfm   = tfm;
+
+   /* Digest the message [RFC2315 9.3] */
+   ret = crypto_shash_digest(desc, pkcs7->data, pkcs7->data_len,
+ sig->digest);
+   if (ret < 0)
+   goto error;
+   pr_devel("MsgDigest = [%*ph]\n", 8, sig->digest);
+
+   /* However, if there are authenticated attributes, there must be a
+* message digest attribute amongst them which corresponds to the
+* digest we just calculated.
+*/
+   if (sinfo->authattrs) {
+   u8 tag;
+
+   if (!sinfo->msgdigest) {
+   pr_warn("Sig %u: No messageDigest\n", sinfo->index);
+   ret = -EKEYREJECTED;
+   goto error;
+   }
+
+   if (sinfo->msgdigest_len != sig->digest_size) {
+   pr_debug("Sig %u: Invalid digest size (%u)\n",
+sinfo->index, sinfo->msgdigest_len);
+   ret = -EBADMSG;
+   goto error;
+   }
+
+   if (memcmp(sig->digest, sinfo->msgdigest,
+  sinfo->msgdigest_len) != 0) {
+   pr_debug("Sig %u: Message digest doesn't match\n",
+sinfo->index);
+   ret = -EKEYREJECTED;
+   goto error;
+   }
+
+   /* We then calculate anew, using the authenticated attributes

[PATCH v4 5/7] lib: crypto: export and enhance pkcs7_verify_one()

2020-07-17 Thread AKASHI Takahiro
The function, pkcs7_verify_one(), will be utilized to rework signature
verification logic aiming to support intermediate certificates in
"chain of trust."

To do that, its function interface is expanded, adding an extra argument
which is expected to return the last certificate in trusted chain.
Then, this last one must further be verified with signature database, db
and/or dbx.

Signed-off-by: AKASHI Takahiro 
---
 include/crypto/pkcs7.h|  9 +-
 lib/crypto/pkcs7_verify.c | 61 ++-
 2 files changed, 62 insertions(+), 8 deletions(-)

diff --git a/include/crypto/pkcs7.h b/include/crypto/pkcs7.h
index 8f5c8a7ee3b9..ca35df29f6fb 100644
--- a/include/crypto/pkcs7.h
+++ b/include/crypto/pkcs7.h
@@ -27,7 +27,14 @@ extern int pkcs7_get_content_data(const struct pkcs7_message 
*pkcs7,
  const void **_data, size_t *_datalen,
  size_t *_headerlen);
 
-#ifndef __UBOOT__
+#ifdef __UBOOT__
+struct pkcs7_signed_info;
+struct x509_certificate;
+
+int pkcs7_verify_one(struct pkcs7_message *pkcs7,
+struct pkcs7_signed_info *sinfo,
+struct x509_certificate **signer);
+#else
 /*
  * pkcs7_trust.c
  */
diff --git a/lib/crypto/pkcs7_verify.c b/lib/crypto/pkcs7_verify.c
index a32e841cb22b..6a51243fcf43 100644
--- a/lib/crypto/pkcs7_verify.c
+++ b/lib/crypto/pkcs7_verify.c
@@ -298,10 +298,27 @@ static int pkcs7_find_key(struct pkcs7_message *pkcs7,
 }
 
 /*
- * Verify the internal certificate chain as best we can.
+ * pkcs7_verify_sig_chain - Verify the internal certificate chain as best
+ *  as we can.
+ * @pkcs7: PKCS7 Signed Data
+ * @sinfo: PKCS7 Signed Info
+ * @signer:Singer's certificate
+ *
+ * Build up and verify the internal certificate chain against a signature
+ * in @sinfo, using certificates contained in @pkcs7 as best as we can.
+ * If the chain reaches the end, the last certificate will be returned
+ * in @signer.
+ *
+ * Return: 0 - on success, non-zero error code - otherwise
  */
+#ifdef __UBOOT__
+static int pkcs7_verify_sig_chain(struct pkcs7_message *pkcs7,
+ struct pkcs7_signed_info *sinfo,
+ struct x509_certificate **signer)
+#else
 static int pkcs7_verify_sig_chain(struct pkcs7_message *pkcs7,
  struct pkcs7_signed_info *sinfo)
+#endif
 {
struct public_key_signature *sig;
struct x509_certificate *x509 = sinfo->signer, *p;
@@ -310,6 +327,8 @@ static int pkcs7_verify_sig_chain(struct pkcs7_message 
*pkcs7,
 
kenter("");
 
+   *signer = NULL;
+
for (p = pkcs7->certs; p; p = p->next)
p->seen = false;
 
@@ -327,6 +346,9 @@ static int pkcs7_verify_sig_chain(struct pkcs7_message 
*pkcs7,
for (p = sinfo->signer; p != x509; p = p->signer)
p->blacklisted = true;
pr_debug("- blacklisted\n");
+#ifdef __UBOOT__
+   *signer = x509;
+#endif
return 0;
}
 
@@ -352,6 +374,9 @@ static int pkcs7_verify_sig_chain(struct pkcs7_message 
*pkcs7,
goto unsupported_crypto_in_x509;
x509->signer = x509;
pr_debug("- self-signed\n");
+#ifdef __UBOOT__
+   *signer = x509;
+#endif
return 0;
}
 
@@ -382,6 +407,9 @@ static int pkcs7_verify_sig_chain(struct pkcs7_message 
*pkcs7,
 
/* We didn't find the root of this chain */
pr_debug("- top\n");
+#ifdef __UBOOT__
+   *signer = x509;
+#endif
return 0;
 
found_issuer_check_skid:
@@ -399,6 +427,9 @@ static int pkcs7_verify_sig_chain(struct pkcs7_message 
*pkcs7,
if (p->seen) {
pr_warn("Sig %u: X.509 chain contains loop\n",
sinfo->index);
+#ifdef __UBOOT__
+   *signer = p;
+#endif
return 0;
}
ret = public_key_verify_signature(p->pub, x509->sig);
@@ -407,6 +438,9 @@ static int pkcs7_verify_sig_chain(struct pkcs7_message 
*pkcs7,
x509->signer = p;
if (x509 == p) {
pr_debug("- self-signed\n");
+#ifdef __UBOOT__
+   *signer = p;
+#endif
return 0;
}
x509 = p;
@@ -426,13 +460,26 @@ unsupported_crypto_in_x509:
 }
 
 /*
- * Verify one signed information block from a PKCS#7 message.
+ * pkcs7_verify_one - Verify one signed information block from a PKCS#7
+ *message.
+ * @pkcs7: PKCS7 Signed Data
+ * @sinfo: PKCS7 Signed Info
+ * @signer:Signer's certificate
+ *
+ * Verify one signature in @sinfo and follow the certificate chain.

[PATCH v4 7/7] test/py: efi_secboot: add test for intermediate certificates

2020-07-17 Thread AKASHI Takahiro
In this test case, an image may have a signature with additional
intermediate certificates. A chain of trust will be followed and all
the certificates in the middle of chain must be verified before loading.

Signed-off-by: AKASHI Takahiro 
---
 test/py/tests/test_efi_secboot/conftest.py| 134 -
 test/py/tests/test_efi_secboot/defs.py|   8 +-
 test/py/tests/test_efi_secboot/openssl.cnf|  48 +++
 .../test_efi_secboot/test_signed_intca.py | 135 ++
 4 files changed, 317 insertions(+), 8 deletions(-)
 create mode 100644 test/py/tests/test_efi_secboot/openssl.cnf
 create mode 100644 test/py/tests/test_efi_secboot/test_signed_intca.py

diff --git a/test/py/tests/test_efi_secboot/conftest.py 
b/test/py/tests/test_efi_secboot/conftest.py
index c6709700a876..20d0cbf3ab01 100644
--- a/test/py/tests/test_efi_secboot/conftest.py
+++ b/test/py/tests/test_efi_secboot/conftest.py
@@ -37,7 +37,7 @@ def efi_boot_env(request, u_boot_config):
 global HELLO_PATH
 
 image_path = u_boot_config.persistent_data_dir
-image_path = image_path + '/' + EFI_SECBOOT_IMAGE_NAME
+image_path = image_path + '/' + EFI_SECBOOT_IMAGE_NAME + '.img'
 
 if HELLO_PATH == '':
 HELLO_PATH = u_boot_config.build_dir + '/lib/efi_loader/helloworld.efi'
@@ -87,21 +87,21 @@ def efi_boot_env(request, u_boot_config):
 # db1-update
 check_call('cd %s; %ssign-efi-sig-list -t "2020-04-06" -a -c KEK.crt 
-k KEK.key db db1.esl db1-update.auth'
% (mnt_point, EFITOOLS_PATH), shell=True)
-## dbx (TEST_dbx certificate)
+# dbx (TEST_dbx certificate)
 check_call('cd %s; openssl req -x509 -sha256 -newkey rsa:2048 -subj 
/CN=TEST_dbx/ -keyout dbx.key -out dbx.crt -nodes -days 365'
% mnt_point, shell=True)
 check_call('cd %s; %scert-to-efi-sig-list -g %s dbx.crt dbx.esl; 
%ssign-efi-sig-list -t "2020-04-05" -c KEK.crt -k KEK.key dbx dbx.esl dbx.auth'
% (mnt_point, EFITOOLS_PATH, GUID, EFITOOLS_PATH),
shell=True)
-## dbx_hash (digest of TEST_db certificate)
+# dbx_hash (digest of TEST_db certificate)
 check_call('cd %s; %scert-to-efi-hash-list -g %s -t 0 -s 256 db.crt 
dbx_hash.crl; %ssign-efi-sig-list -t "2020-04-05" -c KEK.crt -k KEK.key dbx 
dbx_hash.crl dbx_hash.auth'
% (mnt_point, EFITOOLS_PATH, GUID, EFITOOLS_PATH),
shell=True)
-## dbx_hash1 (digest of TEST_db1 certificate)
+# dbx_hash1 (digest of TEST_db1 certificate)
 check_call('cd %s; %scert-to-efi-hash-list -g %s -t 0 -s 256 db1.crt 
dbx_hash1.crl; %ssign-efi-sig-list -t "2020-04-05" -c KEK.crt -k KEK.key dbx 
dbx_hash1.crl dbx_hash1.auth'
% (mnt_point, EFITOOLS_PATH, GUID, EFITOOLS_PATH),
shell=True)
-## dbx_db (with TEST_db certificate)
+# dbx_db (with TEST_db certificate)
 check_call('cd %s; %ssign-efi-sig-list -t "2020-04-05" -c KEK.crt -k 
KEK.key dbx db.esl dbx_db.auth'
% (mnt_point, EFITOOLS_PATH),
shell=True)
@@ -112,10 +112,10 @@ def efi_boot_env(request, u_boot_config):
 # Sign image
 check_call('cd %s; sbsign --key db.key --cert db.crt helloworld.efi'
% mnt_point, shell=True)
-## Sign already-signed image with another key
+# Sign already-signed image with another key
 check_call('cd %s; sbsign --key db1.key --cert db1.crt --output 
helloworld.efi.signed_2sigs helloworld.efi.signed'
% mnt_point, shell=True)
-## Digest image
+# Digest image
 check_call('cd %s; %shash-to-efi-sig-list helloworld.efi 
db_hello.hash; %ssign-efi-sig-list -t "2020-04-07" -c KEK.crt -k KEK.key db 
db_hello.hash db_hello.auth'
% (mnt_point, EFITOOLS_PATH, EFITOOLS_PATH),
shell=True)
@@ -136,3 +136,123 @@ def efi_boot_env(request, u_boot_config):
 yield image_path
 finally:
 call('rm -f %s' % image_path, shell=True)
+
+#
+# Fixture for UEFI secure boot test of intermediate certificates
+#
+
+
+@pytest.fixture(scope='session')
+def efi_boot_env_intca(request, u_boot_config):
+"""Set up a file system to be used in UEFI secure boot test
+of intermediate certificates.
+
+Args:
+request: Pytest request object.
+u_boot_config: U-boot configuration.
+
+Return:
+A path to disk image to be used for testing
+"""
+global HELLO_PATH
+
+image_path = u_boot_config.persistent_data_dir
+image_path = image_path + '/' + EFI_SECBOOT_IMAGE_NAME + '_intca.img'
+
+if HELLO_PATH == '':
+HELLO_PATH = u_boot_config.build_dir + '/lib/efi_loader/helloworld.efi'
+
+try:
+mnt_point = u_boot_config.build_dir + '/mnt_efisecure'
+check_call('rm -rf {}'.format(mnt_point), shell=True)
+check_call('mkdir -p {}'.f

Re: [PATCH v4 4/4] mips: octeon: Add minimal Octeon 3 EBB7304 EVK support

2020-07-17 Thread Stefan Roese

Hi Daniel,

On 16.07.20 20:54, Daniel Schwierzeck wrote:

This patch adds very basic minimal support for the Marvell Octeon 3
CN73xx based EBB7304 EVK. Please note that the basic Octeon port does
not support DDR3/4 initialization yet. To still use U-Boot on with this
port, the L2 cache (4MiB) is used as RAM. This way, U-Boot can boot
to the prompt on this board.

Supported devices:
- UART
- reset
- CFI parallel NOR flash

Signed-off-by: Stefan Roese 

---

Changes in v4:
- Remove CONFIG_BOARD_SIZE_LIMIT

Changes in v3:
- Remove inclusion of "common.h"
- Slightly change some copyright messages (adjust year)

Changes in v2:
- Removed CONFIG_SYS_MIPS_TIMER_FREQ

  arch/mips/dts/Makefile   |  1 +
  arch/mips/dts/mrvl,octeon-ebb7304.dts| 96 
  arch/mips/mach-octeon/Kconfig| 14 
  board/Marvell/octeon_ebb7304/Kconfig | 19 +
  board/Marvell/octeon_ebb7304/MAINTAINERS |  7 ++
  board/Marvell/octeon_ebb7304/Makefile|  8 ++
  board/Marvell/octeon_ebb7304/board.c |  9 +++
  configs/octeon_ebb7304_defconfig | 37 +
  include/configs/octeon_common.h  | 19 +
  include/configs/octeon_ebb7304.h | 20 +
  10 files changed, 230 insertions(+)
  create mode 100644 arch/mips/dts/mrvl,octeon-ebb7304.dts
  create mode 100644 board/Marvell/octeon_ebb7304/Kconfig
  create mode 100644 board/Marvell/octeon_ebb7304/MAINTAINERS
  create mode 100644 board/Marvell/octeon_ebb7304/Makefile
  create mode 100644 board/Marvell/octeon_ebb7304/board.c
  create mode 100644 configs/octeon_ebb7304_defconfig
  create mode 100644 include/configs/octeon_common.h
  create mode 100644 include/configs/octeon_ebb7304.h



both Octeon base support series are applied to u-boot-mips/next. I
reordered and squashed some patches to get a cleaner history. Also
configs/octeon_ebb7304_defconfig needed a little refresh. The GPIO
driver needs another update and the SPI driver some more review and
ack. For the DDR4 init stuff I couldn't spare enough time for review
yet.


Could you check if everything still works so that I can prepare the
pull-request? Thanks.


Thanks Daniel. I checked the "next" branch and all looks good. Running
this on the board also works without any issues. The only thing I
noticed is, that building U-Boot now produces this build warning:

= WARNING ==
This board does not use CONFIG_DM_ETH (Driver Model
for Ethernet drivers). Please update the board to use
CONFIG_DM_ETH before the v2020.07 release. Failure to
update by the deadline may result in board removal.
See doc/driver-model/migration.rst for more info.


Feel free to add (squash) this change to the defconfig to remove this
build warning:

diff --git a/configs/octeon_ebb7304_defconfig 
b/configs/octeon_ebb7304_defconfig

index d810b1e45f..204a42b9fd 100644
--- a/configs/octeon_ebb7304_defconfig
+++ b/configs/octeon_ebb7304_defconfig
@@ -29,6 +29,7 @@ CONFIG_CFI_FLASH=y
 CONFIG_SYS_FLASH_USE_BUFFER_WRITE=y
 CONFIG_FLASH_CFI_MTD=y
 CONFIG_SYS_FLASH_CFI=y
+CONFIG_DM_ETH=y
 # CONFIG_NETDEVICES is not set
 CONFIG_DEBUG_UART_SHIFT=3
 CONFIG_DEBUG_UART_ANNOUNCE=y

Or I will send a patch to change it when the patch series is merged into
mainline.

Thanks,
Stefan


[PATCH] riscv: ae350: Use fdtdec_get_addr_size_auto_noparent to parse smc reg

2020-07-17 Thread Andes
From: Rick Chen 

Use fdtdec_get_addr_size_auto_noparent to read the "reg" property
instead of fdtdec_get_addr. This will increase the compatibility
of dtb parsing.

Signed-off-by: Rick Chen 
---
 board/AndesTech/ax25-ae350/ax25-ae350.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/board/AndesTech/ax25-ae350/ax25-ae350.c 
b/board/AndesTech/ax25-ae350/ax25-ae350.c
index da5bc5b..231a0d5 100644
--- a/board/AndesTech/ax25-ae350/ax25-ae350.c
+++ b/board/AndesTech/ax25-ae350/ax25-ae350.c
@@ -71,7 +71,8 @@ int smc_init(void)
if (node < 0)
return -FDT_ERR_NOTFOUND;
 
-   addr = fdtdec_get_addr(blob, node, "reg");
+   addr = fdtdec_get_addr_size_auto_noparent(blob, node,
+   "reg", 0, NULL, false);
 
if (addr == FDT_ADDR_T_NONE)
return -EINVAL;
-- 
2.7.4



RE: [PATCH 0/9] mmc: fsl_esdhc: support eMMC HS200/HS400 modes

2020-07-17 Thread Y.b. Lu
Hi Jaehoon,

Below is the full log of the performance and function tests for eMMC HS400 
mode. Since I used date to record time, there must be some error more or less.
I tested the r/w performance with 4G data size at 175MHz bus speed. The results 
were,
Read: 273MB/s = 4096MB / 15s
Write: 74MB/s = 4096MB / 55s

According to the eMMC data sheet the HS400 max performance for sequential r/w 
are,
Read: 270MB/s
Write: 90MB/s

The performance seems to be matched and good.
BTW, the test was applied two more patches to fix stability issue. Let me send 
out v2 patch-set with them.
Thanks.

 log ==
NOTICE:  BL2: v1.5(release):LSDK-20.04
NOTICE:  BL2: Built : 05:20:45, Apr  9 2020
NOTICE:  UDIMM 18ADF2G72AZ-3G2E1
NOTICE:  DDR4 UDIMM with 2-rank 64-bit bus (x8)

NOTICE:  32 GB DDR4, 64-bit, CL=22, ECC on, 256B, CS0+CS1
NOTICE:  BL2: Booting BL31
NOTICE:  BL31: v1.5(release):LSDK-20.04
NOTICE:  BL31: Built : 11:00:17, Jul 15 2020
NOTICE:  Welcome to LX2160 BL31 Phase


U-Boot 2020.07-00703-g1b677f8 (Jul 17 2020 - 16:30:43 +0800)

SoC:  LX2160ACE Rev2.0 (0x87360020)
Clock Configuration:
   CPU0(A72):2000 MHz  CPU1(A72):2000 MHz  CPU2(A72):2000 MHz
   CPU3(A72):2000 MHz  CPU4(A72):2000 MHz  CPU5(A72):2000 MHz
   CPU6(A72):2000 MHz  CPU7(A72):2000 MHz  CPU8(A72):2000 MHz
   CPU9(A72):2000 MHz  CPU10(A72):2000 MHz  CPU11(A72):2000 MHz
   CPU12(A72):2000 MHz  CPU13(A72):2000 MHz  CPU14(A72):2000 MHz
   CPU15(A72):2000 MHz
   Bus:  700  MHz  DDR:  2900 MT/s
Reset Configuration Word (RCW):
   : 5038 24500050  
   0010:  0c01  
   0020: 02e001a0 2580  0096
   0030:    
   0040:    
   0050:    
   0060:   00027000 
   0070: 08b30010 00150020
Model: NXP Layerscape LX2160ARDB Board
Board: LX2160ACE Rev2.0-RDB, Board version: B, boot from FlexSPI DEV#1
FPGA: v7.0
SERDES1 Reference: Clock1 = 161.13MHz Clock2 = 161.13MHz
SERDES2 Reference: Clock1 = 100MHz Clock2 = 100MHz
SERDES3 Reference: Clock1 = 100MHz Clock2 = 100MHz
VID: Core voltage after adjustment is at 852 mV
DRAM:  31.9 GiB
DDR31.9 GiB (DDR4, 64-bit, CL=22, ECC on)
   DDR Controller Interleaving Mode: 256B
   DDR Chip-Select Interleaving Mode: CS0+CS1
Using SERDES1 Protocol: 19 (0x13)
Using SERDES2 Protocol: 5 (0x5)
Using SERDES3 Protocol: 2 (0x2)
PCIe0: pcie@340 disabled
PCIe1: pcie@350 disabled
PCIe2: pcie@360 Root Complex: x1 gen1
PCI: Failed autoconfig bar 18
PCIe3: pcie@370 disabled
PCIe4: pcie@380 Root Complex: no link
PCIe5: pcie@390 disabled
MMC:   FSL_SDHC: 0, FSL_SDHC: 1
Loading Environment from SPI Flash... SF: Detected mt35xu512aba with page size 
256 Bytes, erase size 128 KiB, total 64 MiB
*** Warning - bad CRC, using default environment

EEPROM: NXID v1
In:serial_pl01x
Out:   serial_pl01x
Err:   serial_pl01x
Net:   e1000: 68:05:ca:31:2c:73

Warning: e1000#0 MAC addresses don't match:
Address in ROM is   68:05:ca:31:2c:73
Address in environment is   00:04:9f:05:84:57
eth0: DPMAC3@usxgmii, eth1: DPMAC4@usxgmii, eth2: DPMAC17@rgmii-id, eth3: 
DPMAC18@rgmii-id, eth4: e1000#0
SF: Detected mt35xu512aba with page size 256 Bytes, erase size 128 KiB, total 
64 MiB
device 0 offset 0x64, size 0x8
SF: 524288 bytes @ 0x64 Read: OK
device 0 offset 0xa0, size 0x30
SF: 3145728 bytes @ 0xa0 Read: OK
device 0 offset 0xe0, size 0x10
SF: 1048576 bytes @ 0xe0 Read: OK
crc32+
fsl-mc: Booting Management Complex ... SUCCESS
fsl-mc: Management Complex booted (version: 10.20.4, boot status: 0x1)
Hit any key to stop autoboot:  0
=> mmc dev 1
switch to partitions #0, OK
mmc1(part 0) is current device
=> mmcinfo
Device: FSL_SDHC
Manufacturer ID: 13
OEM: 14e
Name: R1J59
Bus Speed: 17500
Mode: HS400 (200MHz)
Rd Block Len: 512
MMC version 5.0
High Capacity: Yes
Capacity: 116.5 GiB
Bus Width: 8-bit DDR
Erase Group Size: 512 KiB
HC WP Group Size: 32 MiB
User Capacity: 116.5 GiB WRREL
Boot Capacity: 8 MiB ENH
RPMB Capacity: 4 MiB ENH
Boot area 0 is not write protected
Boot area 1 is not write protected
=> date;mmc read 8100 0 20;mmc read 8100 0 20;mmc read 8100 
0 20;mmc read 8100 0 20;date
Date: 2020-07-17 (Friday)Time:  7:46:18

MMC read: dev # 1, block # 0, count 2097152 ... 2097152 blocks read: OK

MMC read: dev # 1, block # 0, count 2097152 ... 2097152 blocks read: OK

MMC read: dev # 1, block # 0, count 2097152 ... 2097152 blocks read: OK

MMC read: dev # 1, block # 0, count 2097152 ... 2097152 blocks read: OK
Date: 2020-07-17 (Friday)Time:  7:46:33
=> date;mmc write 8100 0 20;mmc write 8100 0 20;mmc write 
8100 0 20;mmc write 8100 0 20;date
Date: 2020-07-17 (Friday)Time:  7:47:08

MMC write: dev # 1, 

Re: [PATCH] riscv: ae350: Use fdtdec_get_addr_size_auto_noparent to parse smc reg

2020-07-17 Thread Leo Liang
On Fri, Jul 17, 2020 at 04:24:44PM +0800, Open Source Project uboot wrote:
> From: Rick Chen 
> 
> Use fdtdec_get_addr_size_auto_noparent to read the "reg" property
> instead of fdtdec_get_addr. This will increase the compatibility
> of dtb parsing.
> 
> Signed-off-by: Rick Chen 
> ---
>  board/AndesTech/ax25-ae350/ax25-ae350.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/board/AndesTech/ax25-ae350/ax25-ae350.c 
> b/board/AndesTech/ax25-ae350/ax25-ae350.c
> index da5bc5b..231a0d5 100644
> --- a/board/AndesTech/ax25-ae350/ax25-ae350.c
> +++ b/board/AndesTech/ax25-ae350/ax25-ae350.c
> @@ -71,7 +71,8 @@ int smc_init(void)
>   if (node < 0)
>   return -FDT_ERR_NOTFOUND;
>  
> - addr = fdtdec_get_addr(blob, node, "reg");
> + addr = fdtdec_get_addr_size_auto_noparent(blob, node,
> + "reg", 0, NULL, false);
>  
>   if (addr == FDT_ADDR_T_NONE)
>   return -EINVAL;
> -- 
> 2.7.4
>
Acked-by: Leo Liang 


[v2, 00/11] mmc: fsl_esdhc: support eMMC HS200/HS400 modes

2020-07-17 Thread Yangbo Lu
This patch-set is to support eMMC HS200 and HS400 speed modes for
eSDHC, and enable them on LX2160ARDB board.

CI build link
https://travis-ci.org/github/yangbolu1991/u-boot-test/builds/709088861

Changes for v2:
- Added two patches to fix stability issue.

Yangbo Lu (11):
  mmc: add a reinit() API
  mmc: fsl_esdhc: add a reinit() callback
  mmc: fsl_esdhc: support tuning for eMMC HS200
  mmc: fsl_esdhc: clean TBCTL[TB_EN] manually during init
  mmc: add a hs400_tuning flag
  mmc: add a mmc_hs400_prepare_ddr() interface
  mmc: fsl_esdhc: support eMMC HS400 mode
  mmc: fsl_esdhc: fix mmc->clock with actual clock
  mmc: fsl_esdhc: fix eMMC HS400 stability issue
  arm: dts: lx2160ardb: support eMMC HS400 mode
  configs: lx2160ardb: enable eMMC HS400 mode support

 arch/arm/dts/fsl-lx2160a-rdb.dts |   2 +
 configs/lx2160ardb_tfa_SECURE_BOOT_defconfig |   1 +
 configs/lx2160ardb_tfa_defconfig |   1 +
 configs/lx2160ardb_tfa_stmm_defconfig|   1 +
 drivers/mmc/fsl_esdhc.c  | 154 ++-
 drivers/mmc/mmc-uclass.c |  30 ++
 drivers/mmc/mmc.c|  12 ++-
 include/fsl_esdhc.h  |  29 -
 include/mmc.h|  26 -
 9 files changed, 246 insertions(+), 10 deletions(-)

-- 
2.7.4



[v2, 01/11] mmc: add a reinit() API

2020-07-17 Thread Yangbo Lu
For DM_MMC, the controller re-initialization is needed to
clear old configuration for mmc rescan.

Signed-off-by: Yangbo Lu 
---
Changes for v2:
- None.
---
 drivers/mmc/mmc-uclass.c | 15 +++
 drivers/mmc/mmc.c|  8 ++--
 include/mmc.h| 10 ++
 3 files changed, 31 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/mmc-uclass.c b/drivers/mmc/mmc-uclass.c
index c5b7872..b9f0880 100644
--- a/drivers/mmc/mmc-uclass.c
+++ b/drivers/mmc/mmc-uclass.c
@@ -170,6 +170,21 @@ int mmc_deferred_probe(struct mmc *mmc)
return dm_mmc_deferred_probe(mmc->dev);
 }
 
+int dm_mmc_reinit(struct udevice *dev)
+{
+   struct dm_mmc_ops *ops = mmc_get_ops(dev);
+
+   if (ops->reinit)
+   return ops->reinit(dev);
+
+   return 0;
+}
+
+int mmc_reinit(struct mmc *mmc)
+{
+   return dm_mmc_reinit(mmc->dev);
+}
+
 int mmc_of_parse(struct udevice *dev, struct mmc_config *cfg)
 {
int val;
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 50f47d4..a53f93a 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -2813,13 +2813,17 @@ int mmc_get_op_cond(struct mmc *mmc)
return err;
 
 #if CONFIG_IS_ENABLED(DM_MMC)
-   /* The device has already been probed ready for use */
+   /*
+* Re-initialization is needed to clear old configuration for
+* mmc rescan.
+*/
+   err = mmc_reinit(mmc);
 #else
/* made sure it's not NULL earlier */
err = mmc->cfg->ops->init(mmc);
+#endif
if (err)
return err;
-#endif
mmc->ddr_mode = 0;
 
 retry:
diff --git a/include/mmc.h b/include/mmc.h
index 8256219..161b8bc 100644
--- a/include/mmc.h
+++ b/include/mmc.h
@@ -422,6 +422,14 @@ struct dm_mmc_ops {
 */
int (*deferred_probe)(struct udevice *dev);
/**
+* reinit() - Re-initialization to clear old configuration for
+* mmc rescan.
+*
+* @dev:Device to reinit
+* @return 0 if Ok, -ve if error
+*/
+   int (*reinit)(struct udevice *dev);
+   /**
 * send_cmd() - Send a command to the MMC device
 *
 * @dev:Device to receive the command
@@ -518,6 +526,7 @@ int dm_mmc_execute_tuning(struct udevice *dev, uint opcode);
 int dm_mmc_wait_dat0(struct udevice *dev, int state, int timeout_us);
 int dm_mmc_host_power_cycle(struct udevice *dev);
 int dm_mmc_deferred_probe(struct udevice *dev);
+int dm_mmc_reinit(struct udevice *dev);
 int dm_mmc_get_b_max(struct udevice *dev, void *dst, lbaint_t blkcnt);
 
 /* Transition functions for compatibility */
@@ -529,6 +538,7 @@ int mmc_wait_dat0(struct mmc *mmc, int state, int 
timeout_us);
 int mmc_set_enhanced_strobe(struct mmc *mmc);
 int mmc_host_power_cycle(struct mmc *mmc);
 int mmc_deferred_probe(struct mmc *mmc);
+int mmc_reinit(struct mmc *mmc);
 int mmc_get_b_max(struct mmc *mmc, void *dst, lbaint_t blkcnt);
 
 #else
-- 
2.7.4



[v2, 02/11] mmc: fsl_esdhc: add a reinit() callback

2020-07-17 Thread Yangbo Lu
Add a reinit() callback for mmc rescan.

Signed-off-by: Yangbo Lu 
---
Changes for v2:
- None.
---
 drivers/mmc/fsl_esdhc.c | 9 +
 1 file changed, 9 insertions(+)

diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c
index a4b923a..d1f2e4a 100644
--- a/drivers/mmc/fsl_esdhc.c
+++ b/drivers/mmc/fsl_esdhc.c
@@ -946,6 +946,14 @@ static int fsl_esdhc_set_ios(struct udevice *dev)
return esdhc_set_ios_common(priv, &plat->mmc);
 }
 
+static int fsl_esdhc_reinit(struct udevice *dev)
+{
+   struct fsl_esdhc_plat *plat = dev_get_platdata(dev);
+   struct fsl_esdhc_priv *priv = dev_get_priv(dev);
+
+   return esdhc_init_common(priv, &plat->mmc);
+}
+
 static const struct dm_mmc_ops fsl_esdhc_ops = {
.get_cd = fsl_esdhc_get_cd,
.send_cmd   = fsl_esdhc_send_cmd,
@@ -953,6 +961,7 @@ static const struct dm_mmc_ops fsl_esdhc_ops = {
 #ifdef MMC_SUPPORTS_TUNING
.execute_tuning = fsl_esdhc_execute_tuning,
 #endif
+   .reinit = fsl_esdhc_reinit,
 };
 
 static const struct udevice_id fsl_esdhc_ids[] = {
-- 
2.7.4



[v2, 03/11] mmc: fsl_esdhc: support tuning for eMMC HS200

2020-07-17 Thread Yangbo Lu
Support tuning process for eMMC HS200 for eSDHC.

Signed-off-by: Yangbo Lu 
---
Changes for v2:
- None.
---
 drivers/mmc/fsl_esdhc.c | 106 ++--
 include/fsl_esdhc.h |  17 ++--
 2 files changed, 116 insertions(+), 7 deletions(-)

diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c
index d1f2e4a..5ad01ac 100644
--- a/drivers/mmc/fsl_esdhc.c
+++ b/drivers/mmc/fsl_esdhc.c
@@ -60,7 +60,9 @@ struct fsl_esdhc {
uintdmaerrattr; /* DMA error attribute register */
charreserved5[4];   /* reserved */
uinthostcapblt2;/* Host controller capabilities register 2 */
-   charreserved6[756]; /* reserved */
+   charreserved6[8];   /* reserved */
+   uinttbctl;  /* Tuning block control register */
+   charreserved7[744]; /* reserved */
uintesdhcctl;   /* eSDHC control register */
 };
 
@@ -101,7 +103,9 @@ static uint esdhc_xfertyp(struct mmc_cmd *cmd, struct 
mmc_data *data)
if (data) {
xfertyp |= XFERTYP_DPSEL;
 #ifndef CONFIG_SYS_FSL_ESDHC_USE_PIO
-   xfertyp |= XFERTYP_DMAEN;
+   if (cmd->cmdidx != MMC_CMD_SEND_TUNING_BLOCK &&
+   cmd->cmdidx != MMC_CMD_SEND_TUNING_BLOCK_HS200)
+   xfertyp |= XFERTYP_DMAEN;
 #endif
if (data->blocks > 1) {
xfertyp |= XFERTYP_MSBSEL;
@@ -380,6 +384,10 @@ static int esdhc_send_cmd_common(struct fsl_esdhc_priv 
*priv, struct mmc *mmc,
esdhc_write32(®s->cmdarg, cmd->cmdarg);
esdhc_write32(®s->xfertyp, xfertyp);
 
+   if (cmd->cmdidx == MMC_CMD_SEND_TUNING_BLOCK ||
+   cmd->cmdidx == MMC_CMD_SEND_TUNING_BLOCK_HS200)
+   flags = IRQSTAT_BRR;
+
/* Wait for the command to complete */
start = get_timer(0);
while (!(esdhc_read32(®s->irqstat) & flags)) {
@@ -439,6 +447,11 @@ static int esdhc_send_cmd_common(struct fsl_esdhc_priv 
*priv, struct mmc *mmc,
 #ifdef CONFIG_SYS_FSL_ESDHC_USE_PIO
esdhc_pio_read_write(priv, data);
 #else
+   flags = DATA_COMPLETE;
+   if (cmd->cmdidx == MMC_CMD_SEND_TUNING_BLOCK ||
+   cmd->cmdidx == MMC_CMD_SEND_TUNING_BLOCK_HS200)
+   flags = IRQSTAT_BRR;
+
do {
irqstat = esdhc_read32(®s->irqstat);
 
@@ -451,7 +464,7 @@ static int esdhc_send_cmd_common(struct fsl_esdhc_priv 
*priv, struct mmc *mmc,
err = -ECOMM;
goto out;
}
-   } while ((irqstat & DATA_COMPLETE) != DATA_COMPLETE);
+   } while ((irqstat & flags) != flags);
 
/*
 * Need invalidate the dcache here again to avoid any
@@ -555,6 +568,19 @@ static void esdhc_clock_control(struct fsl_esdhc_priv 
*priv, bool enable)
}
 }
 
+static void esdhc_set_timing(struct fsl_esdhc_priv *priv, enum bus_mode mode)
+{
+   struct fsl_esdhc *regs = priv->esdhc_regs;
+
+   esdhc_clock_control(priv, false);
+
+   if (mode == MMC_HS_200)
+   esdhc_clrsetbits32(®s->autoc12err, UHSM_MASK,
+  UHSM_SDR104_HS200);
+
+   esdhc_clock_control(priv, true);
+}
+
 static int esdhc_set_ios_common(struct fsl_esdhc_priv *priv, struct mmc *mmc)
 {
struct fsl_esdhc *regs = priv->esdhc_regs;
@@ -570,6 +596,9 @@ static int esdhc_set_ios_common(struct fsl_esdhc_priv 
*priv, struct mmc *mmc)
if (priv->clock != mmc->clock)
set_sysctl(priv, mmc, mmc->clock);
 
+   /* Set timing */
+   esdhc_set_timing(priv, mmc->selected_mode);
+
/* Set the bus width */
esdhc_clrbits32(®s->proctl, PROCTL_DTW_4 | PROCTL_DTW_8);
 
@@ -954,6 +983,77 @@ static int fsl_esdhc_reinit(struct udevice *dev)
return esdhc_init_common(priv, &plat->mmc);
 }
 
+#ifdef MMC_SUPPORTS_TUNING
+static void esdhc_flush_async_fifo(struct fsl_esdhc_priv *priv)
+{
+   struct fsl_esdhc *regs = priv->esdhc_regs;
+   u32 time_out;
+
+   esdhc_setbits32(®s->esdhcctl, ESDHCCTL_FAF);
+
+   time_out = 20;
+   while (esdhc_read32(®s->esdhcctl) & ESDHCCTL_FAF) {
+   if (time_out == 0) {
+   printf("fsl_esdhc: Flush asynchronous FIFO timeout.\n");
+   break;
+   }
+   time_out--;
+   mdelay(1);
+   }
+}
+
+static void esdhc_tuning_block_enable(struct fsl_esdhc_priv *priv,
+ bool en)
+{
+   struct fsl_esdhc *regs = priv->esdhc_regs;
+
+   esdhc_clock_control(priv, false);
+   esdhc_flush_async_fifo(priv);
+   if (en)
+   esdhc_setbits32(®s->tbctl, TBCTL_TB_EN);
+   else
+   esdhc_clrbits32(®s->tbctl, TBCTL_TB_EN);
+   esdhc_clock_control(priv, true);
+}
+
+static int fsl_esdhc_exec

[v2, 05/11] mmc: add a hs400_tuning flag

2020-07-17 Thread Yangbo Lu
Add a hs400_tuning flag to identify the tuning for HS400 mode.

Signed-off-by: Yangbo Lu 
---
Changes for v2:
- None.
---
 drivers/mmc/mmc.c | 2 ++
 include/mmc.h | 1 +
 2 files changed, 3 insertions(+)

diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index a53f93a..a18e75d 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -1976,7 +1976,9 @@ static int mmc_select_hs400(struct mmc *mmc)
mmc_set_clock(mmc, mmc->tran_speed, false);
 
/* execute tuning if needed */
+   mmc->hs400_tuning = 1;
err = mmc_execute_tuning(mmc, MMC_CMD_SEND_TUNING_BLOCK_HS200);
+   mmc->hs400_tuning = 0;
if (err) {
debug("tuning failed\n");
return err;
diff --git a/include/mmc.h b/include/mmc.h
index 161b8bc..2399cc2 100644
--- a/include/mmc.h
+++ b/include/mmc.h
@@ -707,6 +707,7 @@ struct mmc {
  * accessing the boot partitions
  */
u32 quirks;
+   u8 hs400_tuning;
 };
 
 struct mmc_hwpart_conf {
-- 
2.7.4



[v2, 04/11] mmc: fsl_esdhc: clean TBCTL[TB_EN] manually during init

2020-07-17 Thread Yangbo Lu
Clean TBCTL[TB_EN] manually during init since it is not able to
be reset by reset all operation.

Signed-off-by: Yangbo Lu 
---
Changes for v2:
- None.
---
 drivers/mmc/fsl_esdhc.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c
index 5ad01ac..607b420 100644
--- a/drivers/mmc/fsl_esdhc.c
+++ b/drivers/mmc/fsl_esdhc.c
@@ -637,6 +637,9 @@ static int esdhc_init_common(struct fsl_esdhc_priv *priv, 
struct mmc *mmc)
return -ETIMEDOUT;
}
 
+   /* Clean TBCTL[TB_EN] which is not able to be reset by reset all */
+   esdhc_clrbits32(®s->tbctl, TBCTL_TB_EN);
+
esdhc_enable_cache_snooping(regs);
 
esdhc_setbits32(®s->sysctl, SYSCTL_HCKEN | SYSCTL_IPGEN);
-- 
2.7.4



[v2, 09/11] mmc: fsl_esdhc: fix eMMC HS400 stability issue

2020-07-17 Thread Yangbo Lu
There was a fix-up for eMMC HS400 stability issue in Linux.

Patch link:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/
commit/?id=58d0bf843b49fa99588ac9f85178bd8dfd651b53

Description:
Currently only LX2160A eSDHC supports eMMC HS400. According to
a large number of tests, eMMC HS400 failed to work at 150MHz,
and for a few boards failed to work at 175MHz. But eMMC HS400
worked fine on 200MHz. We hadn't found the root cause but
setting eSDHC_DLLCFG0[DLL_FREQ_SEL] = 0 using slow delay chain
seemed to resovle this issue. Let's use this as fixup for now.

Introduce the fix-up in u-boot since the issue could be reproduced
in u-boot too.

Signed-off-by: Yangbo Lu 
---
Changes for v2:
- Added this patch.
---
 drivers/mmc/fsl_esdhc.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c
index 8999b74..0879739 100644
--- a/drivers/mmc/fsl_esdhc.c
+++ b/drivers/mmc/fsl_esdhc.c
@@ -622,7 +622,10 @@ static void esdhc_set_timing(struct fsl_esdhc_priv *priv, 
enum bus_mode mode)
esdhc_setbits32(®s->sdclkctl, CMD_CLK_CTL);
esdhc_clock_control(priv, true);
 
-   esdhc_setbits32(®s->dllcfg0, DLL_ENABLE | DLL_FREQ_SEL);
+   if (priv->clock == 2)
+   esdhc_setbits32(®s->dllcfg0, DLL_FREQ_SEL);
+
+   esdhc_setbits32(®s->dllcfg0, DLL_ENABLE);
esdhc_setbits32(®s->tbctl, HS400_WNDW_ADJUST);
 
esdhc_clock_control(priv, false);
-- 
2.7.4



[v2, 10/11] arm: dts: lx2160ardb: support eMMC HS400 mode

2020-07-17 Thread Yangbo Lu
Add properties related to eMMC HS400 mode.

mmc-hs400-1_8v;
bus-width = <8>;

Signed-off-by: Yangbo Lu 
---
Changes for v2:
- None.
---
 arch/arm/dts/fsl-lx2160a-rdb.dts | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/dts/fsl-lx2160a-rdb.dts b/arch/arm/dts/fsl-lx2160a-rdb.dts
index d787778..5fbdd90 100644
--- a/arch/arm/dts/fsl-lx2160a-rdb.dts
+++ b/arch/arm/dts/fsl-lx2160a-rdb.dts
@@ -80,6 +80,8 @@
 &esdhc1 {
status = "okay";
mmc-hs200-1_8v;
+   mmc-hs400-1_8v;
+   bus-width = <8>;
 };
 
 &fspi {
-- 
2.7.4



[v2, 07/11] mmc: fsl_esdhc: support eMMC HS400 mode

2020-07-17 Thread Yangbo Lu
The process for eMMC HS400 mode for eSDHC is,

1. Perform the Tuning Process at the HS400 target operating frequency.
   Latched the clock division value.
2. if read transaction, then set the SDTIMNGCTL[FLW_CTL_BG].
3. Switch to High Speed mode and then set the card clock frequency to
   a value not greater than 52Mhz
4. Clear TBCTL[TB_EN],tuning block enable bit.
5. Change to 8 bit DDR Mode
6. Switch the card to HS400 mode.
7. Set TBCTL[TB_EN], tuning block enable bit.
8. Clear SYSCTL[SDCLKEN]
9. Wait for PRSSTAT[SDSTB] to be set
10. Change the clock division to latched value.Set TBCTL[HS 400 mode]
and Set SDCLKCTL[CMD_CLK_CTRL]
11. Set SYSCTL[SDCLKEN]
12. Wait for PRSSTAT[SDSTB] to be set
13. Set DLLCFG0[DLL_ENABLE] and DLLCFG0[DLL_FREQ_SEL].
14. Wait for delay chain to lock.
15. Set TBCTL[HS400_WNDW_ADJUST]
16. Again clear SYSCTL[SDCLKEN]
17. Wait for PRSSTAT[SDSTB] to be set
18. Set ESDHCCTL[FAF]
19. Wait for ESDHCCTL[FAF] to be cleared
20. Set SYSCTL[SDCLKEN]
21. Wait for PRSSTAT[SDSTB] to be set.

Signed-off-by: Yangbo Lu 
---
Changes for v2:
- None.
---
 drivers/mmc/fsl_esdhc.c | 98 -
 include/fsl_esdhc.h | 12 ++
 2 files changed, 76 insertions(+), 34 deletions(-)

diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c
index 607b420..c1a127c 100644
--- a/drivers/mmc/fsl_esdhc.c
+++ b/drivers/mmc/fsl_esdhc.c
@@ -62,7 +62,12 @@ struct fsl_esdhc {
uinthostcapblt2;/* Host controller capabilities register 2 */
charreserved6[8];   /* reserved */
uinttbctl;  /* Tuning block control register */
-   charreserved7[744]; /* reserved */
+   charreserved7[32];  /* reserved */
+   uintsdclkctl;   /* SD clock control register */
+   uintsdtimingctl;/* SD timing control register */
+   charreserved8[20];  /* reserved */
+   uintdllcfg0;/* DLL config 0 register */
+   charreserved9[680]; /* reserved */
uintesdhcctl;   /* eSDHC control register */
 };
 
@@ -568,6 +573,38 @@ static void esdhc_clock_control(struct fsl_esdhc_priv 
*priv, bool enable)
}
 }
 
+static void esdhc_flush_async_fifo(struct fsl_esdhc_priv *priv)
+{
+   struct fsl_esdhc *regs = priv->esdhc_regs;
+   u32 time_out;
+
+   esdhc_setbits32(®s->esdhcctl, ESDHCCTL_FAF);
+
+   time_out = 20;
+   while (esdhc_read32(®s->esdhcctl) & ESDHCCTL_FAF) {
+   if (time_out == 0) {
+   printf("fsl_esdhc: Flush asynchronous FIFO timeout.\n");
+   break;
+   }
+   time_out--;
+   mdelay(1);
+   }
+}
+
+static void esdhc_tuning_block_enable(struct fsl_esdhc_priv *priv,
+ bool en)
+{
+   struct fsl_esdhc *regs = priv->esdhc_regs;
+
+   esdhc_clock_control(priv, false);
+   esdhc_flush_async_fifo(priv);
+   if (en)
+   esdhc_setbits32(®s->tbctl, TBCTL_TB_EN);
+   else
+   esdhc_clrbits32(®s->tbctl, TBCTL_TB_EN);
+   esdhc_clock_control(priv, true);
+}
+
 static void esdhc_set_timing(struct fsl_esdhc_priv *priv, enum bus_mode mode)
 {
struct fsl_esdhc *regs = priv->esdhc_regs;
@@ -577,7 +614,17 @@ static void esdhc_set_timing(struct fsl_esdhc_priv *priv, 
enum bus_mode mode)
if (mode == MMC_HS_200)
esdhc_clrsetbits32(®s->autoc12err, UHSM_MASK,
   UHSM_SDR104_HS200);
+   if (mode == MMC_HS_400) {
+   esdhc_setbits32(®s->tbctl, HS400_MODE);
+   esdhc_setbits32(®s->sdclkctl, CMD_CLK_CTL);
+   esdhc_clock_control(priv, true);
 
+   esdhc_setbits32(®s->dllcfg0, DLL_ENABLE | DLL_FREQ_SEL);
+   esdhc_setbits32(®s->tbctl, HS400_WNDW_ADJUST);
+
+   esdhc_clock_control(priv, false);
+   esdhc_flush_async_fifo(priv);
+   }
esdhc_clock_control(priv, true);
 }
 
@@ -592,6 +639,9 @@ static int esdhc_set_ios_common(struct fsl_esdhc_priv 
*priv, struct mmc *mmc)
esdhc_clock_control(priv, true);
}
 
+   if (mmc->selected_mode == MMC_HS_400)
+   esdhc_tuning_block_enable(priv, true);
+
/* Set the clock speed */
if (priv->clock != mmc->clock)
set_sysctl(priv, mmc, mmc->clock);
@@ -987,38 +1037,6 @@ static int fsl_esdhc_reinit(struct udevice *dev)
 }
 
 #ifdef MMC_SUPPORTS_TUNING
-static void esdhc_flush_async_fifo(struct fsl_esdhc_priv *priv)
-{
-   struct fsl_esdhc *regs = priv->esdhc_regs;
-   u32 time_out;
-
-   esdhc_setbits32(®s->esdhcctl, ESDHCCTL_FAF);
-
-   time_out = 20;
-   while (esdhc_read32(®s->esdhcctl) & ESDHCCTL_FAF) {
-   if (time_out == 0) {
-   printf("fsl_esdhc: Flush asynchronous FIFO timeout.\n");
-   break;
-   }
-   time_out--;
-  

[v2, 08/11] mmc: fsl_esdhc: fix mmc->clock with actual clock

2020-07-17 Thread Yangbo Lu
Fix mmc->clock with actual clock which is divided by the
controller, and record it with priv->clock which was removed
accidentally.

Signed-off-by: Yangbo Lu 
---
Changes for v2:
- Added this patch.
---
 drivers/mmc/fsl_esdhc.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c
index c1a127c..8999b74 100644
--- a/drivers/mmc/fsl_esdhc.c
+++ b/drivers/mmc/fsl_esdhc.c
@@ -523,6 +523,9 @@ static void set_sysctl(struct fsl_esdhc_priv *priv, struct 
mmc *mmc, uint clock)
while (sdhc_clk / (div * pre_div) > clock && div < 16)
div++;
 
+   mmc->clock = sdhc_clk / pre_div / div;
+   priv->clock = mmc->clock;
+
pre_div >>= 1;
div -= 1;
 
-- 
2.7.4



[v2, 06/11] mmc: add a mmc_hs400_prepare_ddr() interface

2020-07-17 Thread Yangbo Lu
Add a mmc_hs400_prepare_ddr() interface for controllers
which needs preparation before switching to DDR mode for
HS400 mode.

Signed-off-by: Yangbo Lu 
---
Changes for v2:
- None.
---
 drivers/mmc/mmc-uclass.c | 15 +++
 drivers/mmc/mmc.c|  2 ++
 include/mmc.h| 15 ++-
 3 files changed, 31 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/mmc-uclass.c b/drivers/mmc/mmc-uclass.c
index b9f0880..240b205 100644
--- a/drivers/mmc/mmc-uclass.c
+++ b/drivers/mmc/mmc-uclass.c
@@ -141,6 +141,21 @@ int mmc_set_enhanced_strobe(struct mmc *mmc)
 }
 #endif
 
+int dm_mmc_hs400_prepare_ddr(struct udevice *dev)
+{
+   struct dm_mmc_ops *ops = mmc_get_ops(dev);
+
+   if (ops->hs400_prepare_ddr)
+   return ops->hs400_prepare_ddr(dev);
+
+   return 0;
+}
+
+int mmc_hs400_prepare_ddr(struct mmc *mmc)
+{
+   return dm_mmc_hs400_prepare_ddr(mmc->dev);
+}
+
 int dm_mmc_host_power_cycle(struct udevice *dev)
 {
struct dm_mmc_ops *ops = mmc_get_ops(dev);
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index a18e75d..e396207 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -1987,6 +1987,8 @@ static int mmc_select_hs400(struct mmc *mmc)
/* Set back to HS */
mmc_set_card_speed(mmc, MMC_HS, true);
 
+   mmc_hs400_prepare_ddr(mmc);
+
err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH,
 EXT_CSD_BUS_WIDTH_8 | EXT_CSD_DDR_FLAG);
if (err)
diff --git a/include/mmc.h b/include/mmc.h
index 2399cc2..659df75 100644
--- a/include/mmc.h
+++ b/include/mmc.h
@@ -513,6 +513,14 @@ struct dm_mmc_ops {
 * @return maximum number of blocks for this transfer
 */
int (*get_b_max)(struct udevice *dev, void *dst, lbaint_t blkcnt);
+
+   /**
+* hs400_prepare_ddr - prepare to switch to DDR mode
+*
+* @dev:Device to check
+* @return 0 if success, -ve on error
+*/
+   int (*hs400_prepare_ddr)(struct udevice *dev);
 };
 
 #define mmc_get_ops(dev)((struct dm_mmc_ops *)(dev)->driver->ops)
@@ -540,7 +548,7 @@ int mmc_host_power_cycle(struct mmc *mmc);
 int mmc_deferred_probe(struct mmc *mmc);
 int mmc_reinit(struct mmc *mmc);
 int mmc_get_b_max(struct mmc *mmc, void *dst, lbaint_t blkcnt);
-
+int mmc_hs400_prepare_ddr(struct mmc *mmc);
 #else
 struct mmc_ops {
int (*send_cmd)(struct mmc *mmc,
@@ -552,6 +560,11 @@ struct mmc_ops {
int (*host_power_cycle)(struct mmc *mmc);
int (*get_b_max)(struct mmc *mmc, void *dst, lbaint_t blkcnt);
 };
+
+static inline int mmc_hs400_prepare_ddr(struct mmc *mmc)
+{
+   return 0;
+}
 #endif
 
 struct mmc_config {
-- 
2.7.4



[v2, 11/11] configs: lx2160ardb: enable eMMC HS400 mode support

2020-07-17 Thread Yangbo Lu
Enable eMMC HS400 mode support on LX2160ARDB.

Signed-off-by: Yangbo Lu 
---
Changes for v2:
- None.
---
 configs/lx2160ardb_tfa_SECURE_BOOT_defconfig | 1 +
 configs/lx2160ardb_tfa_defconfig | 1 +
 configs/lx2160ardb_tfa_stmm_defconfig| 1 +
 3 files changed, 3 insertions(+)

diff --git a/configs/lx2160ardb_tfa_SECURE_BOOT_defconfig 
b/configs/lx2160ardb_tfa_SECURE_BOOT_defconfig
index 12e224f..6c65853 100644
--- a/configs/lx2160ardb_tfa_SECURE_BOOT_defconfig
+++ b/configs/lx2160ardb_tfa_SECURE_BOOT_defconfig
@@ -40,6 +40,7 @@ CONFIG_DM_I2C=y
 CONFIG_I2C_SET_DEFAULT_BUS_NUM=y
 CONFIG_I2C_DEFAULT_BUS_NUMBER=0
 CONFIG_DM_MMC=y
+CONFIG_MMC_HS400_SUPPORT=y
 CONFIG_FSL_ESDHC=y
 CONFIG_MTD=y
 CONFIG_DM_SPI_FLASH=y
diff --git a/configs/lx2160ardb_tfa_defconfig b/configs/lx2160ardb_tfa_defconfig
index a5c78d2..a5c60c8 100644
--- a/configs/lx2160ardb_tfa_defconfig
+++ b/configs/lx2160ardb_tfa_defconfig
@@ -46,6 +46,7 @@ CONFIG_DM_I2C=y
 CONFIG_I2C_SET_DEFAULT_BUS_NUM=y
 CONFIG_I2C_DEFAULT_BUS_NUMBER=0
 CONFIG_DM_MMC=y
+CONFIG_MMC_HS400_SUPPORT=y
 CONFIG_FSL_ESDHC=y
 CONFIG_MTD=y
 CONFIG_DM_SPI_FLASH=y
diff --git a/configs/lx2160ardb_tfa_stmm_defconfig 
b/configs/lx2160ardb_tfa_stmm_defconfig
index e97c9b0..869d4e2 100644
--- a/configs/lx2160ardb_tfa_stmm_defconfig
+++ b/configs/lx2160ardb_tfa_stmm_defconfig
@@ -48,6 +48,7 @@ CONFIG_DM_I2C=y
 CONFIG_I2C_SET_DEFAULT_BUS_NUM=y
 CONFIG_I2C_DEFAULT_BUS_NUMBER=0
 CONFIG_DM_MMC=y
+CONFIG_MMC_HS400_SUPPORT=y
 CONFIG_SUPPORT_EMMC_RPMB=y
 CONFIG_FSL_ESDHC=y
 CONFIG_MTD=y
-- 
2.7.4



Re: [PATCH] riscv: ae350: Use fdtdec_get_addr_size_auto_noparent to parse smc reg

2020-07-17 Thread Bin Meng
On Fri, Jul 17, 2020 at 4:35 PM Andes  wrote:
>
> From: Rick Chen 
>
> Use fdtdec_get_addr_size_auto_noparent to read the "reg" property
> instead of fdtdec_get_addr. This will increase the compatibility
> of dtb parsing.
>
> Signed-off-by: Rick Chen 
> ---
>  board/AndesTech/ax25-ae350/ax25-ae350.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
>

Reviewed-by: Bin Meng 


Re: [PATCH v1 1/4] usb: xhci: Add missing endian conversions (cpu_to_leXX / leXX_to_cpu)

2020-07-17 Thread Stefan Roese

On 17.07.20 07:15, Bin Meng wrote:

On Thu, Jul 2, 2020 at 4:47 PM Stefan Roese  wrote:


While trying to use the U-Boot xHCI driver on the MIPS Octeon platform,
which is big endian, I noticed that the driver is missing a few endian
conversion calls. This patch adds these missing endian conversion
calls.

Signed-off-by: Stefan Roese 
Cc: Bin Meng 
Cc: Marek Vasut 
---

  drivers/usb/host/xhci-mem.c | 9 +
  1 file changed, 5 insertions(+), 4 deletions(-)



Good catch! It's hard to detect these problems if we only validate
xHCI on ARM/x86 which are little-endian. Apparently there is no xHCI
on PPC, so MIPS becomes the first big endian platform using xHCI.


Yes, I was also astonished that the xHCI driver has only been used by
little-endian platforms so far. I did expect that at least some PPC
platforms supported this code. Apparently this is not the case.


Reviewed-by: Bin Meng 


Thanks,
Stefan


Re: [PATCH v1 2/4] usb: xhci: xhci_mem_init: Use cpu_to_le64() and not xhci_writeq()

2020-07-17 Thread Stefan Roese

On 17.07.20 07:24, Bin Meng wrote:

Hi Stefan,

On Thu, Jul 2, 2020 at 4:47 PM Stefan Roese  wrote:


xhci_writeq() makes the CPU->LE swapping only when addressing registers
in the xHCI controller address range and not in the local memory (RAM).


Is the above behavior exposed by the MIPS platform's writel()?


Not sure what you mean with this. Without this patch, xhci_writeq()
will not swap on Octeon MIPS, as the destination address is located
in local memory (DDR). Using the xhci_read/write accessor functions
should be restricted to accessing the controller registers.

BTW: The Octeon MIPS writel will swap to little-endian, when the
location is in the xHCI controller address space (and PCI etc). This
support for selective swapping is not pushed into mainline yet. I
will send it in some follow up patches.

Thanks,
Stefan


We need to use cpu_to_le64() here to ensure that the conversion is done
correctly.

Signed-off-by: Stefan Roese 
Cc: Bin Meng 
Cc: Marek Vasut 
---

  drivers/usb/host/xhci-mem.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index bd959b4093..3b805ecb9e 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -562,7 +562,7 @@ int xhci_mem_init(struct xhci_ctrl *ctrl, struct xhci_hccr 
*hccr,
 trb_64 = 0;
 trb_64 = (uintptr_t)seg->trbs;
 struct xhci_erst_entry *entry = &ctrl->erst.entries[val];
-   xhci_writeq(&entry->seg_addr, trb_64);
+   entry->seg_addr = cpu_to_le64(trb_64);
 entry->seg_size = cpu_to_le32(TRBS_PER_SEGMENT);
 entry->rsvd = 0;
 seg = seg->next;


Reviewed-by: Bin Meng 

Regards,
Bin



Thanks,
Stefan



Re: [PATCH v1 3/4] usb: usb-uclass.c: Drop le16_to_cpu() as values are already swapped

2020-07-17 Thread Stefan Roese

On 17.07.20 07:33, Bin Meng wrote:

Hi Stefan,

On Thu, Jul 2, 2020 at 4:47 PM Stefan Roese  wrote:


These values are already swapped to CPU endianess, so swapping them


Can you please add more details as to when these values are swapped? I
assume this is inside usb_select_config() which is called before this
function is called?


Yes. Its swapped exactly here:

int usb_select_config(struct usb_device *dev)
{
unsigned char *tmpbuf = NULL;
int err;

err = get_descriptor_len(dev, USB_DT_DEVICE_SIZE, USB_DT_DEVICE_SIZE);
if (err)
return err;

/* correct le values */
le16_to_cpus(&dev->descriptor.bcdUSB);
le16_to_cpus(&dev->descriptor.idVendor);
le16_to_cpus(&dev->descriptor.idProduct);
le16_to_cpus(&dev->descriptor.bcdDevice);


But I wonder how this code ever worked on ARM/x86?


On ARM/x86, the little-endian swapping is a no-op. So it doesn't matter
if you swap once or twice or... ;)


again is a bug. Let's remove the swap here instead.

Signed-off-by: Stefan Roese 
Cc: Bin Meng 
Cc: Marek Vasut 
---

  drivers/usb/host/usb-uclass.c | 8 
  1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/host/usb-uclass.c b/drivers/usb/host/usb-uclass.c
index cb79dfbbd5..aa08d4ffc6 100644
--- a/drivers/usb/host/usb-uclass.c
+++ b/drivers/usb/host/usb-uclass.c
@@ -416,21 +416,21 @@ static int usb_match_device(const struct 
usb_device_descriptor *desc,
 const struct usb_device_id *id)
  {
 if ((id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) &&
-   id->idVendor != le16_to_cpu(desc->idVendor))
+   id->idVendor != desc->idVendor)
 return 0;

 if ((id->match_flags & USB_DEVICE_ID_MATCH_PRODUCT) &&
-   id->idProduct != le16_to_cpu(desc->idProduct))
+   id->idProduct != desc->idProduct)
 return 0;

 /* No need to test id->bcdDevice_lo != 0, since 0 is never
greater than any unsigned number. */
 if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_LO) &&
-   (id->bcdDevice_lo > le16_to_cpu(desc->bcdDevice)))
+   (id->bcdDevice_lo > desc->bcdDevice))
 return 0;

 if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_HI) &&
-   (id->bcdDevice_hi < le16_to_cpu(desc->bcdDevice)))
+   (id->bcdDevice_hi < desc->bcdDevice))
 return 0;

 if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_CLASS) &&


Reviewed-by: Bin Meng 

Regards,
Bin


Thanks,
Stefan


Re: [PATCH v1 2/4] usb: xhci: xhci_mem_init: Use cpu_to_le64() and not xhci_writeq()

2020-07-17 Thread Bin Meng
Hi Stefan,

On Fri, Jul 17, 2020 at 6:04 PM Stefan Roese  wrote:
>
> On 17.07.20 07:24, Bin Meng wrote:
> > Hi Stefan,
> >
> > On Thu, Jul 2, 2020 at 4:47 PM Stefan Roese  wrote:
> >>
> >> xhci_writeq() makes the CPU->LE swapping only when addressing registers
> >> in the xHCI controller address range and not in the local memory (RAM).
> >
> > Is the above behavior exposed by the MIPS platform's writel()?
>
> Not sure what you mean with this. Without this patch, xhci_writeq()
> will not swap on Octeon MIPS, as the destination address is located
> in local memory (DDR).

I wonder why xhci_writeq() does not swap? Is this due to the writel()
implementation on Octeon MIPS?

> Using the xhci_read/write accessor functions
> should be restricted to accessing the controller registers.

Yes, this is the supposed usage that xhci_read/write should be called
to operate on xHCI registers. However my question was why
xhci_read/write does not swap even it is called on memory space, hence
the writel() question.

>
> BTW: The Octeon MIPS writel will swap to little-endian, when the
> location is in the xHCI controller address space (and PCI etc). This
> support for selective swapping is not pushed into mainline yet. I
> will send it in some follow up patches.
>

Regards,
Bin


Re: [PATCH v1 2/4] usb: xhci: xhci_mem_init: Use cpu_to_le64() and not xhci_writeq()

2020-07-17 Thread Stefan Roese

Hi Bin,

On 17.07.20 12:09, Bin Meng wrote:

Hi Stefan,

On Fri, Jul 17, 2020 at 6:04 PM Stefan Roese  wrote:


On 17.07.20 07:24, Bin Meng wrote:

Hi Stefan,

On Thu, Jul 2, 2020 at 4:47 PM Stefan Roese  wrote:


xhci_writeq() makes the CPU->LE swapping only when addressing registers
in the xHCI controller address range and not in the local memory (RAM).


Is the above behavior exposed by the MIPS platform's writel()?


Not sure what you mean with this. Without this patch, xhci_writeq()
will not swap on Octeon MIPS, as the destination address is located
in local memory (DDR).


I wonder why xhci_writeq() does not swap? Is this due to the writel()
implementation on Octeon MIPS?


Ah, okay. Please see my comment below for this. Here again:

BTW: The Octeon MIPS writel will swap to little-endian, when the
location is in the xHCI controller address space (and PCI etc). This
support for selective swapping is not pushed into mainline yet. I
will send it in some follow up patches.

So to answer your question: writel will not swap when addressing
local memory.


Using the xhci_read/write accessor functions
should be restricted to accessing the controller registers.


Yes, this is the supposed usage that xhci_read/write should be called
to operate on xHCI registers. However my question was why
xhci_read/write does not swap even it is called on memory space, hence
the writel() question.



BTW: The Octeon MIPS writel will swap to little-endian, when the
location is in the xHCI controller address space (and PCI etc). This
support for selective swapping is not pushed into mainline yet. I
will send it in some follow up patches.



Regards,
Bin



Thanks,
Stefan


Re: [PATCH v1 3/4] usb: usb-uclass.c: Drop le16_to_cpu() as values are already swapped

2020-07-17 Thread Bin Meng
Hi Stefan,

On Fri, Jul 17, 2020 at 6:08 PM Stefan Roese  wrote:
>
> On 17.07.20 07:33, Bin Meng wrote:
> > Hi Stefan,
> >
> > On Thu, Jul 2, 2020 at 4:47 PM Stefan Roese  wrote:
> >>
> >> These values are already swapped to CPU endianess, so swapping them
> >
> > Can you please add more details as to when these values are swapped? I
> > assume this is inside usb_select_config() which is called before this
> > function is called?
>
> Yes. Its swapped exactly here:
>
> int usb_select_config(struct usb_device *dev)
> {
> unsigned char *tmpbuf = NULL;
> int err;
>
> err = get_descriptor_len(dev, USB_DT_DEVICE_SIZE, USB_DT_DEVICE_SIZE);
> if (err)
> return err;
>
> /* correct le values */
> le16_to_cpus(&dev->descriptor.bcdUSB);
> le16_to_cpus(&dev->descriptor.idVendor);
> le16_to_cpus(&dev->descriptor.idProduct);
> le16_to_cpus(&dev->descriptor.bcdDevice);
>
> > But I wonder how this code ever worked on ARM/x86?
>
> On ARM/x86, the little-endian swapping is a no-op. So it doesn't matter
> if you swap once or twice or... ;)
>

Ah, yes! I misread this as an unconditional swap ...

> >> again is a bug. Let's remove the swap here instead.
> >>
> >> Signed-off-by: Stefan Roese 
> >> Cc: Bin Meng 
> >> Cc: Marek Vasut 
> >> ---
> >>
> >>   drivers/usb/host/usb-uclass.c | 8 
> >>   1 file changed, 4 insertions(+), 4 deletions(-)
> >>

Regards,
Bin


Re: [PATCH] riscv: ae350: Use fdtdec_get_addr_size_auto_noparent to parse smc reg

2020-07-17 Thread Leo Liang
On Fri, Jul 17, 2020 at 05:38:19PM +0800, Bin Meng wrote:
> On Fri, Jul 17, 2020 at 4:35 PM Andes  wrote:
> >
> > From: Rick Chen 
> >
> > Use fdtdec_get_addr_size_auto_noparent to read the "reg" property
> > instead of fdtdec_get_addr. This will increase the compatibility
> > of dtb parsing.
> >
> > Signed-off-by: Rick Chen 
> > ---
> >  board/AndesTech/ax25-ae350/ax25-ae350.c | 3 ++-
> >  1 file changed, 2 insertions(+), 1 deletion(-)
> >
> 
> Reviewed-by: Bin Meng 

Tested-by: Leo Liang 


Re: [PATCH v1 2/4] usb: xhci: xhci_mem_init: Use cpu_to_le64() and not xhci_writeq()

2020-07-17 Thread Bin Meng
Hi Stefan,

On Fri, Jul 17, 2020 at 6:11 PM Stefan Roese  wrote:
>
> Hi Bin,
>
> On 17.07.20 12:09, Bin Meng wrote:
> > Hi Stefan,
> >
> > On Fri, Jul 17, 2020 at 6:04 PM Stefan Roese  wrote:
> >>
> >> On 17.07.20 07:24, Bin Meng wrote:
> >>> Hi Stefan,
> >>>
> >>> On Thu, Jul 2, 2020 at 4:47 PM Stefan Roese  wrote:
> 
>  xhci_writeq() makes the CPU->LE swapping only when addressing registers
>  in the xHCI controller address range and not in the local memory (RAM).
> >>>
> >>> Is the above behavior exposed by the MIPS platform's writel()?
> >>
> >> Not sure what you mean with this. Without this patch, xhci_writeq()
> >> will not swap on Octeon MIPS, as the destination address is located
> >> in local memory (DDR).
> >
> > I wonder why xhci_writeq() does not swap? Is this due to the writel()
> > implementation on Octeon MIPS?
>
> Ah, okay. Please see my comment below for this. Here again:
>
> BTW: The Octeon MIPS writel will swap to little-endian, when the
> location is in the xHCI controller address space (and PCI etc). This
> support for selective swapping is not pushed into mainline yet. I
> will send it in some follow up patches.
>
> So to answer your question: writel will not swap when addressing
> local memory.

Thanks. That explains.

>
> >> Using the xhci_read/write accessor functions
> >> should be restricted to accessing the controller registers.
> >
> > Yes, this is the supposed usage that xhci_read/write should be called
> > to operate on xHCI registers. However my question was why
> > xhci_read/write does not swap even it is called on memory space, hence
> > the writel() question.
> >

Regards,
Bin


Please pull u-boot-x86

2020-07-17 Thread Bin Meng
Hi Tom,

This PR includes the following changes for v2020.10 release:

- New timer API to allow delays with a 32-bit microsecond timer
- Add dynamic ACPI structs (DSDT/SSDT) generations to the DM core
- x86: Enable ACPI table generation by default
- x86: Enable the copy framebuffer on Coral
- x86: A few fixes to FSP2 with ApolloLake
- x86: Drop setup_pcat_compatibility()
- x86: Primary-to-Sideband Bus minor fixes

Azure results: PASS
https://dev.azure.com/bmeng/GitHub/_build/results?buildId=263&view=results

The following changes since commit fee68b98fe3890631a9bdf8f8db328179011ee3f:

  Merge tag 'efi-2020-10-rc1-4' of
https://gitlab.denx.de/u-boot/custodians/u-boot-efi (2020-07-16
16:35:15 -0400)

are available in the git repository at:

  https://gitlab.denx.de/u-boot/custodians/u-boot-x86

for you to fetch changes up to d40d2c570600396b54dece16429727ef50cfeef0:

  acpi: Enable ACPI table generation by default on x86 (2020-07-17
14:32:24 +0800)


Simon Glass (82):
  timer: Allow delays with a 32-bit microsecond timer
  coral: Enable the copy framebuffer
  x86: Avoid #ifdef with CONFIG_HAVE_ACPI_RESUME
  x86: fsp: Support a warning message when DRAM init is slow
  dm: core: Add an ACPI name for the root node
  acpi: Add a function to get a device path and scope
  acpi: Add a way to check device status
  irq: Add a method to convert an interrupt to ACPI
  acpi: Support generation of ACPI code
  acpi: Support generation of interrupt descriptor
  gpio: Add a method to convert a GPIO to ACPI
  acpi: Support string output
  acpi: Support generation of GPIO descriptor
  acpi: Support generation of a GPIO/irq for a device
  acpi: Support generation of I2C descriptor
  acpi: Support generation of SPI descriptor
  acpigen: Support writing a length
  acpigen: Support writing a package
  acpi: Support writing an integer
  acpi: Support writing a string
  acpi: Support writing a name
  acpi: Support writing a UUID
  acpi: Support writing Device Properties objects via _DSD
  acpi: Support writing a GPIO
  acpi: Support copying properties from device tree to ACPI
  acpi: Add support for various misc ACPI opcodes
  acpi: Add support for writing a Power Resource
  acpi: Add support for writing a GPIO power sequence
  acpi: Add support for a generic power sequence
  acpi: Add support for SSDT generation
  x86: acpi: Move MADT down a bit
  acpi: Record the items added to SSDT
  acpi: Support ordering SSDT data by device
  x86: Allow devices to write an SSDT
  acpi: Add support for DSDT generation
  x86: Allow devices to write to DSDT
  pci: Avoid a crash in device_is_on_pci_bus()
  dm: acpi: Enhance acpi_get_name()
  acpi: Add an acpi command to list/dump generated ACPI items
  binman: Allow setting the ROM offset
  binman: Refactor binman_entry_find() to allow other nodes
  binman: Add way to locate an entry in memory
  acpi: Allow creating the GNVS to fail
  dtoc: Support ACPI paths in of-platdata
  dm: core: Add a way of overriding the ACPI device path
  dm: acpi: Add support for the NHLT table
  acpi: Export functions to write sized values
  acpi: Support generation of a scope
  acpi: Support generation of a generic register
  acpi: mmc: Generate ACPI info for the PCI SD Card
  x86: Add bindings for NHLT
  acpi: Support generation of a device
  acpi: Support writing named values
  x86: Add support for building up an NHLT structure
  sound: Add an ACPI driver for Dialog Semicondutor da7219
  sound: Add an ACPI driver for Maxim MAX98357ac
  x86: pinctrl: Add a way to get the pinctrl reg address
  x86: pinctrl: Update comment for intel_pinctrl_get_pad()
  x86: pinctrl: Add multi-ACPI control
  x86: pinctrl: Set up itss in the probe() method
  x86: pinctrl: Drop the acpi_path member
  x86: Add error checking for csrt table generation
  x86: apl: Use memory-mapped access for VBT
  x86: gpio: Add support for obtaining ACPI info for a GPIO
  i2c: designware_i2c: Add a little more debugging
  i2c: Add log_ret() on error
  i2c: designware_i2c: Support ACPI table generation
  p2sb: Add a method to hide the bus
  x86: apl: Support set_hide() in p2sb driver
  x86: apl: Hide the p2sb on exit from U-Boot
  pmc: Move common registers to the header file
  x86: irq: Support flags for acpi_gpe
  x86: apl: Fix save/restore of ITSS priorities
  x86: Add debugging to table writing
  x86: apl: Set the correct boot mode in the FSP-M code
  x86: apl: Adjust FSP-M code to avoid hard-coded address
  x86: Store the coreboot table address in global_data
  x86: Update the comment about booting for FSP2
  x86: Drop setup_pcat_compatibility()
  x86: acpi: Correct the versi

Re: [PATCH v1 4/4] usb: xhci: Add virt_to_phys() to support mapped platforms

2020-07-17 Thread Stefan Roese

Hi Bin,

On 17.07.20 07:57, Bin Meng wrote:

Hi Stefan,

On Thu, Jul 2, 2020 at 4:47 PM Stefan Roese  wrote:


Some platforms, like MIPS Octeon, use mapped addresses (virtual address
!= physical address). On these platforms we need to make sure, that the
local virtual addresses are converted to physical (DMA) addresses for
the xHCI controller. This patch adds the missing virt_to_phys() calls,
so that the correct addresses are used.

Signed-off-by: Stefan Roese 
Cc: Bin Meng 
Cc: Marek Vasut 

---

  drivers/usb/host/xhci-mem.c  | 19 +--
  drivers/usb/host/xhci-ring.c |  8 
  drivers/usb/host/xhci.c  |  3 +--
  3 files changed, 14 insertions(+), 16 deletions(-)

diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 3b805ecb9e..874caf4761 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -224,7 +224,7 @@ static void xhci_link_segments(struct xhci_segment *prev,
 return;
 prev->next = next;
 if (link_trbs) {
-   val_64 = (uintptr_t)next->trbs;
+   val_64 = virt_to_phys(next->trbs);
 prev->trbs[TRBS_PER_SEGMENT-1].link.segment_ptr =
 cpu_to_le64(val_64);

@@ -484,7 +484,7 @@ int xhci_alloc_virt_device(struct xhci_ctrl *ctrl, unsigned 
int slot_id)
 /* Allocate endpoint 0 ring */
 virt_dev->eps[0].ring = xhci_ring_alloc(1, true);

-   byte_64 = (uintptr_t)(virt_dev->out_ctx->bytes);
+   byte_64 = virt_to_phys(virt_dev->out_ctx->bytes);

 /* Point to output device context in dcbaa. */
 ctrl->dcbaa->dev_context_ptrs[slot_id] = cpu_to_le64(byte_64);
@@ -509,7 +509,7 @@ int xhci_mem_init(struct xhci_ctrl *ctrl, struct xhci_hccr 
*hccr,
 uint64_t val_64;
 uint64_t trb_64;
 uint32_t val;
-   unsigned long deq;
+   uint64_t deq;


This change seems unnecessary?


In most (all other?) places, the variable containing these 64 bit
addresses has the type uint64_t in this driver. So I wanted to make the
code more consistant here. Or do you see a problem with this change?


 int i;
 struct xhci_segment *seg;

@@ -521,7 +521,7 @@ int xhci_mem_init(struct xhci_ctrl *ctrl, struct xhci_hccr 
*hccr,
 return -ENOMEM;
 }

-   val_64 = (uintptr_t)ctrl->dcbaa;
+   val_64 = virt_to_phys(ctrl->dcbaa);
 /* Set the pointer in DCBAA register */
 xhci_writeq(&hcor->or_dcbaap, val_64);

@@ -529,7 +529,7 @@ int xhci_mem_init(struct xhci_ctrl *ctrl, struct xhci_hccr 
*hccr,
 ctrl->cmd_ring = xhci_ring_alloc(1, true);

 /* Set the address in the Command Ring Control register */
-   trb_64 = (uintptr_t)ctrl->cmd_ring->first_seg->trbs;
+   trb_64 = virt_to_phys(ctrl->cmd_ring->first_seg->trbs);
 val_64 = xhci_readq(&hcor->or_crcr);
 val_64 = (val_64 & (u64) CMD_RING_RSVD_BITS) |
 (trb_64 & (u64) ~CMD_RING_RSVD_BITS) |
@@ -559,8 +559,7 @@ int xhci_mem_init(struct xhci_ctrl *ctrl, struct xhci_hccr 
*hccr,
 for (val = 0, seg = ctrl->event_ring->first_seg;
 val < ERST_NUM_SEGS;
 val++) {
-   trb_64 = 0;
-   trb_64 = (uintptr_t)seg->trbs;
+   trb_64 = virt_to_phys(seg->trbs);
 struct xhci_erst_entry *entry = &ctrl->erst.entries[val];
 entry->seg_addr = cpu_to_le64(trb_64);
 entry->seg_size = cpu_to_le32(TRBS_PER_SEGMENT);
@@ -570,7 +569,7 @@ int xhci_mem_init(struct xhci_ctrl *ctrl, struct xhci_hccr 
*hccr,
 xhci_flush_cache((uintptr_t)ctrl->erst.entries,
  ERST_NUM_SEGS * sizeof(struct xhci_erst_entry));

-   deq = (unsigned long)ctrl->event_ring->dequeue;
+   deq = virt_to_phys(ctrl->event_ring->dequeue);

 /* Update HC event ring dequeue pointer */
 xhci_writeq(&ctrl->ir_set->erst_dequeue,
@@ -585,7 +584,7 @@ int xhci_mem_init(struct xhci_ctrl *ctrl, struct xhci_hccr 
*hccr,
 /* this is the event ring segment table pointer */
 val_64 = xhci_readq(&ctrl->ir_set->erst_base);
 val_64 &= ERST_PTR_MASK;
-   val_64 |= ((uintptr_t)(ctrl->erst.entries) & ~ERST_PTR_MASK);
+   val_64 |= virt_to_phys(ctrl->erst.entries) & ~ERST_PTR_MASK;

 xhci_writeq(&ctrl->ir_set->erst_base, val_64);

@@ -853,7 +852,7 @@ void xhci_setup_addressable_virt_dev(struct xhci_ctrl *ctrl,
 cpu_to_le32(((0 & MAX_BURST_MASK) << MAX_BURST_SHIFT) |
 ((3 & ERROR_COUNT_MASK) << ERROR_COUNT_SHIFT));

-   trb_64 = (uintptr_t)virt_dev->eps[0].ring->first_seg->trbs;
+   trb_64 = virt_to_phys(virt_dev->eps[0].ring->first_seg->trbs);
 ep0_ctx->deq = cpu_to_le64(trb_64 | 
virt_dev->eps[0].ring->cycle_state);

 /*
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 86aeaab412..092ed6eaf1 100644
--- a/dri

[PATCH v4] arm: socfpga: add board support for ic-automation Moritz III

2020-07-17 Thread Nico Becker
add board support for the moritz III from ic-automation
 
Changes for v4:
- re-sort list alphabetically
- c style comments

Changes for v3:
 - Resend via git send-email

Changes for v2:
- Coding Style cleanup

Signed-off-by: Nico Becker 
---
 arch/arm/dts/Makefile |   1 +
 ...ocfpga_cyclone5_ica_moritz_iii-u-boot.dtsi |  45 ++
 .../dts/socfpga_cyclone5_ica_moritz_iii.dts   | 123 
 arch/arm/mach-socfpga/Kconfig |   8 +
 board/ic-automation/moritz_iii/MAINTAINERS|   8 +
 board/ic-automation/moritz_iii/Makefile   |   8 +
 .../moritz_iii/moritz_iii_board.c | 126 
 .../moritz_iii/qts/iocsr_config.h | 658 ++
 .../moritz_iii/qts/pinmux_config.h| 218 ++
 .../ic-automation/moritz_iii/qts/pll_config.h |  83 +++
 .../moritz_iii/qts/sdram_config.h | 344 +
 board/ic-automation/moritz_iii/socfpga.c  |   5 +
 configs/socfpga_moritz_iii_defconfig  |  74 ++
 include/configs/socfpga_ica_moritz_iii.h  |  46 ++
 14 files changed, 1747 insertions(+)
 create mode 100644 arch/arm/dts/socfpga_cyclone5_ica_moritz_iii-u-boot.dtsi
 create mode 100644 arch/arm/dts/socfpga_cyclone5_ica_moritz_iii.dts
 create mode 100644 board/ic-automation/moritz_iii/MAINTAINERS
 create mode 100644 board/ic-automation/moritz_iii/Makefile
 create mode 100644 board/ic-automation/moritz_iii/moritz_iii_board.c
 create mode 100644 board/ic-automation/moritz_iii/qts/iocsr_config.h
 create mode 100644 board/ic-automation/moritz_iii/qts/pinmux_config.h
 create mode 100644 board/ic-automation/moritz_iii/qts/pll_config.h
 create mode 100644 board/ic-automation/moritz_iii/qts/sdram_config.h
 create mode 100644 board/ic-automation/moritz_iii/socfpga.c
 create mode 100644 configs/socfpga_moritz_iii_defconfig
 create mode 100644 include/configs/socfpga_ica_moritz_iii.h

diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 9900b44274..6fbedfe3b3 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -352,6 +352,7 @@ dtb-$(CONFIG_ARCH_SOCFPGA) +=   
\
socfpga_cyclone5_de0_nano_soc.dtb   \
socfpga_cyclone5_de1_soc.dtb\
socfpga_cyclone5_de10_nano.dtb  \
+   socfpga_cyclone5_ica_moritz_iii.dtb \
socfpga_cyclone5_sockit.dtb \
socfpga_cyclone5_socrates.dtb   \
socfpga_cyclone5_sr1500.dtb \
diff --git a/arch/arm/dts/socfpga_cyclone5_ica_moritz_iii-u-boot.dtsi 
b/arch/arm/dts/socfpga_cyclone5_ica_moritz_iii-u-boot.dtsi
new file mode 100644
index 00..3ba01d1fd9
--- /dev/null
+++ b/arch/arm/dts/socfpga_cyclone5_ica_moritz_iii-u-boot.dtsi
@@ -0,0 +1,45 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * U-Boot additions
+ *
+ * Copyright (C) 2012 Altera Corporation 
+ * Copyright (c) 2018 Simon Goldschmidt
+ */
+
+#include "socfpga-common-u-boot.dtsi"
+
+/{
+   aliases {
+   spi0 = "/soc/spi@ff705000";
+   udc0 = &usb1;
+   };
+};
+
+&watchdog0 {
+   status = "disabled";
+};
+
+&mmc {
+   u-boot,dm-pre-reloc;
+};
+
+&qspi {
+   u-boot,dm-pre-reloc;
+};
+
+&uart0 {
+   clock-frequency = <1>;
+   u-boot,dm-pre-reloc;
+};
+
+&porta {
+   bank-name = "porta";
+};
+
+&portb {
+   bank-name = "portb";
+};
+
+&portc {
+   bank-name = "portc";
+};
diff --git a/arch/arm/dts/socfpga_cyclone5_ica_moritz_iii.dts 
b/arch/arm/dts/socfpga_cyclone5_ica_moritz_iii.dts
new file mode 100644
index 00..d81f8ea5bf
--- /dev/null
+++ b/arch/arm/dts/socfpga_cyclone5_ica_moritz_iii.dts
@@ -0,0 +1,123 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2012 Altera Corporation 
+ * Copyright (C) 2020 Nico Becker ic-automation GmbH 

+ */
+
+#include "socfpga_cyclone5.dtsi"
+
+/ {
+   model = "ic-automation Moritz III";
+   compatible = "ic-automation,moritz_iii", "altr,socfpga-cyclone5", 
"altr,socfpga";
+
+   chosen {
+   bootargs = "earlyprintk";
+   stdout-path = "serial0:115200n8";
+   };
+
+   memory@0 {
+   name = "memory";
+   device_type = "memory";
+   reg = <0x0 0x4000>; /* 1GB */
+   };
+
+   aliases {
+   /* this allow the ethaddr uboot environmnet variable contents
+* to be added to the gmac1 device tree blob.
+*/
+   ethernet0 = &gmac1;
+   };
+
+  fpga_bridge3: fpga_bridge@ffc25080 {
+   compatible = "altr,socfpga-fpga2sdram-bridge";
+   reg = <0xffc25080 0x4>;
+   };
+
+   regulator_3_3v: 3-3-v-regulator {
+   compatible = "regulator-fixed";
+   regulator-name = "3.3V";
+   regulator-min-microvolt = <330>;
+   regulator-max-microvolt = <330>;
+   };
+};
+
+&gmac1 

Re: [PATCH v1 4/4] usb: xhci: Add virt_to_phys() to support mapped platforms

2020-07-17 Thread Bin Meng
Hi Stefan,

On Fri, Jul 17, 2020 at 6:17 PM Stefan Roese  wrote:
>
> Hi Bin,
>
> On 17.07.20 07:57, Bin Meng wrote:
> > Hi Stefan,
> >
> > On Thu, Jul 2, 2020 at 4:47 PM Stefan Roese  wrote:
> >>
> >> Some platforms, like MIPS Octeon, use mapped addresses (virtual address
> >> != physical address). On these platforms we need to make sure, that the
> >> local virtual addresses are converted to physical (DMA) addresses for
> >> the xHCI controller. This patch adds the missing virt_to_phys() calls,
> >> so that the correct addresses are used.
> >>
> >> Signed-off-by: Stefan Roese 
> >> Cc: Bin Meng 
> >> Cc: Marek Vasut 
> >>
> >> ---
> >>
> >>   drivers/usb/host/xhci-mem.c  | 19 +--
> >>   drivers/usb/host/xhci-ring.c |  8 
> >>   drivers/usb/host/xhci.c  |  3 +--
> >>   3 files changed, 14 insertions(+), 16 deletions(-)
> >>
> >> diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
> >> index 3b805ecb9e..874caf4761 100644
> >> --- a/drivers/usb/host/xhci-mem.c
> >> +++ b/drivers/usb/host/xhci-mem.c
> >> @@ -224,7 +224,7 @@ static void xhci_link_segments(struct xhci_segment 
> >> *prev,
> >>  return;
> >>  prev->next = next;
> >>  if (link_trbs) {
> >> -   val_64 = (uintptr_t)next->trbs;
> >> +   val_64 = virt_to_phys(next->trbs);
> >>  prev->trbs[TRBS_PER_SEGMENT-1].link.segment_ptr =
> >>  cpu_to_le64(val_64);
> >>
> >> @@ -484,7 +484,7 @@ int xhci_alloc_virt_device(struct xhci_ctrl *ctrl, 
> >> unsigned int slot_id)
> >>  /* Allocate endpoint 0 ring */
> >>  virt_dev->eps[0].ring = xhci_ring_alloc(1, true);
> >>
> >> -   byte_64 = (uintptr_t)(virt_dev->out_ctx->bytes);
> >> +   byte_64 = virt_to_phys(virt_dev->out_ctx->bytes);
> >>
> >>  /* Point to output device context in dcbaa. */
> >>  ctrl->dcbaa->dev_context_ptrs[slot_id] = cpu_to_le64(byte_64);
> >> @@ -509,7 +509,7 @@ int xhci_mem_init(struct xhci_ctrl *ctrl, struct 
> >> xhci_hccr *hccr,
> >>  uint64_t val_64;
> >>  uint64_t trb_64;
> >>  uint32_t val;
> >> -   unsigned long deq;
> >> +   uint64_t deq;
> >
> > This change seems unnecessary?
>
> In most (all other?) places, the variable containing these 64 bit
> addresses has the type uint64_t in this driver. So I wanted to make the
> code more consistant here. Or do you see a problem with this change?

No, just wondering if you see something is wrong with (unsigned long)
on a 32-bit platform.

Regards,
Bin


Re: [PATCH v4 6/7] efi_loader: signature: rework for intermediate certificates support

2020-07-17 Thread Heinrich Schuchardt
On 17.07.20 09:16, AKASHI Takahiro wrote:
> In this commit, efi_signature_verify(with_sigdb) will be re-implemented
> using pcks7_verify_one() in order to support certificates chain, where
> the signer's certificate will be signed by an intermediate CA (certificate
> authority) and the latter's certificate will also be signed by another CA
> and so on.
>
> What we need to do here is to search for certificates in a signature,
> build up a chain of certificates and verify one by one. pkcs7_verify_one()
> handles most of these steps except the last one.
>
> pkcs7_verify_one() returns, if succeeded, the last certificate to verify,
> which can be either a self-signed one or one that should be signed by one
> of certificates in "db". Re-worked efi_signature_verify() will take care
> of this step.
>
> Signed-off-by: AKASHI Takahiro 
> ---

With patches 1-6 applied to origin/master (fee68b98fe3890):

make tests:

test/py/tests/test_efi_secboot/test_authvar.py F
test/py/tests/test_efi_secboot/test_signed.py .F..FF
test/py/tests/test_efi_secboot/test_unsigned.py ...

Patches 1-5 pass the test.

Best regards

Heinrich


Re: [PATCH v1 4/4] usb: xhci: Add virt_to_phys() to support mapped platforms

2020-07-17 Thread Stefan Roese

Hi Bin,

On 17.07.20 12:23, Bin Meng wrote:

Hi Stefan,

On Fri, Jul 17, 2020 at 6:17 PM Stefan Roese  wrote:


Hi Bin,

On 17.07.20 07:57, Bin Meng wrote:

Hi Stefan,

On Thu, Jul 2, 2020 at 4:47 PM Stefan Roese  wrote:


Some platforms, like MIPS Octeon, use mapped addresses (virtual address
!= physical address). On these platforms we need to make sure, that the
local virtual addresses are converted to physical (DMA) addresses for
the xHCI controller. This patch adds the missing virt_to_phys() calls,
so that the correct addresses are used.

Signed-off-by: Stefan Roese 
Cc: Bin Meng 
Cc: Marek Vasut 

---

   drivers/usb/host/xhci-mem.c  | 19 +--
   drivers/usb/host/xhci-ring.c |  8 
   drivers/usb/host/xhci.c  |  3 +--
   3 files changed, 14 insertions(+), 16 deletions(-)

diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 3b805ecb9e..874caf4761 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -224,7 +224,7 @@ static void xhci_link_segments(struct xhci_segment *prev,
  return;
  prev->next = next;
  if (link_trbs) {
-   val_64 = (uintptr_t)next->trbs;
+   val_64 = virt_to_phys(next->trbs);
  prev->trbs[TRBS_PER_SEGMENT-1].link.segment_ptr =
  cpu_to_le64(val_64);

@@ -484,7 +484,7 @@ int xhci_alloc_virt_device(struct xhci_ctrl *ctrl, unsigned 
int slot_id)
  /* Allocate endpoint 0 ring */
  virt_dev->eps[0].ring = xhci_ring_alloc(1, true);

-   byte_64 = (uintptr_t)(virt_dev->out_ctx->bytes);
+   byte_64 = virt_to_phys(virt_dev->out_ctx->bytes);

  /* Point to output device context in dcbaa. */
  ctrl->dcbaa->dev_context_ptrs[slot_id] = cpu_to_le64(byte_64);
@@ -509,7 +509,7 @@ int xhci_mem_init(struct xhci_ctrl *ctrl, struct xhci_hccr 
*hccr,
  uint64_t val_64;
  uint64_t trb_64;
  uint32_t val;
-   unsigned long deq;
+   uint64_t deq;


This change seems unnecessary?


In most (all other?) places, the variable containing these 64 bit
addresses has the type uint64_t in this driver. So I wanted to make the
code more consistant here. Or do you see a problem with this change?


No, just wondering if you see something is wrong with (unsigned long)
on a 32-bit platform.


I see. Thanks for checking.

Do you have a (little-endian) platform that you could use to test this
patchset on? I currently do not have such a board on my desk and would
very much like to see it tested on little-endian systems before being
applied.

Thanks,
Stefan


Re: [PATCH v4 7/7] test/py: efi_secboot: add test for intermediate certificates

2020-07-17 Thread Heinrich Schuchardt
On 17.07.20 09:16, AKASHI Takahiro wrote:
> In this test case, an image may have a signature with additional
> intermediate certificates. A chain of trust will be followed and all
> the certificates in the middle of chain must be verified before loading.
>
> Signed-off-by: AKASHI Takahiro 

Thanks for providing all these tests and for rebasing on 53ce9a6ed98b6
("test: use virt-make-fs to build image").

Essentially this patch could have been split into two:

* style corrections for existing code
* new tests

Unfortunatly the setup not working correctly. 'make tests' shows:

test/py/tests/test_efi_secboot/test_authvar.py F
test/py/tests/test_efi_secboot/test_signed.py .F..FF
test/py/tests/test_efi_secboot/test_signed_intca.py sss
test/py/tests/test_efi_secboot/test_unsigned.py ...

SKIPPED [3] test/py/tests/test_efi_secboot/conftest.py:254: Setup
failed: cd build-sandbox/mnt_efisecure; sbsign --key TestCert.key --cert
TestCert.crt --addcert TestSub.crt --out helloworld.efi.signed_ab
helloworld.efi

If you replace as follows in test/run you get the extra skip messages:

%s/--bd/-ra --bd/g

> ---
>  test/py/tests/test_efi_secboot/conftest.py| 134 -
>  test/py/tests/test_efi_secboot/defs.py|   8 +-
>  test/py/tests/test_efi_secboot/openssl.cnf|  48 +++
>  .../test_efi_secboot/test_signed_intca.py | 135 ++
>  4 files changed, 317 insertions(+), 8 deletions(-)
>  create mode 100644 test/py/tests/test_efi_secboot/openssl.cnf
>  create mode 100644 test/py/tests/test_efi_secboot/test_signed_intca.py
>
> diff --git a/test/py/tests/test_efi_secboot/conftest.py 
> b/test/py/tests/test_efi_secboot/conftest.py
> index c6709700a876..20d0cbf3ab01 100644
> --- a/test/py/tests/test_efi_secboot/conftest.py
> +++ b/test/py/tests/test_efi_secboot/conftest.py
> @@ -37,7 +37,7 @@ def efi_boot_env(request, u_boot_config):
>  global HELLO_PATH
>
>  image_path = u_boot_config.persistent_data_dir
> -image_path = image_path + '/' + EFI_SECBOOT_IMAGE_NAME
> +image_path = image_path + '/' + EFI_SECBOOT_IMAGE_NAME + '.img'

I would prefer a separate constant for
EFI_SECBOOT_IMAGE_NAME + '_intca.img'
to ensure that conftest.py and test_signed_intca.py use the same value.

>
>  if HELLO_PATH == '':

Shouldn't we set HELLO_PATH = 'lib/efi_loader/helloworld.efi' in defs.py
and use another variable name here?

bin_path = u_boot_config.build_dir + '/' + HELLO_PATH

>  HELLO_PATH = u_boot_config.build_dir + 
> '/lib/efi_loader/helloworld.efi'

Capitalization should only be used for constants.

Best regards

Heinrich

> @@ -87,21 +87,21 @@ def efi_boot_env(request, u_boot_config):
>  # db1-update
>  check_call('cd %s; %ssign-efi-sig-list -t "2020-04-06" -a -c KEK.crt 
> -k KEK.key db db1.esl db1-update.auth'
> % (mnt_point, EFITOOLS_PATH), shell=True)
> -## dbx (TEST_dbx certificate)
> +# dbx (TEST_dbx certificate)
>  check_call('cd %s; openssl req -x509 -sha256 -newkey rsa:2048 -subj 
> /CN=TEST_dbx/ -keyout dbx.key -out dbx.crt -nodes -days 365'
> % mnt_point, shell=True)
>  check_call('cd %s; %scert-to-efi-sig-list -g %s dbx.crt dbx.esl; 
> %ssign-efi-sig-list -t "2020-04-05" -c KEK.crt -k KEK.key dbx dbx.esl 
> dbx.auth'
> % (mnt_point, EFITOOLS_PATH, GUID, EFITOOLS_PATH),
> shell=True)
> -## dbx_hash (digest of TEST_db certificate)
> +# dbx_hash (digest of TEST_db certificate)
>  check_call('cd %s; %scert-to-efi-hash-list -g %s -t 0 -s 256 db.crt 
> dbx_hash.crl; %ssign-efi-sig-list -t "2020-04-05" -c KEK.crt -k KEK.key dbx 
> dbx_hash.crl dbx_hash.auth'
> % (mnt_point, EFITOOLS_PATH, GUID, EFITOOLS_PATH),
> shell=True)
> -## dbx_hash1 (digest of TEST_db1 certificate)
> +# dbx_hash1 (digest of TEST_db1 certificate)
>  check_call('cd %s; %scert-to-efi-hash-list -g %s -t 0 -s 256 db1.crt 
> dbx_hash1.crl; %ssign-efi-sig-list -t "2020-04-05" -c KEK.crt -k KEK.key dbx 
> dbx_hash1.crl dbx_hash1.auth'
> % (mnt_point, EFITOOLS_PATH, GUID, EFITOOLS_PATH),
> shell=True)
> -## dbx_db (with TEST_db certificate)
> +# dbx_db (with TEST_db certificate)
>  check_call('cd %s; %ssign-efi-sig-list -t "2020-04-05" -c KEK.crt -k 
> KEK.key dbx db.esl dbx_db.auth'
> % (mnt_point, EFITOOLS_PATH),
> shell=True)
> @@ -112,10 +112,10 @@ def efi_boot_env(request, u_boot_config):
>  # Sign image
>  check_call('cd %s; sbsign --key db.key --cert db.crt helloworld.efi'
> % mnt_point, shell=True)
> -## Sign already-signed image with another key
> +# Sign already-signed image with another key
>  check_call('cd %s; sbsign --key db1.key --cert db1.crt --output 
> helloworld.efi.signed_2sigs helloworld.efi.signed'

Re: [PATCH v1 4/4] usb: xhci: Add virt_to_phys() to support mapped platforms

2020-07-17 Thread Bin Meng
Hi Stefan,

On Fri, Jul 17, 2020 at 6:28 PM Stefan Roese  wrote:
>
> Hi Bin,
>
> On 17.07.20 12:23, Bin Meng wrote:
> > Hi Stefan,
> >
> > On Fri, Jul 17, 2020 at 6:17 PM Stefan Roese  wrote:
> >>
> >> Hi Bin,
> >>
> >> On 17.07.20 07:57, Bin Meng wrote:
> >>> Hi Stefan,
> >>>
> >>> On Thu, Jul 2, 2020 at 4:47 PM Stefan Roese  wrote:
> 
>  Some platforms, like MIPS Octeon, use mapped addresses (virtual address
>  != physical address). On these platforms we need to make sure, that the
>  local virtual addresses are converted to physical (DMA) addresses for
>  the xHCI controller. This patch adds the missing virt_to_phys() calls,
>  so that the correct addresses are used.
> 
>  Signed-off-by: Stefan Roese 
>  Cc: Bin Meng 
>  Cc: Marek Vasut 
> 
>  ---
> 
> drivers/usb/host/xhci-mem.c  | 19 +--
> drivers/usb/host/xhci-ring.c |  8 
> drivers/usb/host/xhci.c  |  3 +--
> 3 files changed, 14 insertions(+), 16 deletions(-)
> 
>  diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
>  index 3b805ecb9e..874caf4761 100644
>  --- a/drivers/usb/host/xhci-mem.c
>  +++ b/drivers/usb/host/xhci-mem.c
>  @@ -224,7 +224,7 @@ static void xhci_link_segments(struct xhci_segment 
>  *prev,
>    return;
>    prev->next = next;
>    if (link_trbs) {
>  -   val_64 = (uintptr_t)next->trbs;
>  +   val_64 = virt_to_phys(next->trbs);
>    prev->trbs[TRBS_PER_SEGMENT-1].link.segment_ptr =
>    cpu_to_le64(val_64);
> 
>  @@ -484,7 +484,7 @@ int xhci_alloc_virt_device(struct xhci_ctrl *ctrl, 
>  unsigned int slot_id)
>    /* Allocate endpoint 0 ring */
>    virt_dev->eps[0].ring = xhci_ring_alloc(1, true);
> 
>  -   byte_64 = (uintptr_t)(virt_dev->out_ctx->bytes);
>  +   byte_64 = virt_to_phys(virt_dev->out_ctx->bytes);
> 
>    /* Point to output device context in dcbaa. */
>    ctrl->dcbaa->dev_context_ptrs[slot_id] = cpu_to_le64(byte_64);
>  @@ -509,7 +509,7 @@ int xhci_mem_init(struct xhci_ctrl *ctrl, struct 
>  xhci_hccr *hccr,
>    uint64_t val_64;
>    uint64_t trb_64;
>    uint32_t val;
>  -   unsigned long deq;
>  +   uint64_t deq;
> >>>
> >>> This change seems unnecessary?
> >>
> >> In most (all other?) places, the variable containing these 64 bit
> >> addresses has the type uint64_t in this driver. So I wanted to make the
> >> code more consistant here. Or do you see a problem with this change?
> >
> > No, just wondering if you see something is wrong with (unsigned long)
> > on a 32-bit platform.
>
> I see. Thanks for checking.
>
> Do you have a (little-endian) platform that you could use to test this
> patchset on? I currently do not have such a board on my desk and would
> very much like to see it tested on little-endian systems before being
> applied.

Yes, I can test this series on x86 Minnowmax. Will send results then.

Regards,
Bin


Re: [PATCH v2] efi_loader: Rename and correct values for ARM_SMC_MM_*

2020-07-17 Thread Heinrich Schuchardt
On 17.07.20 06:55, Ilias Apalodimas wrote:
> Instead of adding the definition for the specific MM SVC used in
> StandAloneMM we added the one used in the standard SMC calls.
> So change the value from -4 to -5 to match the correct one defined in
> EDK2 and rename them to avoid future confusion
>
> Fixes 23a397d2e2fb: ("efi_loader: Add headers for EDK2 StandAloneMM 
> communication")> Signed-off-by: Ilias Apalodimas 

Reviewed-by: Heinrich Schuchardt 


Re: [PATCH v1 4/4] usb: xhci: Add virt_to_phys() to support mapped platforms

2020-07-17 Thread Stefan Roese

Hi Bin,

On 17.07.20 12:29, Bin Meng wrote:

Hi Stefan,

On Fri, Jul 17, 2020 at 6:28 PM Stefan Roese  wrote:


Hi Bin,

On 17.07.20 12:23, Bin Meng wrote:

Hi Stefan,

On Fri, Jul 17, 2020 at 6:17 PM Stefan Roese  wrote:


Hi Bin,

On 17.07.20 07:57, Bin Meng wrote:

Hi Stefan,

On Thu, Jul 2, 2020 at 4:47 PM Stefan Roese  wrote:


Some platforms, like MIPS Octeon, use mapped addresses (virtual address
!= physical address). On these platforms we need to make sure, that the
local virtual addresses are converted to physical (DMA) addresses for
the xHCI controller. This patch adds the missing virt_to_phys() calls,
so that the correct addresses are used.

Signed-off-by: Stefan Roese 
Cc: Bin Meng 
Cc: Marek Vasut 

---

drivers/usb/host/xhci-mem.c  | 19 +--
drivers/usb/host/xhci-ring.c |  8 
drivers/usb/host/xhci.c  |  3 +--
3 files changed, 14 insertions(+), 16 deletions(-)

diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 3b805ecb9e..874caf4761 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -224,7 +224,7 @@ static void xhci_link_segments(struct xhci_segment *prev,
   return;
   prev->next = next;
   if (link_trbs) {
-   val_64 = (uintptr_t)next->trbs;
+   val_64 = virt_to_phys(next->trbs);
   prev->trbs[TRBS_PER_SEGMENT-1].link.segment_ptr =
   cpu_to_le64(val_64);

@@ -484,7 +484,7 @@ int xhci_alloc_virt_device(struct xhci_ctrl *ctrl, unsigned 
int slot_id)
   /* Allocate endpoint 0 ring */
   virt_dev->eps[0].ring = xhci_ring_alloc(1, true);

-   byte_64 = (uintptr_t)(virt_dev->out_ctx->bytes);
+   byte_64 = virt_to_phys(virt_dev->out_ctx->bytes);

   /* Point to output device context in dcbaa. */
   ctrl->dcbaa->dev_context_ptrs[slot_id] = cpu_to_le64(byte_64);
@@ -509,7 +509,7 @@ int xhci_mem_init(struct xhci_ctrl *ctrl, struct xhci_hccr 
*hccr,
   uint64_t val_64;
   uint64_t trb_64;
   uint32_t val;
-   unsigned long deq;
+   uint64_t deq;


This change seems unnecessary?


In most (all other?) places, the variable containing these 64 bit
addresses has the type uint64_t in this driver. So I wanted to make the
code more consistant here. Or do you see a problem with this change?


No, just wondering if you see something is wrong with (unsigned long)
on a 32-bit platform.


I see. Thanks for checking.

Do you have a (little-endian) platform that you could use to test this
patchset on? I currently do not have such a board on my desk and would
very much like to see it tested on little-endian systems before being
applied.


Yes, I can test this series on x86 Minnowmax. Will send results then.


Thanks a lot.

Thanks,
Stefan


Re: [PATCH v1 1/4] usb: xhci: Add missing endian conversions (cpu_to_leXX / leXX_to_cpu)

2020-07-17 Thread Bin Meng
Hi Stefan,

On Thu, Jul 2, 2020 at 4:47 PM Stefan Roese  wrote:
>
> While trying to use the U-Boot xHCI driver on the MIPS Octeon platform,
> which is big endian, I noticed that the driver is missing a few endian
> conversion calls. This patch adds these missing endian conversion
> calls.
>
> Signed-off-by: Stefan Roese 
> Cc: Bin Meng 
> Cc: Marek Vasut 
> ---
>
>  drivers/usb/host/xhci-mem.c | 9 +
>  1 file changed, 5 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
> index 2d968aafb0..bd959b4093 100644
> --- a/drivers/usb/host/xhci-mem.c
> +++ b/drivers/usb/host/xhci-mem.c
> @@ -110,7 +110,7 @@ static void xhci_scratchpad_free(struct xhci_ctrl *ctrl)
>
> ctrl->dcbaa->dev_context_ptrs[0] = 0;
>
> -   free((void *)(uintptr_t)ctrl->scratchpad->sp_array[0]);
> +   free((void *)le64_to_cpu(ctrl->scratchpad->sp_array[0]));

There is a build warning for this:

drivers/usb/host/xhci-mem.c: In function 'xhci_scratchpad_free':
drivers/usb/host/xhci-mem.c:113:7: warning: cast to pointer from
integer of different size [-Wint-to-pointer-cast]
  free((void *)le64_to_cpu(ctrl->scratchpad->sp_array[0]));
   ^

> free(ctrl->scratchpad->sp_array);
> free(ctrl->scratchpad);
> ctrl->scratchpad = NULL;
> @@ -225,7 +225,8 @@ static void xhci_link_segments(struct xhci_segment *prev,
> prev->next = next;
> if (link_trbs) {
> val_64 = (uintptr_t)next->trbs;
> -   prev->trbs[TRBS_PER_SEGMENT-1].link.segment_ptr = val_64;
> +   prev->trbs[TRBS_PER_SEGMENT-1].link.segment_ptr =
> +   cpu_to_le64(val_64);
>
> /*
>  * Set the last TRB in the segment to
> @@ -486,7 +487,7 @@ int xhci_alloc_virt_device(struct xhci_ctrl *ctrl, 
> unsigned int slot_id)
> byte_64 = (uintptr_t)(virt_dev->out_ctx->bytes);
>
> /* Point to output device context in dcbaa. */
> -   ctrl->dcbaa->dev_context_ptrs[slot_id] = byte_64;
> +   ctrl->dcbaa->dev_context_ptrs[slot_id] = cpu_to_le64(byte_64);
>
> xhci_flush_cache((uintptr_t)&ctrl->dcbaa->dev_context_ptrs[slot_id],
>  sizeof(__le64));
> @@ -768,7 +769,7 @@ void xhci_setup_addressable_virt_dev(struct xhci_ctrl 
> *ctrl,
>
> debug("route string %x\n", route);
>  #endif
> -   slot_ctx->dev_info |= route;
> +   slot_ctx->dev_info |= cpu_to_le32(route);
>
> switch (speed) {
> case USB_SPEED_SUPER:
> --

Test results on Minnowmax which has one USB 2.0 port and one 3.0 port:

USB 2.0 flash drive inserted to USB 2.0 port: recognized, read/write OK
USB 2.0 flash drive inserted to USB 3.0 port: recognized, read/write OK

USB 3.0 flash drive inserted to USB 2.0 port: recognized, read/write OK
USB 3.0 flash drive inserted to USB 3.0 port: recognized, read/write OK

USB 2.0 flash drive connected to a USB 3.0 HUB inserted to USB 2.0
port: recognized, read/write OK
USB 2.0 flash drive connected to a USB 3.0 HUB inserted to USB 3.0
port: recognized, read/write OK

USB 3.0 flash drive connected to a USB 3.0 HUB inserted to USB 2.0
port: recognized, read/write OK
USB 3.0 flash drive connected to a USB 3.0 HUB inserted to USB 3.0
port: recognized, read/write OK

Tested-by: Bin Meng 

Regards,
Bin


Re: [PATCH v1 3/4] usb: usb-uclass.c: Drop le16_to_cpu() as values are already swapped

2020-07-17 Thread Bin Meng
On Thu, Jul 2, 2020 at 4:47 PM Stefan Roese  wrote:
>
> These values are already swapped to CPU endianess, so swapping them
> again is a bug. Let's remove the swap here instead.
>
> Signed-off-by: Stefan Roese 
> Cc: Bin Meng 
> Cc: Marek Vasut 
> ---
>
>  drivers/usb/host/usb-uclass.c | 8 
>  1 file changed, 4 insertions(+), 4 deletions(-)
>

Tested-by: Bin Meng 


Re: [PATCH v1 2/4] usb: xhci: xhci_mem_init: Use cpu_to_le64() and not xhci_writeq()

2020-07-17 Thread Bin Meng
On Thu, Jul 2, 2020 at 4:47 PM Stefan Roese  wrote:
>
> xhci_writeq() makes the CPU->LE swapping only when addressing registers
> in the xHCI controller address range and not in the local memory (RAM).
> We need to use cpu_to_le64() here to ensure that the conversion is done
> correctly.
>
> Signed-off-by: Stefan Roese 
> Cc: Bin Meng 
> Cc: Marek Vasut 
> ---
>
>  drivers/usb/host/xhci-mem.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>

Tested-by: Bin Meng 


Re: [PATCH v1 4/4] usb: xhci: Add virt_to_phys() to support mapped platforms

2020-07-17 Thread Bin Meng
On Thu, Jul 2, 2020 at 4:47 PM Stefan Roese  wrote:
>
> Some platforms, like MIPS Octeon, use mapped addresses (virtual address
> != physical address). On these platforms we need to make sure, that the
> local virtual addresses are converted to physical (DMA) addresses for
> the xHCI controller. This patch adds the missing virt_to_phys() calls,
> so that the correct addresses are used.
>
> Signed-off-by: Stefan Roese 
> Cc: Bin Meng 
> Cc: Marek Vasut 
>
> ---
>
>  drivers/usb/host/xhci-mem.c  | 19 +--
>  drivers/usb/host/xhci-ring.c |  8 
>  drivers/usb/host/xhci.c  |  3 +--
>  3 files changed, 14 insertions(+), 16 deletions(-)
>

Tested-by: Bin Meng 


[PATCH 2/3] mkimage: fit: handle FDT_ERR_NOSPACE when ciphering

2020-07-17 Thread patrick . oppenlander
From: Patrick Oppenlander 

This meant that the order of operations had to change. If we replace the
data property first then fail to add the data-size-unciphered property
the data will be ciphered again when retrying.

Signed-off-by: Patrick Oppenlander 
---
 tools/image-host.c | 19 ++-
 1 file changed, 10 insertions(+), 9 deletions(-)

diff --git a/tools/image-host.c b/tools/image-host.c
index 8fa1b9aba7..87ef79ef53 100644
--- a/tools/image-host.c
+++ b/tools/image-host.c
@@ -399,25 +399,26 @@ int fit_image_write_cipher(void *fit, int image_noffset, 
int noffset,
 {
int ret = -1;
 
-   /* Remove unciphered data */
-   ret = fdt_delprop(fit, image_noffset, FIT_DATA_PROP);
+   /* add non ciphered data size */
+   ret = fdt_setprop_u32(fit, image_noffset, "data-size-unciphered", size);
+   if (ret == -FDT_ERR_NOSPACE) {
+   ret = -ENOSPC;
+   goto out;
+   }
if (ret) {
-   printf("Can't remove data (err = %d)\n", ret);
+   printf("Can't add unciphered data size (err = %d)\n", ret);
goto out;
}
 
/* Add ciphered data */
ret = fdt_setprop(fit, image_noffset, FIT_DATA_PROP,
  data_ciphered, data_ciphered_len);
-   if (ret) {
-   printf("Can't add ciphered data (err = %d)\n", ret);
+   if (ret == -FDT_ERR_NOSPACE) {
+   ret = -ENOSPC;
goto out;
}
-
-   /* add non ciphered data size */
-   ret = fdt_setprop_u32(fit, image_noffset, "data-size-unciphered", size);
if (ret) {
-   printf("Can't add unciphered data size (err = %d)\n", ret);
+   printf("Can't add ciphered data (err = %d)\n", ret);
goto out;
}
 
-- 
2.27.0



[PATCH 1/3] mkimage: fit: only process one cipher node

2020-07-17 Thread patrick . oppenlander
From: Patrick Oppenlander 

Previously mkimage would process any node matching the regex cipher.*
and apply the ciphers to the image data in the order they appeared in
the FDT. This meant that data could be inadvertently ciphered multiple
times.

Switch to processing a single cipher node which exactly matches
FIT_CIPHER_NODENAME.

Signed-off-by: Patrick Oppenlander 
---
 tools/image-host.c | 56 +-
 1 file changed, 21 insertions(+), 35 deletions(-)

diff --git a/tools/image-host.c b/tools/image-host.c
index 9a83b7f675..8fa1b9aba7 100644
--- a/tools/image-host.c
+++ b/tools/image-host.c
@@ -323,15 +323,15 @@ err:
 static int fit_image_setup_cipher(struct image_cipher_info *info,
  const char *keydir, void *fit,
  const char *image_name, int image_noffset,
- const char *node_name, int noffset)
+ int noffset)
 {
char *algo_name;
char filename[128];
int ret = -1;
 
if (fit_image_cipher_get_algo(fit, noffset, &algo_name)) {
-   printf("Can't get algo name for cipher '%s' in image '%s'\n",
-  node_name, image_name);
+   printf("Can't get algo name for cipher in image '%s'\n",
+  image_name);
goto out;
}
 
@@ -340,16 +340,16 @@ static int fit_image_setup_cipher(struct 
image_cipher_info *info,
/* Read the key name */
info->keyname = fdt_getprop(fit, noffset, FIT_KEY_HINT, NULL);
if (!info->keyname) {
-   printf("Can't get key name for cipher '%s' in image '%s'\n",
-  node_name, image_name);
+   printf("Can't get key name for cipher in image '%s'\n",
+  image_name);
goto out;
}
 
/* Read the IV name */
info->ivname = fdt_getprop(fit, noffset, "iv-name-hint", NULL);
if (!info->ivname) {
-   printf("Can't get iv name for cipher '%s' in image '%s'\n",
-  node_name, image_name);
+   printf("Can't get iv name for cipher in image '%s'\n",
+  image_name);
goto out;
}
 
@@ -428,8 +428,7 @@ int fit_image_write_cipher(void *fit, int image_noffset, 
int noffset,
 static int
 fit_image_process_cipher(const char *keydir, void *keydest, void *fit,
 const char *image_name, int image_noffset,
-const char *node_name, int node_noffset,
-const void *data, size_t size,
+int node_noffset, const void *data, size_t size,
 const char *cmdname)
 {
struct image_cipher_info info;
@@ -440,7 +439,7 @@ fit_image_process_cipher(const char *keydir, void *keydest, 
void *fit,
memset(&info, 0, sizeof(info));
 
ret = fit_image_setup_cipher(&info, keydir, fit, image_name,
-image_noffset, node_name, node_noffset);
+image_noffset, node_noffset);
if (ret)
goto out;
 
@@ -482,7 +481,7 @@ int fit_image_cipher_data(const char *keydir, void *keydest,
const char *image_name;
const void *data;
size_t size;
-   int node_noffset;
+   int cipher_node_offset;
 
/* Get image name */
image_name = fit_get_name(fit, image_noffset, NULL);
@@ -497,32 +496,19 @@ int fit_image_cipher_data(const char *keydir, void 
*keydest,
return -1;
}
 
-   /* Process all hash subnodes of the component image node */
-   for (node_noffset = fdt_first_subnode(fit, image_noffset);
-node_noffset >= 0;
-node_noffset = fdt_next_subnode(fit, node_noffset)) {
-   const char *node_name;
-   int ret = 0;
-
-   node_name = fit_get_name(fit, node_noffset, NULL);
-   if (!node_name) {
-   printf("Can't get node name\n");
-   return -1;
-   }
 
-   if (IMAGE_ENABLE_ENCRYPT && keydir &&
-   !strncmp(node_name, FIT_CIPHER_NODENAME,
-strlen(FIT_CIPHER_NODENAME)))
-   ret = fit_image_process_cipher(keydir, keydest,
-  fit, image_name,
-  image_noffset,
-  node_name, node_noffset,
-  data, size, cmdname);
-   if (ret)
-   return ret;
+   /* Process cipher node if present */
+   cipher_node_offset = fdt_subnode_offset(fit, image_noffset, "cipher");
+   if (cipher_node_offset == -FDT_ERR_NOTFOUND)
+   return 0;
+   if (cipher_n

[PATCH 3/3] mkimage: fit: don't cipher ciphered data

2020-07-17 Thread patrick . oppenlander
From: Patrick Oppenlander 

Previously, mkimage -F could be run multiple times causing already
ciphered image data to be ciphered again.

Signed-off-by: Patrick Oppenlander 
---
 tools/image-host.c | 47 +++---
 1 file changed, 32 insertions(+), 15 deletions(-)

diff --git a/tools/image-host.c b/tools/image-host.c
index 87ef79ef53..12de9b5ec0 100644
--- a/tools/image-host.c
+++ b/tools/image-host.c
@@ -397,33 +397,43 @@ int fit_image_write_cipher(void *fit, int image_noffset, 
int noffset,
   const void *data, size_t size,
   unsigned char *data_ciphered, int data_ciphered_len)
 {
-   int ret = -1;
+   /*
+* fit_image_cipher_data() uses the presence of the data-size-unciphered
+* property as a sentinel to detect whether the data for this image is
+* already encrypted. This is important as:
+* - 'mkimage -F' can be run multiple times on a FIT image
+* - This function is in a retry loop to handle ENOSPC
+*/
 
-   /* add non ciphered data size */
+   int ret;
+
+   /* Add unciphered data size */
ret = fdt_setprop_u32(fit, image_noffset, "data-size-unciphered", size);
-   if (ret == -FDT_ERR_NOSPACE) {
-   ret = -ENOSPC;
-   goto out;
-   }
+   if (ret == -FDT_ERR_NOSPACE)
+   return -ENOSPC;
if (ret) {
printf("Can't add unciphered data size (err = %d)\n", ret);
-   goto out;
+   return -EIO;
}
 
-   /* Add ciphered data */
+   /* Replace contents of data property with data_ciphered */
ret = fdt_setprop(fit, image_noffset, FIT_DATA_PROP,
  data_ciphered, data_ciphered_len);
if (ret == -FDT_ERR_NOSPACE) {
-   ret = -ENOSPC;
-   goto out;
+   /* Remove data-size-unciphered; data is not ciphered */
+   ret = fdt_delprop(fit, image_noffset, "data-size-unciphered");
+   if (ret) {
+   printf("Can't remove unciphered data size (err = 
%d)\n", ret);
+   return -EIO;
+   }
+   return -ENOSPC;
}
if (ret) {
-   printf("Can't add ciphered data (err = %d)\n", ret);
-   goto out;
+   printf("Can't replace data with ciphered data (err = %d)\n", 
ret);
+   return -EIO;
}
 
- out:
-   return ret;
+   return 0;
 }
 
 static int
@@ -482,7 +492,7 @@ int fit_image_cipher_data(const char *keydir, void *keydest,
const char *image_name;
const void *data;
size_t size;
-   int cipher_node_offset;
+   int cipher_node_offset, len;
 
/* Get image name */
image_name = fit_get_name(fit, image_noffset, NULL);
@@ -497,6 +507,13 @@ int fit_image_cipher_data(const char *keydir, void 
*keydest,
return -1;
}
 
+   /* Don't cipher ciphered data */
+   if (fdt_getprop(fit, image_noffset, "data-size-unciphered", &len))
+   return 0;
+   if (len != -FDT_ERR_NOTFOUND) {
+   printf("Failure testing for data-size-unciphered\n");
+   return -1;
+   }
 
/* Process cipher node if present */
cipher_node_offset = fdt_subnode_offset(fit, image_noffset, "cipher");
-- 
2.27.0



Re: [PATCH v1 1/4] usb: xhci: Add missing endian conversions (cpu_to_leXX / leXX_to_cpu)

2020-07-17 Thread Stefan Roese

Hi Bin,

On 17.07.20 13:18, Bin Meng wrote:

Hi Stefan,

On Thu, Jul 2, 2020 at 4:47 PM Stefan Roese  wrote:


While trying to use the U-Boot xHCI driver on the MIPS Octeon platform,
which is big endian, I noticed that the driver is missing a few endian
conversion calls. This patch adds these missing endian conversion
calls.

Signed-off-by: Stefan Roese 
Cc: Bin Meng 
Cc: Marek Vasut 
---

  drivers/usb/host/xhci-mem.c | 9 +
  1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 2d968aafb0..bd959b4093 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -110,7 +110,7 @@ static void xhci_scratchpad_free(struct xhci_ctrl *ctrl)

 ctrl->dcbaa->dev_context_ptrs[0] = 0;

-   free((void *)(uintptr_t)ctrl->scratchpad->sp_array[0]);
+   free((void *)le64_to_cpu(ctrl->scratchpad->sp_array[0]));


There is a build warning for this:

drivers/usb/host/xhci-mem.c: In function 'xhci_scratchpad_free':
drivers/usb/host/xhci-mem.c:113:7: warning: cast to pointer from
integer of different size [-Wint-to-pointer-cast]
   free((void *)le64_to_cpu(ctrl->scratchpad->sp_array[0]));
^


So we need the (uintptr_t) here as well?

  free((void *)(uintptr_t)le64_to_cpu(ctrl->scratchpad->sp_array[0]));

Should I send v2 for this patch?


 free(ctrl->scratchpad->sp_array);
 free(ctrl->scratchpad);
 ctrl->scratchpad = NULL;
@@ -225,7 +225,8 @@ static void xhci_link_segments(struct xhci_segment *prev,
 prev->next = next;
 if (link_trbs) {
 val_64 = (uintptr_t)next->trbs;
-   prev->trbs[TRBS_PER_SEGMENT-1].link.segment_ptr = val_64;
+   prev->trbs[TRBS_PER_SEGMENT-1].link.segment_ptr =
+   cpu_to_le64(val_64);

 /*
  * Set the last TRB in the segment to
@@ -486,7 +487,7 @@ int xhci_alloc_virt_device(struct xhci_ctrl *ctrl, unsigned 
int slot_id)
 byte_64 = (uintptr_t)(virt_dev->out_ctx->bytes);

 /* Point to output device context in dcbaa. */
-   ctrl->dcbaa->dev_context_ptrs[slot_id] = byte_64;
+   ctrl->dcbaa->dev_context_ptrs[slot_id] = cpu_to_le64(byte_64);

 xhci_flush_cache((uintptr_t)&ctrl->dcbaa->dev_context_ptrs[slot_id],
  sizeof(__le64));
@@ -768,7 +769,7 @@ void xhci_setup_addressable_virt_dev(struct xhci_ctrl *ctrl,

 debug("route string %x\n", route);
  #endif
-   slot_ctx->dev_info |= route;
+   slot_ctx->dev_info |= cpu_to_le32(route);

 switch (speed) {
 case USB_SPEED_SUPER:
--


Test results on Minnowmax which has one USB 2.0 port and one 3.0 port:

USB 2.0 flash drive inserted to USB 2.0 port: recognized, read/write OK
USB 2.0 flash drive inserted to USB 3.0 port: recognized, read/write OK

USB 3.0 flash drive inserted to USB 2.0 port: recognized, read/write OK
USB 3.0 flash drive inserted to USB 3.0 port: recognized, read/write OK

USB 2.0 flash drive connected to a USB 3.0 HUB inserted to USB 2.0
port: recognized, read/write OK
USB 2.0 flash drive connected to a USB 3.0 HUB inserted to USB 3.0
port: recognized, read/write OK

USB 3.0 flash drive connected to a USB 3.0 HUB inserted to USB 2.0
port: recognized, read/write OK
USB 3.0 flash drive connected to a USB 3.0 HUB inserted to USB 3.0
port: recognized, read/write OK

Tested-by: Bin Meng 


Very good. :)

Thanks,
Stefan


[PATCH] psci: put psci_method in .data section if EFI_LOADER is not enabled

2020-07-17 Thread Patrick Delaunay
From: Yann Gautier 

Move the variable psci_method in .data section when EFI is not
activated and the psci driver safely access it before relocation.

Without this patch the variable is located in .bss section
and the psci probe requested before relocation corrupts the device
tree (probe is requested by board_f.c::print_resetinfo()).

When EFI_LOADER is activated, this variable in already located in the
.data.efi_runtime section by __efi_runtime_data.

Signed-off-by: Yann Gautier 
Signed-off-by: Patrick Delaunay 
---

 drivers/firmware/psci.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/firmware/psci.c b/drivers/firmware/psci.c
index 23cf807591..7d2e49fd3e 100644
--- a/drivers/firmware/psci.c
+++ b/drivers/firmware/psci.c
@@ -25,7 +25,11 @@
 #define PSCI_METHOD_HVC 1
 #define PSCI_METHOD_SMC 2
 
+#if CONFIG_IS_ENABLED(EFI_LOADER)
 int __efi_runtime_data psci_method;
+#else
+int psci_method __attribute__ ((section(".data")));
+#endif
 
 unsigned long __efi_runtime invoke_psci_fn
(unsigned long function_id, unsigned long arg0,
-- 
2.17.1



[PATCH v2 5/8] sandbox64: enable button

2020-07-17 Thread Philippe Reynes
Enable the support of button (driver and command) on sandbox64.

Reviewed-by: Simon Glass 
Signed-off-by: Philippe Reynes 
---
Changelog:
v2:
- no change

 configs/sandbox64_defconfig | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/configs/sandbox64_defconfig b/configs/sandbox64_defconfig
index a3f049e..89ba504 100644
--- a/configs/sandbox64_defconfig
+++ b/configs/sandbox64_defconfig
@@ -90,6 +90,8 @@ CONFIG_ADC=y
 CONFIG_ADC_SANDBOX=y
 CONFIG_AXI=y
 CONFIG_AXI_SANDBOX=y
+CONFIG_BUTTON=y
+CONFIG_BUTTON_GPIO=y
 CONFIG_CLK=y
 CONFIG_CPU=y
 CONFIG_DM_DEMO=y
-- 
2.7.4



[PATCH v2 2/8] dm: button: add a driver for button driven by gpio

2020-07-17 Thread Philippe Reynes
Add a simple driver which allows use of buttons attached to GPIOs.

Reviewed-by: Simon Glass 
Signed-off-by: Philippe Reynes 
---
Changelog:
v2:
- remove useless default in Kconfig
- re-order include
- fix condition in button_gpio_remove

 drivers/button/Kconfig   |   9 
 drivers/button/Makefile  |   1 +
 drivers/button/button-gpio.c | 111 +++
 3 files changed, 121 insertions(+)
 create mode 100644 drivers/button/button-gpio.c

diff --git a/drivers/button/Kconfig b/drivers/button/Kconfig
index 8301858..6b3ec7e 100644
--- a/drivers/button/Kconfig
+++ b/drivers/button/Kconfig
@@ -9,4 +9,13 @@ config BUTTON
  can provide access to board-specific buttons. Use of the device tree
  for configuration is encouraged.
 
+config BUTTON_GPIO
+   bool "Button gpio"
+   depends on BUTTON
+   help
+ Enable support for buttons which are connected to GPIO lines. These
+ GPIOs may be on the SoC or some other device which provides GPIOs.
+ The GPIO driver must used driver model. Buttons are configured using
+ the device tree.
+
 endmenu
diff --git a/drivers/button/Makefile b/drivers/button/Makefile
index 0b4c128..fcc10eb 100644
--- a/drivers/button/Makefile
+++ b/drivers/button/Makefile
@@ -3,3 +3,4 @@
 # Copyright (C) 2020 Philippe Reynes 
 
 obj-$(CONFIG_BUTTON) += button-uclass.o
+obj-$(CONFIG_BUTTON_GPIO) += button-gpio.o
diff --git a/drivers/button/button-gpio.c b/drivers/button/button-gpio.c
new file mode 100644
index 000..4f71fce
--- /dev/null
+++ b/drivers/button/button-gpio.c
@@ -0,0 +1,111 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 Philippe Reynes 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+struct button_gpio_priv {
+   struct gpio_desc gpio;
+};
+
+static enum button_state_t button_gpio_get_state(struct udevice *dev)
+{
+   struct button_gpio_priv *priv = dev_get_priv(dev);
+   int ret;
+
+   if (!dm_gpio_is_valid(&priv->gpio))
+   return -EREMOTEIO;
+   ret = dm_gpio_get_value(&priv->gpio);
+   if (ret < 0)
+   return ret;
+
+   return ret ? BUTTON_ON : BUTTON_OFF;
+}
+
+static int button_gpio_probe(struct udevice *dev)
+{
+   struct button_uc_plat *uc_plat = dev_get_uclass_platdata(dev);
+   struct button_gpio_priv *priv = dev_get_priv(dev);
+   int ret;
+
+   /* Ignore the top-level button node */
+   if (!uc_plat->label)
+   return 0;
+
+   ret = gpio_request_by_name(dev, "gpios", 0, &priv->gpio, GPIOD_IS_IN);
+   if (ret)
+   return ret;
+
+   return 0;
+}
+
+static int button_gpio_remove(struct udevice *dev)
+{
+   /*
+* The GPIO driver may have already been removed. We will need to
+* address this more generally.
+*/
+   if (!IS_ENABLED(CONFIG_SANDBOX)) {
+   struct button_gpio_priv *priv = dev_get_priv(dev);
+
+   if (dm_gpio_is_valid(&priv->gpio))
+   dm_gpio_free(dev, &priv->gpio);
+   }
+
+   return 0;
+}
+
+static int button_gpio_bind(struct udevice *parent)
+{
+   struct udevice *dev;
+   ofnode node;
+   int ret;
+
+   dev_for_each_subnode(node, parent) {
+   struct button_uc_plat *uc_plat;
+   const char *label;
+
+   label = ofnode_read_string(node, "label");
+   if (!label) {
+   debug("%s: node %s has no label\n", __func__,
+ ofnode_get_name(node));
+   return -EINVAL;
+   }
+   ret = device_bind_driver_to_node(parent, "button_gpio",
+ofnode_get_name(node),
+node, &dev);
+   if (ret)
+   return ret;
+   uc_plat = dev_get_uclass_platdata(dev);
+   uc_plat->label = label;
+   }
+
+   return 0;
+}
+
+static const struct button_ops button_gpio_ops = {
+   .get_state  = button_gpio_get_state,
+};
+
+static const struct udevice_id button_gpio_ids[] = {
+   { .compatible = "button-gpio" },
+   { }
+};
+
+U_BOOT_DRIVER(button_gpio) = {
+   .name   = "button_gpio",
+   .id = UCLASS_BUTTON,
+   .of_match   = button_gpio_ids,
+   .ops= &button_gpio_ops,
+   .priv_auto_alloc_size = sizeof(struct button_gpio_priv),
+   .bind   = button_gpio_bind,
+   .probe  = button_gpio_probe,
+   .remove = button_gpio_remove,
+};
-- 
2.7.4



[PATCH v2 6/8] sandbox: enable button

2020-07-17 Thread Philippe Reynes
Enable the support of button (driver and command) on sandbox.

Reviewed-by: Simon Glass 
Signed-off-by: Philippe Reynes 
---
Changelog:
v2:
- no change

 configs/sandbox_defconfig | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index 5b75693..67801ed 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -102,6 +102,8 @@ CONFIG_AXI_SANDBOX=y
 CONFIG_BOOTCOUNT_LIMIT=y
 CONFIG_DM_BOOTCOUNT=y
 CONFIG_DM_BOOTCOUNT_RTC=y
+CONFIG_BUTTON=y
+CONFIG_BUTTON_GPIO=y
 CONFIG_CLK=y
 CONFIG_CLK_COMPOSITE_CCF=y
 CONFIG_SANDBOX_CLK_CCF=y
-- 
2.7.4



[PATCH v2 1/8] dm: button: add an uclass for button

2020-07-17 Thread Philippe Reynes
Add a new uclass for button that implements two functions:
- button_get_by_label
- button_get_status

Reviewed-by: Simon Glass 
Signed-off-by: Philippe Reynes 
---

Changelog:
v2:
- re-order include
- use uclass_id_foreach_dev
- add comments to enum button_state_t

 drivers/Kconfig|  2 ++
 drivers/Makefile   |  1 +
 drivers/button/Kconfig | 12 +
 drivers/button/Makefile|  5 
 drivers/button/button-uclass.c | 43 ++
 include/button.h   | 59 ++
 include/dm/uclass-id.h |  1 +
 7 files changed, 123 insertions(+)
 create mode 100644 drivers/button/Kconfig
 create mode 100644 drivers/button/Makefile
 create mode 100644 drivers/button/button-uclass.c
 create mode 100644 include/button.h

diff --git a/drivers/Kconfig b/drivers/Kconfig
index e34a227..3cb05aa 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -14,6 +14,8 @@ source "drivers/block/Kconfig"
 
 source "drivers/bootcount/Kconfig"
 
+source "drivers/button/Kconfig"
+
 source "drivers/cache/Kconfig"
 
 source "drivers/clk/Kconfig"
diff --git a/drivers/Makefile b/drivers/Makefile
index 94e8c5d..727a713 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -1,5 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0+
 
+obj-$(CONFIG_$(SPL_TPL_)BUTTON) += button/
 obj-$(CONFIG_$(SPL_TPL_)CACHE) += cache/
 obj-$(CONFIG_$(SPL_TPL_)CLK) += clk/
 obj-$(CONFIG_$(SPL_TPL_)DM) += core/
diff --git a/drivers/button/Kconfig b/drivers/button/Kconfig
new file mode 100644
index 000..8301858
--- /dev/null
+++ b/drivers/button/Kconfig
@@ -0,0 +1,12 @@
+menu "Button Support"
+
+config BUTTON
+   bool "Enable button support"
+   depends on DM
+   help
+ Many boards have buttons which can be used to change behaviour 
(reset, ...).
+ U-Boot provides a uclass API to implement this feature. Button drivers
+ can provide access to board-specific buttons. Use of the device tree
+ for configuration is encouraged.
+
+endmenu
diff --git a/drivers/button/Makefile b/drivers/button/Makefile
new file mode 100644
index 000..0b4c128
--- /dev/null
+++ b/drivers/button/Makefile
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (C) 2020 Philippe Reynes 
+
+obj-$(CONFIG_BUTTON) += button-uclass.o
diff --git a/drivers/button/button-uclass.c b/drivers/button/button-uclass.c
new file mode 100644
index 000..1c742c2
--- /dev/null
+++ b/drivers/button/button-uclass.c
@@ -0,0 +1,43 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2020 Philippe Reynes 
+ *
+ * Based on led-uclass.c
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+int button_get_by_label(const char *label, struct udevice **devp)
+{
+   struct udevice *dev;
+   struct uclass *uc;
+
+   uclass_id_foreach_dev(UCLASS_BUTTON, dev, uc) {
+   struct button_uc_plat *uc_plat = dev_get_uclass_platdata(dev);
+
+   /* Ignore the top-level button node */
+   if (uc_plat->label && !strcmp(label, uc_plat->label))
+   return uclass_get_device_tail(dev, 0, devp);
+   }
+
+   return -ENODEV;
+}
+
+enum button_state_t button_get_state(struct udevice *dev)
+{
+   struct button_ops *ops = button_get_ops(dev);
+
+   if (!ops->get_state)
+   return -ENOSYS;
+
+   return ops->get_state(dev);
+}
+
+UCLASS_DRIVER(button) = {
+   .id = UCLASS_BUTTON,
+   .name   = "button",
+   .per_device_platdata_auto_alloc_size = sizeof(struct button_uc_plat),
+};
diff --git a/include/button.h b/include/button.h
new file mode 100644
index 000..688b63b
--- /dev/null
+++ b/include/button.h
@@ -0,0 +1,59 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2020 Philippe Reynes 
+ */
+
+#ifndef __BUTTON_H
+#define __BUTTON_H
+
+/**
+ * struct button_uc_plat - Platform data the uclass stores about each device
+ *
+ * @label: Button label
+ */
+struct button_uc_plat {
+   const char *label;
+};
+
+/**
+ * enum button_state_t - State used for button
+ * - BUTTON_OFF - Button is not pressed
+ * - BUTTON_ON - Button is pressed
+ * - BUTTON_COUNT - Number of button state
+ */
+enum button_state_t {
+   BUTTON_OFF = 0,
+   BUTTON_ON = 1,
+   BUTTON_COUNT,
+};
+
+struct button_ops {
+   /**
+* get_state() - get the state of a button
+*
+* @dev:button device to change
+* @return button state button_state_t, or -ve on error
+*/
+   enum button_state_t (*get_state)(struct udevice *dev);
+};
+
+#define button_get_ops(dev)((struct button_ops *)(dev)->driver->ops)
+
+/**
+ * button_get_by_label() - Find a button device by label
+ *
+ * @label: button label to look up
+ * @devp:  Returns the associated device, if found
+ * @return 0 if found, -ENODEV if not found, other -ve on error
+ */
+int button_get_by_label(const char *label, struct 

[PATCH v2 7/8] test/py: add tests for the button commands

2020-07-17 Thread Philippe Reynes
Adds tests for the button commands.

Reviewed-by: Simon Glass 
Signed-off-by: Philippe Reynes 
---
Changelog:
v2:
- no change (button uclass test is added in another commit

 arch/sandbox/dts/test.dts| 14 ++
 test/py/tests/test_button.py | 19 +++
 2 files changed, 33 insertions(+)
 create mode 100644 test/py/tests/test_button.py

diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index 5ce5e28..101d729 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -51,6 +51,20 @@
#sound-dai-cells = <1>;
};
 
+   buttons {
+   compatible = "button-gpio";
+
+   summer {
+   gpios = <&gpio_a 3 0>;
+   label = "summer";
+   };
+
+   christmas {
+   gpios = <&gpio_a 4 0>;
+   label = "christmas";
+   };
+   };
+
cros_ec: cros-ec {
reg = <0 0>;
compatible = "google,cros-ec-sandbox";
diff --git a/test/py/tests/test_button.py b/test/py/tests/test_button.py
new file mode 100644
index 000..98067a9
--- /dev/null
+++ b/test/py/tests/test_button.py
@@ -0,0 +1,19 @@
+# SPDX-License-Identifier: GPL-2.0+
+
+import pytest
+
+@pytest.mark.boardspec('sandbox')
+@pytest.mark.buildconfigspec('cmd_button')
+def test_button_exit_statuses(u_boot_console):
+"""Test that non-input button commands correctly return the command
+success/failure status."""
+
+expected_response = 'rc:0'
+response = u_boot_console.run_command('button list; echo rc:$?')
+assert(expected_response in response)
+response = u_boot_console.run_command('button summer; echo rc:$?')
+assert(expected_response in response)
+
+expected_response = 'rc:1'
+response = u_boot_console.run_command('button nonexistent-button; echo 
rc:$?')
+assert(expected_response in response)
-- 
2.7.4



[PATCH v2 4/8] sandbox: dtsi: add buttons

2020-07-17 Thread Philippe Reynes
Adds two buttons on sandbox so button framework may be tested.

Reviewed-by: Simon Glass 
Signed-off-by: Philippe Reynes 
---
Changelog:
v2:
- no change

 arch/sandbox/dts/sandbox.dtsi | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/arch/sandbox/dts/sandbox.dtsi b/arch/sandbox/dts/sandbox.dtsi
index e1f68cd..bd87dac 100644
--- a/arch/sandbox/dts/sandbox.dtsi
+++ b/arch/sandbox/dts/sandbox.dtsi
@@ -15,6 +15,20 @@
#sound-dai-cells = <1>;
};
 
+   buttons {
+   compatible = "button-gpio";
+
+   summer {
+   gpios = <&gpio_a 3 0>;
+   label = "summer";
+   };
+
+   christmas {
+   gpios = <&gpio_a 4 0>;
+   label = "christmas";
+   };
+   };
+
gpio_a: gpios@0 {
u-boot,dm-pre-reloc;
gpio-controller;
-- 
2.7.4



[PATCH v2 8/8] test: dm: add a test for class button

2020-07-17 Thread Philippe Reynes
Add a test to confirm that we can read button state
using the button-gpio driver.

Signed-off-by: Philippe Reynes 
---
Changelog:
v2:
- new commit in the serie

 test/dm/Makefile |  1 +
 test/dm/button.c | 74 
 2 files changed, 75 insertions(+)
 create mode 100644 test/dm/button.c

diff --git a/test/dm/Makefile b/test/dm/Makefile
index 6c18fd0..092a70e 100644
--- a/test/dm/Makefile
+++ b/test/dm/Makefile
@@ -17,6 +17,7 @@ obj-$(CONFIG_ACPIGEN) += acpi.o
 obj-$(CONFIG_SOUND) += audio.o
 obj-$(CONFIG_BLK) += blk.o
 obj-$(CONFIG_BOARD) += board.o
+obj-$(CONFIG_BUTTON) += button.o
 obj-$(CONFIG_DM_BOOTCOUNT) += bootcount.o
 obj-$(CONFIG_CLK) += clk.o clk_ccf.o
 obj-$(CONFIG_DEVRES) += devres.o
diff --git a/test/dm/button.c b/test/dm/button.c
new file mode 100644
index 000..890f470
--- /dev/null
+++ b/test/dm/button.c
@@ -0,0 +1,74 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2020 Philippe Reynes 
+ *
+ * Based on led.c
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/* Base test of the button uclass */
+static int dm_test_button_base(struct unit_test_state *uts)
+{
+   struct udevice *dev;
+
+   /* Get the top-level device */
+   ut_assertok(uclass_get_device(UCLASS_BUTTON, 0, &dev));
+   ut_assertok(uclass_get_device(UCLASS_BUTTON, 1, &dev));
+   ut_assertok(uclass_get_device(UCLASS_BUTTON, 2, &dev));
+   ut_asserteq(-ENODEV, uclass_get_device(UCLASS_BUTTON, 3, &dev));
+
+   return 0;
+}
+DM_TEST(dm_test_button_base, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+/* Test of the button uclass using the button_gpio driver */
+static int dm_test_button_gpio(struct unit_test_state *uts)
+{
+   const int offset = 3;
+   struct udevice *dev, *gpio;
+
+   /*
+* Check that we can manipulate an BUTTON. BUTTON 1 is connected to GPIO
+* bank gpio_a, offset 3.
+*/
+   ut_assertok(uclass_get_device(UCLASS_BUTTON, 1, &dev));
+   ut_assertok(uclass_get_device(UCLASS_GPIO, 1, &gpio));
+
+   ut_asserteq(0, sandbox_gpio_set_value(gpio, offset, 0));
+   ut_asserteq(0, sandbox_gpio_get_value(gpio, offset));
+   ut_asserteq(BUTTON_OFF, button_get_state(dev));
+
+   ut_asserteq(0, sandbox_gpio_set_value(gpio, offset, 1));
+   ut_asserteq(1, sandbox_gpio_get_value(gpio, offset));
+   ut_asserteq(BUTTON_ON, button_get_state(dev));
+
+   return 0;
+}
+DM_TEST(dm_test_button_gpio, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+/* Test obtaining an BUTTON by label */
+static int dm_test_button_label(struct unit_test_state *uts)
+{
+   struct udevice *dev, *cmp;
+
+   ut_assertok(button_get_by_label("summer", &dev));
+   ut_asserteq(1, device_active(dev));
+   ut_assertok(uclass_get_device(UCLASS_BUTTON, 1, &cmp));
+   ut_asserteq_ptr(dev, cmp);
+
+   ut_assertok(button_get_by_label("christmas", &dev));
+   ut_asserteq(1, device_active(dev));
+   ut_assertok(uclass_get_device(UCLASS_BUTTON, 2, &cmp));
+   ut_asserteq_ptr(dev, cmp);
+
+   ut_asserteq(-ENODEV, button_get_by_label("spring", &dev));
+
+   return 0;
+}
+DM_TEST(dm_test_button_label, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
-- 
2.7.4



[PATCH v2 3/8] cmd: button: add a new 'button' command

2020-07-17 Thread Philippe Reynes
Adds a command 'button' that provides the list of buttons
supported by the board, and the state of a button.

Reviewed-by: Simon Glass 
Signed-off-by: Philippe Reynes 
---
Changelog:
v2
- no change

 cmd/Kconfig  | 11 
 cmd/Makefile |  1 +
 cmd/button.c | 86 
 3 files changed, 98 insertions(+)
 create mode 100644 cmd/button.c

diff --git a/cmd/Kconfig b/cmd/Kconfig
index 192b3b2..750d26a 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -1664,6 +1664,17 @@ config CMD_BLOCK_CACHE
  during development, but also allows the cache to be disabled when
  it might hurt performance (e.g. when using the ums command).
 
+config CMD_BUTTON
+   bool "button"
+   depends on BUTTON
+   default y if BUTTON
+   help
+ Enable the 'button' command which allows to get the status of
+ buttons supported by the board. The buttonss can be listed with
+ 'button list' and state can be known with 'button '.
+ Any button drivers can be controlled with this command, e.g.
+ button_gpio.
+
 config CMD_CACHE
bool "icache or dcache"
help
diff --git a/cmd/Makefile b/cmd/Makefile
index 974ad48..5ded3a6 100644
--- a/cmd/Makefile
+++ b/cmd/Makefile
@@ -32,6 +32,7 @@ obj-$(CONFIG_CMD_BOOTSTAGE) += bootstage.o
 obj-$(CONFIG_CMD_BOOTZ) += bootz.o
 obj-$(CONFIG_CMD_BOOTI) += booti.o
 obj-$(CONFIG_CMD_BTRFS) += btrfs.o
+obj-$(CONFIG_CMD_BUTTON) += button.o
 obj-$(CONFIG_CMD_CACHE) += cache.o
 obj-$(CONFIG_CMD_CBFS) += cbfs.o
 obj-$(CONFIG_CMD_CLK) += clk.o
diff --git a/cmd/button.c b/cmd/button.c
new file mode 100644
index 000..84ad165
--- /dev/null
+++ b/cmd/button.c
@@ -0,0 +1,86 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 Philippe Reynes 
+ *
+ * Based on led.c
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static const char *const state_label[] = {
+   [BUTTON_OFF]= "off",
+   [BUTTON_ON] = "on",
+};
+
+static int show_button_state(struct udevice *dev)
+{
+   int ret;
+
+   ret = button_get_state(dev);
+   if (ret >= BUTTON_COUNT)
+   ret = -EINVAL;
+   if (ret >= 0)
+   printf("%s\n", state_label[ret]);
+
+   return ret;
+}
+
+static int list_buttons(void)
+{
+   struct udevice *dev;
+   int ret;
+
+   for (uclass_find_first_device(UCLASS_BUTTON, &dev);
+dev;
+uclass_find_next_device(&dev)) {
+   struct button_uc_plat *plat = dev_get_uclass_platdata(dev);
+
+   if (!plat->label)
+   continue;
+   printf("%-15s ", plat->label);
+   if (device_active(dev)) {
+   ret = show_button_state(dev);
+   if (ret < 0)
+   printf("Error %d\n", ret);
+   } else {
+   printf("\n");
+   }
+   }
+
+   return 0;
+}
+
+int do_button(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
+{
+   const char *button_label;
+   struct udevice *dev;
+   int ret;
+
+   /* Validate arguments */
+   if (argc < 2)
+   return CMD_RET_USAGE;
+   button_label = argv[1];
+   if (strncmp(button_label, "list", 4) == 0)
+   return list_buttons();
+
+   ret = button_get_by_label(button_label, &dev);
+   if (ret) {
+   printf("Button '%s' not found (err=%d)\n", button_label, ret);
+   return CMD_RET_FAILURE;
+   }
+
+   ret = show_button_state(dev);
+
+   return 0;
+}
+
+U_BOOT_CMD(
+   button, 4, 1, do_button,
+   "manage buttons",
+   " \tGet button state\n"
+   "button list\t\tShow a list of buttons"
+);
-- 
2.7.4



Re: [PATCH 1/1] test/dm: check if devices exist

2020-07-17 Thread Philippe REYNES
Hi Heinrich

> Running 'ut dm' on the sandbox without -D or -d results in segmentation
> faults due to NULL pointer dereferences.
> 
> Check that device pointers are non-NULL before using them.
> 
> Use ut_assertnonnull() for pointers instead of ut_assert().

Tested-by: Philippe Reynes 

> Signed-off-by: Heinrich Schuchardt 
> ---
> test/dm/acpi.c | 3 +++
> test/dm/core.c | 10 +-
> test/dm/devres.c | 1 +
> test/dm/test-fdt.c | 2 ++
> test/dm/virtio.c | 7 +++
> 5 files changed, 18 insertions(+), 5 deletions(-)
> 
> diff --git a/test/dm/acpi.c b/test/dm/acpi.c
> index 4c46dd83a6..ece7993cf3 100644
> --- a/test/dm/acpi.c
> +++ b/test/dm/acpi.c
> @@ -96,7 +96,10 @@ DM_TEST(dm_test_acpi_get_table_revision,
> static int dm_test_acpi_create_dmar(struct unit_test_state *uts)
> {
> struct acpi_dmar dmar;
> + struct udevice *cpu;
> 
> + ut_assertok(uclass_first_device(UCLASS_CPU, &cpu));
> + ut_assertnonnull(cpu);
> ut_assertok(acpi_create_dmar(&dmar, DMAR_INTR_REMAP));
> ut_asserteq(DMAR_INTR_REMAP, dmar.flags);
> ut_asserteq(32 - 1, dmar.host_address_width);
> diff --git a/test/dm/core.c b/test/dm/core.c
> index 6a930ae31a..d20c48443f 100644
> --- a/test/dm/core.c
> +++ b/test/dm/core.c
> @@ -158,7 +158,7 @@ static int dm_test_autobind_uclass_pdata_alloc(struct
> unit_test_state *uts)
> for (uclass_find_first_device(UCLASS_TEST, &dev);
> dev;
> uclass_find_next_device(&dev)) {
> - ut_assert(dev);
> + ut_assertnonnull(dev);
> 
> uc_pdata = dev_get_uclass_platdata(dev);
> ut_assert(uc_pdata);
> @@ -181,7 +181,7 @@ static int dm_test_autobind_uclass_pdata_valid(struct
> unit_test_state *uts)
> for (uclass_find_first_device(UCLASS_TEST, &dev);
> dev;
> uclass_find_next_device(&dev)) {
> - ut_assert(dev);
> + ut_assertnonnull(dev);
> 
> uc_pdata = dev_get_uclass_platdata(dev);
> ut_assert(uc_pdata);
> @@ -747,11 +747,11 @@ static int dm_test_uclass_devices_find(struct
> unit_test_state *uts)
> dev;
> ret = uclass_find_next_device(&dev)) {
> ut_assert(!ret);
> - ut_assert(dev);
> + ut_assertnonnull(dev);
> }
> 
> ut_assertok(uclass_find_first_device(UCLASS_TEST_DUMMY, &dev));
> - ut_assert(!dev);
> + ut_assertnull(dev);
> 
> return 0;
> }
> @@ -778,7 +778,7 @@ static int dm_test_uclass_devices_find_by_name(struct
> unit_test_state *uts)
> testdev;
> ret = uclass_find_next_device(&testdev)) {
> ut_assertok(ret);
> - ut_assert(testdev);
> + ut_assertnonnull(testdev);
> 
> findret = uclass_find_device_by_name(UCLASS_TEST_FDT,
> testdev->name,
> diff --git a/test/dm/devres.c b/test/dm/devres.c
> index b5de0cb191..550787495d 100644
> --- a/test/dm/devres.c
> +++ b/test/dm/devres.c
> @@ -153,6 +153,7 @@ static int dm_test_devres_phase(struct unit_test_state 
> *uts)
> * allocation created in the bind() method.
> */
> ut_assertok(uclass_find_first_device(UCLASS_TEST_DEVRES, &dev));
> + ut_assertnonnull(dev);
> devres_get_stats(dev, &stats);
> ut_asserteq(1, stats.allocs);
> ut_asserteq(TEST_DEVRES_SIZE, stats.total_size);
> diff --git a/test/dm/test-fdt.c b/test/dm/test-fdt.c
> index 51f2547409..8ef7c7a88e 100644
> --- a/test/dm/test-fdt.c
> +++ b/test/dm/test-fdt.c
> @@ -832,10 +832,12 @@ static int dm_test_fdt_phandle(struct unit_test_state
> *uts)
> struct udevice *back, *dev, *dev2;
> 
> ut_assertok(uclass_find_first_device(UCLASS_PANEL_BACKLIGHT, &back));
> + ut_assertnonnull(back);
> ut_asserteq(-ENOENT, uclass_find_device_by_phandle(UCLASS_REGULATOR,
> back, "missing", &dev));
> ut_assertok(uclass_find_device_by_phandle(UCLASS_REGULATOR, back,
> "power-supply", &dev));
> + ut_assertnonnull(dev);
> ut_asserteq(0, device_active(dev));
> ut_asserteq_str("ldo1", dev->name);
> ut_assertok(uclass_get_device_by_phandle(UCLASS_REGULATOR, back,
> diff --git a/test/dm/virtio.c b/test/dm/virtio.c
> index 4b317d2ec3..4a0c0b23b8 100644
> --- a/test/dm/virtio.c
> +++ b/test/dm/virtio.c
> @@ -22,9 +22,11 @@ static int dm_test_virtio_base(struct unit_test_state *uts)
> 
> /* check probe success */
> ut_assertok(uclass_first_device(UCLASS_VIRTIO, &bus));
> + ut_assertnonnull(bus);
> 
> /* check the child virtio-blk device is bound */
> ut_assertok(device_find_first_child(bus, &dev));
> + ut_assertnonnull(dev);
> ut_assertok(strcmp(dev->name, "virtio-blk#0"));
> 
> /* check driver status */
> @@ -49,15 +51,18 @@ static int dm_test_virtio_all_ops(struct unit_test_state
> *uts)
> 
> /* check probe success */
> ut_assertok(uclass_first_device(UCLASS_VIRTIO, &bus));
> + ut_assertnonnull(bus);
> 
> /* check the child virtio-blk device is bound */
> ut_assertok(device_find_first_child(bus, &dev));
> + ut_assertnonnull(dev);
> 
> /*
> * fake the virtio device probe by filling in uc_priv->vdev
> * which is used by virtio_find_vqs/virtio_del_vqs.
> */
> uc_priv = dev_get_uclass_priv(bus);
> + ut_assertnonnull(uc_priv);
> uc_priv->vdev = dev;
> 
> /* test virtio_xxx APIs */
> @@ -106,9 +111,11 @@ static int dm_test_virtio_remove(struct unit_test_state
> *uts)
> 
> /* check probe success */
> ut_assertok(uclass_first_device(UCLASS_VIRTI

Re: [PATCH 1/4] lmb/bdinfo: dump lmb info via bdinfo

2020-07-17 Thread Tom Rini
On Fri, Jun 12, 2020 at 03:41:18PM +0300, Tero Kristo wrote:

> Dump lmb status from the bdinfo command. This is useful for seeing the
> reserved memory regions from the u-boot cmdline.
> 
> Signed-off-by: Tero Kristo 
> ---
>  cmd/bdinfo.c  |  8 +++-
>  include/lmb.h |  1 +
>  lib/lmb.c | 42 +++---
>  3 files changed, 31 insertions(+), 20 deletions(-)
> 
> diff --git a/cmd/bdinfo.c b/cmd/bdinfo.c
> index dba552b03f..05e1b27de0 100644
> --- a/cmd/bdinfo.c
> +++ b/cmd/bdinfo.c
> @@ -10,6 +10,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -365,8 +366,13 @@ static int do_bdinfo(struct cmd_tbl *cmdtp, int flag, 
> int argc,
>  #if CONFIG_IS_ENABLED(MULTI_DTB_FIT)
>   print_num("multi_dtb_fit", (ulong)gd->multi_dtb_fit);
>  #endif
> - if (gd->fdt_blob)
> + if (gd->fdt_blob) {
> + struct lmb lmb;
>   print_num("fdt_blob", (ulong)gd->fdt_blob);
> + lmb_init_and_reserve(&lmb, gd->bd, (void *)gd->fdt_blob);
> + lmb_dump_all_force(&lmb);
> + }
> +
>   print_cpu_word_size();
>  
>   return 0;

Can you please rebase this on top of master?  Simon's series to cleanup
bdinfo stuff has been applied, thanks.  The rest of your changes are
fine and under test now.

-- 
Tom


signature.asc
Description: PGP signature


Re: [PATCH] lib: zlib: Use post-increment only in inffast.c

2020-07-17 Thread Tom Rini
On Wed, Jun 24, 2020 at 04:34:03PM +0800, Ley Foon Tan wrote:

> From: Chin Liang See 
> 
> This fixes CVE-2016-9841. Changes integrated from [1], with changes
> make for Uboot code base.
> 
> An old inffast.c optimization turns out to not be optimal anymore
> with modern compilers, and furthermore was not compliant with the
> C standard, for which decrementing a pointer before its allocated
> memory is undefined. Per the recommendation of a security audit of
> the zlib code by Trail of Bits and TrustInSoft, in support of the
> Mozilla Foundation, this "optimization" was removed, in order to
> avoid the possibility of undefined behavior.
> 
> [1]: 
> https://github.com/madler/zlib/commit/9aaec95e82117c1cb0f9624264c3618fc380cecb
> 
> Signed-off-by: Mark Adler 
> Signed-off-by: Chin Liang See 
> Signed-off-by: Ley Foon Tan 

This breaks the following tests on sandbox:
FAILED test/py/tests/test_efi_fit.py::test_efi_fit_launch - u_boot_spawn.Timeout
FAILED test/py/tests/test_fit.py::test_fit - OSError: [Errno 5] Input/output 
error

-- 
Tom


signature.asc
Description: PGP signature


[PATCH 1/2] bcmgenet: fix DMA buffer management

2020-07-17 Thread Jason Wessel
This commit fixes a serious issue occurring when several network
commands are run on a raspberry pi 4 board: for instance a "dhcp"
command and then one or several "tftp" commands. In this case,
packet recv callbacks were called several times on the same packets,
and send function was failing most of the time.

note: if the boot procedure is made of a single network
command, the issue is not visible.

The issue is related to management of the packet ring buffers
(producer / consumer) and DMA.
Each time a packet is received, the ethernet device stores it
in the buffer and increments an index called RDMA_PROD_INDEX.
Each time the driver outputs a received packet, it increments
another index called RDMA_CONS_INDEX.

Between each pair of network commands, as part of the driver
'start' function, previous code tried to reset both RDMA_CONS_INDEX
and RDMA_PROD_INDEX to 0. But RDMA_PROD_INDEX cannot be written from
driver side, thus its value was actually not updated, and only
RDMA_CONS_INDEX was reset to 0. This was resulting in a major
synchronization issue between the driver and the device. Most
visible behavior was that the driver seemed to receive again the
packets from the previous commands (e.g. DHCP response packets
"received" again when performing the first TFTP command).

This fix consists in setting RDMA_CONS_INDEX to the same
value as RDMA_PROD_INDEX, when resetting the driver.

The same kind of fix was needed on the TX side, and a few variables
had to be reset accordingly (c_index, tx_index, rx_index).

The rx_index and tx_index have only 256 entries so the bottom 8 bits
must be masked off.

Originated-by: Etienne Dublé 
Signed-off-by: Jason Wessel 
---
 drivers/net/bcmgenet.c | 17 +
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/drivers/net/bcmgenet.c b/drivers/net/bcmgenet.c
index 11b6148ab6..1b7e7ba2bf 100644
--- a/drivers/net/bcmgenet.c
+++ b/drivers/net/bcmgenet.c
@@ -378,8 +378,6 @@ static void rx_descs_init(struct bcmgenet_eth_priv *priv)
u32 len_stat, i;
void *desc_base = priv->rx_desc_base;
 
-   priv->c_index = 0;
-
len_stat = (RX_BUF_LENGTH << DMA_BUFLENGTH_SHIFT) | DMA_OWN;
 
for (i = 0; i < RX_DESCS; i++) {
@@ -403,8 +401,11 @@ static void rx_ring_init(struct bcmgenet_eth_priv *priv)
writel(RX_DESCS * DMA_DESC_SIZE / 4 - 1,
   priv->mac_reg + RDMA_RING_REG_BASE + DMA_END_ADDR);
 
-   writel(0x0, priv->mac_reg + RDMA_PROD_INDEX);
-   writel(0x0, priv->mac_reg + RDMA_CONS_INDEX);
+   /* cannot init RDMA_PROD_INDEX to 0, so align RDMA_CONS_INDEX on it 
instead */
+   priv->c_index = readl(priv->mac_reg + RDMA_PROD_INDEX);
+   writel(priv->c_index, priv->mac_reg + RDMA_CONS_INDEX);
+   priv->rx_index = priv->c_index;
+   priv->rx_index &= 0xFF;
writel((RX_DESCS << DMA_RING_SIZE_SHIFT) | RX_BUF_LENGTH,
   priv->mac_reg + RDMA_RING_REG_BASE + DMA_RING_BUF_SIZE);
writel(DMA_FC_THRESH_VALUE, priv->mac_reg + RDMA_XON_XOFF_THRESH);
@@ -421,8 +422,10 @@ static void tx_ring_init(struct bcmgenet_eth_priv *priv)
writel(0x0, priv->mac_reg + TDMA_WRITE_PTR);
writel(TX_DESCS * DMA_DESC_SIZE / 4 - 1,
   priv->mac_reg + TDMA_RING_REG_BASE + DMA_END_ADDR);
-   writel(0x0, priv->mac_reg + TDMA_PROD_INDEX);
-   writel(0x0, priv->mac_reg + TDMA_CONS_INDEX);
+   /* cannot init TDMA_CONS_INDEX to 0, so align TDMA_PROD_INDEX on it 
instead */
+   priv->tx_index = readl(priv->mac_reg + TDMA_CONS_INDEX);
+   writel(priv->tx_index, priv->mac_reg + TDMA_PROD_INDEX);
+   priv->tx_index &= 0xFF;
writel(0x1, priv->mac_reg + TDMA_RING_REG_BASE + DMA_MBUF_DONE_THRESH);
writel(0x0, priv->mac_reg + TDMA_FLOW_PERIOD);
writel((TX_DESCS << DMA_RING_SIZE_SHIFT) | RX_BUF_LENGTH,
@@ -469,8 +472,6 @@ static int bcmgenet_gmac_eth_start(struct udevice *dev)
 
priv->tx_desc_base = priv->mac_reg + GENET_TX_OFF;
priv->rx_desc_base = priv->mac_reg + GENET_RX_OFF;
-   priv->tx_index = 0x0;
-   priv->rx_index = 0x0;
 
bcmgenet_umac_reset(priv);
 
-- 
2.17.1



[PATCH 2/2] bcmgenet: Add support for rgmii-rxid

2020-07-17 Thread Jason Wessel
The commit 57805f2270c4 ("net: bcmgenet: Don't set ID_MODE_DIS when
not using RGMII") needed to be extended for the case of using the
rgmii-rxid.  The latest version of the Rasbperry Pi4 dtb files for the
5.4 now specify the rgmii-rxid.

Signed-off-by: Jason Wessel 
---
 drivers/net/bcmgenet.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/bcmgenet.c b/drivers/net/bcmgenet.c
index 1b7e7ba2bf..ace1331362 100644
--- a/drivers/net/bcmgenet.c
+++ b/drivers/net/bcmgenet.c
@@ -457,7 +457,8 @@ static int bcmgenet_adjust_link(struct bcmgenet_eth_priv 
*priv)
clrsetbits_32(priv->mac_reg + EXT_RGMII_OOB_CTRL, OOB_DISABLE,
RGMII_LINK | RGMII_MODE_EN);
 
-   if (phy_dev->interface == PHY_INTERFACE_MODE_RGMII)
+   if (phy_dev->interface == PHY_INTERFACE_MODE_RGMII ||
+   phy_dev->interface == PHY_INTERFACE_MODE_RGMII_RXID)
setbits_32(priv->mac_reg + EXT_RGMII_OOB_CTRL, ID_MODE_DIS);
 
writel(speed << CMD_SPEED_SHIFT, (priv->mac_reg + UMAC_CMD));
-- 
2.17.1



Re: [PATCH 1/4] lmb/bdinfo: dump lmb info via bdinfo

2020-07-17 Thread Tero Kristo

On 17/07/2020 16:29, Tom Rini wrote:

On Fri, Jun 12, 2020 at 03:41:18PM +0300, Tero Kristo wrote:


Dump lmb status from the bdinfo command. This is useful for seeing the
reserved memory regions from the u-boot cmdline.

Signed-off-by: Tero Kristo 
---
  cmd/bdinfo.c  |  8 +++-
  include/lmb.h |  1 +
  lib/lmb.c | 42 +++---
  3 files changed, 31 insertions(+), 20 deletions(-)

diff --git a/cmd/bdinfo.c b/cmd/bdinfo.c
index dba552b03f..05e1b27de0 100644
--- a/cmd/bdinfo.c
+++ b/cmd/bdinfo.c
@@ -10,6 +10,7 @@
  #include 
  #include 
  #include 
+#include 
  #include 
  #include 
  #include 
@@ -365,8 +366,13 @@ static int do_bdinfo(struct cmd_tbl *cmdtp, int flag, int 
argc,
  #if CONFIG_IS_ENABLED(MULTI_DTB_FIT)
print_num("multi_dtb_fit", (ulong)gd->multi_dtb_fit);
  #endif
-   if (gd->fdt_blob)
+   if (gd->fdt_blob) {
+   struct lmb lmb;
print_num("fdt_blob", (ulong)gd->fdt_blob);
+   lmb_init_and_reserve(&lmb, gd->bd, (void *)gd->fdt_blob);
+   lmb_dump_all_force(&lmb);
+   }
+
print_cpu_word_size();
  
  	return 0;


Can you please rebase this on top of master?  Simon's series to cleanup
bdinfo stuff has been applied, thanks.  The rest of your changes are
fine and under test now.


Yeah, I can repost this single patch. Thanks for the heads-up.

-Tero

--
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. 
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki


Re: [PATCH v1 1/4] usb: xhci: Add missing endian conversions (cpu_to_leXX / leXX_to_cpu)

2020-07-17 Thread Bin Meng
Hi Stefan,

On Fri, Jul 17, 2020 at 7:34 PM Stefan Roese  wrote:
>
> Hi Bin,
>
> On 17.07.20 13:18, Bin Meng wrote:
> > Hi Stefan,
> >
> > On Thu, Jul 2, 2020 at 4:47 PM Stefan Roese  wrote:
> >>
> >> While trying to use the U-Boot xHCI driver on the MIPS Octeon platform,
> >> which is big endian, I noticed that the driver is missing a few endian
> >> conversion calls. This patch adds these missing endian conversion
> >> calls.
> >>
> >> Signed-off-by: Stefan Roese 
> >> Cc: Bin Meng 
> >> Cc: Marek Vasut 
> >> ---
> >>
> >>   drivers/usb/host/xhci-mem.c | 9 +
> >>   1 file changed, 5 insertions(+), 4 deletions(-)
> >>
> >> diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
> >> index 2d968aafb0..bd959b4093 100644
> >> --- a/drivers/usb/host/xhci-mem.c
> >> +++ b/drivers/usb/host/xhci-mem.c
> >> @@ -110,7 +110,7 @@ static void xhci_scratchpad_free(struct xhci_ctrl 
> >> *ctrl)
> >>
> >>  ctrl->dcbaa->dev_context_ptrs[0] = 0;
> >>
> >> -   free((void *)(uintptr_t)ctrl->scratchpad->sp_array[0]);
> >> +   free((void *)le64_to_cpu(ctrl->scratchpad->sp_array[0]));
> >
> > There is a build warning for this:
> >
> > drivers/usb/host/xhci-mem.c: In function 'xhci_scratchpad_free':
> > drivers/usb/host/xhci-mem.c:113:7: warning: cast to pointer from
> > integer of different size [-Wint-to-pointer-cast]
> >free((void *)le64_to_cpu(ctrl->scratchpad->sp_array[0]));
> > ^
>
> So we need the (uintptr_t) here as well?
>
>free((void *)(uintptr_t)le64_to_cpu(ctrl->scratchpad->sp_array[0]));

I think so.

>
> Should I send v2 for this patch?

Yes, please.

>
> >>  free(ctrl->scratchpad->sp_array);
> >>  free(ctrl->scratchpad);
> >>  ctrl->scratchpad = NULL;
> >> @@ -225,7 +225,8 @@ static void xhci_link_segments(struct xhci_segment 
> >> *prev,
> >>  prev->next = next;
> >>  if (link_trbs) {
> >>  val_64 = (uintptr_t)next->trbs;
> >> -   prev->trbs[TRBS_PER_SEGMENT-1].link.segment_ptr = val_64;
> >> +   prev->trbs[TRBS_PER_SEGMENT-1].link.segment_ptr =
> >> +   cpu_to_le64(val_64);
> >>
> >>  /*
> >>   * Set the last TRB in the segment to
> >> @@ -486,7 +487,7 @@ int xhci_alloc_virt_device(struct xhci_ctrl *ctrl, 
> >> unsigned int slot_id)
> >>  byte_64 = (uintptr_t)(virt_dev->out_ctx->bytes);
> >>
> >>  /* Point to output device context in dcbaa. */
> >> -   ctrl->dcbaa->dev_context_ptrs[slot_id] = byte_64;
> >> +   ctrl->dcbaa->dev_context_ptrs[slot_id] = cpu_to_le64(byte_64);
> >>
> >>  
> >> xhci_flush_cache((uintptr_t)&ctrl->dcbaa->dev_context_ptrs[slot_id],
> >>   sizeof(__le64));
> >> @@ -768,7 +769,7 @@ void xhci_setup_addressable_virt_dev(struct xhci_ctrl 
> >> *ctrl,
> >>
> >>  debug("route string %x\n", route);
> >>   #endif
> >> -   slot_ctx->dev_info |= route;
> >> +   slot_ctx->dev_info |= cpu_to_le32(route);
> >>
> >>  switch (speed) {
> >>  case USB_SPEED_SUPER:
> >> --
> >
> > Test results on Minnowmax which has one USB 2.0 port and one 3.0 port:
> >
> > USB 2.0 flash drive inserted to USB 2.0 port: recognized, read/write OK
> > USB 2.0 flash drive inserted to USB 3.0 port: recognized, read/write OK
> >
> > USB 3.0 flash drive inserted to USB 2.0 port: recognized, read/write OK
> > USB 3.0 flash drive inserted to USB 3.0 port: recognized, read/write OK
> >
> > USB 2.0 flash drive connected to a USB 3.0 HUB inserted to USB 2.0
> > port: recognized, read/write OK
> > USB 2.0 flash drive connected to a USB 3.0 HUB inserted to USB 3.0
> > port: recognized, read/write OK
> >
> > USB 3.0 flash drive connected to a USB 3.0 HUB inserted to USB 2.0
> > port: recognized, read/write OK
> > USB 3.0 flash drive connected to a USB 3.0 HUB inserted to USB 3.0
> > port: recognized, read/write OK
> >
> > Tested-by: Bin Meng 
>
> Very good. :)

Regards,
Bin


[PATCH v2 1/4] usb: xhci: Add missing endian conversions (cpu_to_leXX / leXX_to_cpu)

2020-07-17 Thread Stefan Roese
While trying to use the U-Boot xHCI driver on the MIPS Octeon platform,
which is big endian, I noticed that the driver is missing a few endian
conversion calls. This patch adds these missing endian conversion
calls.

Signed-off-by: Stefan Roese 
Reviewed-by: Bin Meng 
Cc: Bin Meng 
Cc: Marek Vasut 
---
v2:
- Add missing (uintptr_t) cast to remove compile time warning

 drivers/usb/host/xhci-mem.c | 9 +
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 2d968aafb0..7d55944765 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -110,7 +110,7 @@ static void xhci_scratchpad_free(struct xhci_ctrl *ctrl)
 
ctrl->dcbaa->dev_context_ptrs[0] = 0;
 
-   free((void *)(uintptr_t)ctrl->scratchpad->sp_array[0]);
+   free((void *)(uintptr_t)le64_to_cpu(ctrl->scratchpad->sp_array[0]));
free(ctrl->scratchpad->sp_array);
free(ctrl->scratchpad);
ctrl->scratchpad = NULL;
@@ -225,7 +225,8 @@ static void xhci_link_segments(struct xhci_segment *prev,
prev->next = next;
if (link_trbs) {
val_64 = (uintptr_t)next->trbs;
-   prev->trbs[TRBS_PER_SEGMENT-1].link.segment_ptr = val_64;
+   prev->trbs[TRBS_PER_SEGMENT-1].link.segment_ptr =
+   cpu_to_le64(val_64);
 
/*
 * Set the last TRB in the segment to
@@ -486,7 +487,7 @@ int xhci_alloc_virt_device(struct xhci_ctrl *ctrl, unsigned 
int slot_id)
byte_64 = (uintptr_t)(virt_dev->out_ctx->bytes);
 
/* Point to output device context in dcbaa. */
-   ctrl->dcbaa->dev_context_ptrs[slot_id] = byte_64;
+   ctrl->dcbaa->dev_context_ptrs[slot_id] = cpu_to_le64(byte_64);
 
xhci_flush_cache((uintptr_t)&ctrl->dcbaa->dev_context_ptrs[slot_id],
 sizeof(__le64));
@@ -768,7 +769,7 @@ void xhci_setup_addressable_virt_dev(struct xhci_ctrl *ctrl,
 
debug("route string %x\n", route);
 #endif
-   slot_ctx->dev_info |= route;
+   slot_ctx->dev_info |= cpu_to_le32(route);
 
switch (speed) {
case USB_SPEED_SUPER:
-- 
2.27.0



Re: [PATCH v2 1/4] usb: xhci: Add missing endian conversions (cpu_to_leXX / leXX_to_cpu)

2020-07-17 Thread Bin Meng
Hi Stefan,

On Fri, Jul 17, 2020 at 10:04 PM Stefan Roese  wrote:
>
> While trying to use the U-Boot xHCI driver on the MIPS Octeon platform,
> which is big endian, I noticed that the driver is missing a few endian
> conversion calls. This patch adds these missing endian conversion
> calls.
>
> Signed-off-by: Stefan Roese 
> Reviewed-by: Bin Meng 
> Cc: Bin Meng 
> Cc: Marek Vasut 
> ---
> v2:
> - Add missing (uintptr_t) cast to remove compile time warning
>
>  drivers/usb/host/xhci-mem.c | 9 +
>  1 file changed, 5 insertions(+), 4 deletions(-)

Tested-by: Bin Meng 

Only this patch is sent as v2?

Regards,
Bin


[PATCH v6 00/25] x86: Enhance MTRR functionality to support multiple CPUs

2020-07-17 Thread Simon Glass
At present MTRRs are mirrored to the secondary CPUs only once, as those
CPUs are started up. But U-Boot may add more MTRRs later, e.g. if it
decides that a video console must be set up.

This series enhances the x86 multi-processor support to allow MTRRs to
be updated at any time. It also updates the 'mtrr' command to support
setting the MTRRs on CPUs other than the boot CPU.

Changes in v6:
- Rebase to x86/master

Changes in v5:
- Drop timing in mp_park_aps()

Changes in v4:
- Update get_bsp() to return zero when SMP is not inited
- Add a Kconfig to control this feature, enabled only on APL
- Only enable this feature of CONFIG_SMP_AP_WORK is enabled
- Allow running on the BSP if SMP is not enabled
- Update mp_next_cpu() to stop if CONFIG_SMP_AP_WORK is not enabled

Changes in v3:
- Update bsp_do_flight_plan() to say 'on the BSP'
- s/slow/slot/
- Use C code instead of assembler to read/write callback pointers
- Update commit message to mention dropping of cpu_map
- Rename flag to GD_FLG_SMP_READY
- Rename flag to GD_FLG_SMP_READY
- Add a comment to run_ap_work()
- Rename flag to GD_FLG_SMP_READY
- Update the comment for run_ap_work() to explain logical_cpu_number
- Clarify meaning of @cpu_select in mp_run_on_cpus() comment
- Update the comment for mp_park_aps()
- Add more comments on how the iterators work
- Mention that the CPU number is in hex
- Remove stray asterisk from comments
- Drop mention of cpu_map which was handled in a previous patch

Changes in v2:
- Add comments to explain what start_aps() does
- Drop change to include/dm/uclass.h
- Mention error return in get_bsp()
- Add more comments
- Rename mtrr_save_all() to mtrr_read_all()
- Add a new patch to avoid enabling SMP in SPL
- Add new patch to add AP_DEFAULT_BASE to coral's memory map
- Rename function to mtrr_write_all()
- Keep things building by temporarily renaming the function in cmd/
- Drop the renamed mtrr_set_valid_() instead of mtrr_set_valid()
- Add a new patch with more comments

Simon Glass (25):
  x86: mp_init: Switch to livetree
  x86: Move MP code into mp_init
  x86: mp_init: Avoid declarations in header files
  x86: mp_init: Switch parameter names in start_aps()
  x86: mp_init: Drop the num_cpus static variable
  x86: mtrr: Fix 'ensable' typo
  x86: mp_init: Set up the CPU numbers at the start
  x86: mp_init: Adjust bsp_init() to return more information
  x86: cpu: Remove unnecessary #ifdefs
  x86: mp: Support APs waiting for instructions
  global_data: Add a generic global_data flag for SMP state
  x86: Set the SMP flag when MP init is complete
  x86: mp: Allow running functions on multiple CPUs
  x86: mp: Park CPUs before running the OS
  x86: mp: Add iterators for CPUs
  x86: mtrr: Use MP calls to list the MTRRs
  x86: Don't enable SMP in SPL
  x86: coral: Update the memory map
  x86: mtrr: Update MTRRs on all CPUs
  x86: mtrr: Add support for writing to MTRRs on any CPU
  x86: mtrr: Update the command to use the new mtrr calls
  x86: mtrr: Restructure so command execution is in one place
  x86: mtrr: Update 'mtrr' to allow setting MTRRs on any CPU
  x86: mp: Add more comments to the module
  x86: mtrr: Enhance 'mtrr' command to list MTRRs on any CPU

 arch/x86/Kconfig  |   7 +
 arch/x86/cpu/Makefile |   2 +-
 arch/x86/cpu/apollolake/Kconfig   |   1 +
 arch/x86/cpu/cpu.c|  58 +--
 arch/x86/cpu/i386/cpu.c   |  26 +-
 arch/x86/cpu/mp_init.c| 528 ++
 arch/x86/cpu/mtrr.c   | 149 
 arch/x86/include/asm/mp.h | 137 ++-
 arch/x86/include/asm/mtrr.h   |  51 +++
 cmd/x86/mtrr.c| 148 +---
 doc/board/google/chromebook_coral.rst |   1 +
 include/asm-generic/global_data.h |   1 +
 12 files changed, 924 insertions(+), 185 deletions(-)

-- 
2.28.0.rc0.105.gf9edc3c819-goog



[PATCH v6 05/25] x86: mp_init: Drop the num_cpus static variable

2020-07-17 Thread Simon Glass
This does not need to be global across all functions in this file. Pass a
parameter instead.

Signed-off-by: Simon Glass 
Reviewed-by: Wolfgang Wallner 
Reviewed-by: Bin Meng 
---

(no changes since v3)

Changes in v3:
- Update bsp_do_flight_plan() to say 'on the BSP'

 arch/x86/cpu/mp_init.c | 22 +++---
 1 file changed, 15 insertions(+), 7 deletions(-)

diff --git a/arch/x86/cpu/mp_init.c b/arch/x86/cpu/mp_init.c
index 8b00d57c88..df43f71572 100644
--- a/arch/x86/cpu/mp_init.c
+++ b/arch/x86/cpu/mp_init.c
@@ -31,9 +31,6 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-/* Total CPUs include BSP */
-static int num_cpus;
-
 /* This also needs to match the sipi.S assembly code for saved MSR encoding */
 struct saved_msr {
uint32_t index;
@@ -384,13 +381,23 @@ static int start_aps(int num_aps, atomic_t *ap_count)
return 0;
 }
 
-static int bsp_do_flight_plan(struct udevice *cpu, struct mp_flight_plan *plan)
+/**
+ * bsp_do_flight_plan() - Do the flight plan on the BSP
+ *
+ * This runs the flight plan on the main CPU used to boot U-Boot
+ *
+ * @cpu: Device for the main CPU
+ * @plan: Flight plan to run
+ * @num_aps: Number of APs (CPUs other than the BSP)
+ * @returns 0 on success, -ETIMEDOUT if an AP failed to come up
+ */
+static int bsp_do_flight_plan(struct udevice *cpu, struct mp_flight_plan *plan,
+ int num_aps)
 {
int i;
int ret = 0;
const int timeout_us = 10;
const int step_us = 100;
-   int num_aps = num_cpus - 1;
 
for (i = 0; i < plan->num_records; i++) {
struct mp_flight_record *rec = &plan->records[i];
@@ -410,6 +417,7 @@ static int bsp_do_flight_plan(struct udevice *cpu, struct 
mp_flight_plan *plan)
 
release_barrier(&rec->barrier);
}
+
return ret;
 }
 
@@ -454,7 +462,7 @@ static struct mp_flight_record mp_steps[] = {
 
 int mp_init(void)
 {
-   int num_aps;
+   int num_aps, num_cpus;
atomic_t *ap_count;
struct udevice *cpu;
int ret;
@@ -516,7 +524,7 @@ int mp_init(void)
}
 
/* Walk the flight plan for the BSP */
-   ret = bsp_do_flight_plan(cpu, &mp_info);
+   ret = bsp_do_flight_plan(cpu, &mp_info, num_aps);
if (ret) {
debug("CPU init failed: err=%d\n", ret);
return ret;
-- 
2.28.0.rc0.105.gf9edc3c819-goog



[PATCH v6 01/25] x86: mp_init: Switch to livetree

2020-07-17 Thread Simon Glass
Update this code to use livetree calls instead of flat-tree.

Signed-off-by: Simon Glass 
Reviewed-by: Wolfgang Wallner 
Reviewed-by: Bin Meng 
---

(no changes since v1)

 arch/x86/cpu/mp_init.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/arch/x86/cpu/mp_init.c b/arch/x86/cpu/mp_init.c
index 7fde4ff7e1..c25d17c647 100644
--- a/arch/x86/cpu/mp_init.c
+++ b/arch/x86/cpu/mp_init.c
@@ -507,8 +507,7 @@ int mp_init_cpu(struct udevice *cpu, void *unused)
 * seq num in the uclass_resolve_seq() during device_probe(). To avoid
 * this, set req_seq to the reg number in the device tree in advance.
 */
-   cpu->req_seq = fdtdec_get_int(gd->fdt_blob, dev_of_offset(cpu), "reg",
- -1);
+   cpu->req_seq = dev_read_u32_default(cpu, "reg", -1);
plat->ucode_version = microcode_read_rev();
plat->device_id = gd->arch.x86_device;
 
-- 
2.28.0.rc0.105.gf9edc3c819-goog



[PATCH v6 03/25] x86: mp_init: Avoid declarations in header files

2020-07-17 Thread Simon Glass
The functions used by the flight plan are declared in the header file but
are not used in any other file.

Move the flight plan steps down to just above where it is used so that we
can make these function static.

Signed-off-by: Simon Glass 
Reviewed-by: Wolfgang Wallner 
Reviewed-by: Bin Meng 
---

(no changes since v1)

 arch/x86/cpu/mp_init.c| 40 +++
 arch/x86/include/asm/mp.h |  3 ---
 2 files changed, 20 insertions(+), 23 deletions(-)

diff --git a/arch/x86/cpu/mp_init.c b/arch/x86/cpu/mp_init.c
index 831fd7035d..e77d7f2cd6 100644
--- a/arch/x86/cpu/mp_init.c
+++ b/arch/x86/cpu/mp_init.c
@@ -41,10 +41,6 @@ struct saved_msr {
uint32_t hi;
 } __packed;
 
-static struct mp_flight_record mp_steps[] = {
-   MP_FR_BLOCK_APS(mp_init_cpu, NULL, mp_init_cpu, NULL),
-};
-
 struct mp_flight_plan {
int num_records;
struct mp_flight_record *records;
@@ -423,6 +419,26 @@ static int init_bsp(struct udevice **devp)
return 0;
 }
 
+static int mp_init_cpu(struct udevice *cpu, void *unused)
+{
+   struct cpu_platdata *plat = dev_get_parent_platdata(cpu);
+
+   /*
+* Multiple APs are brought up simultaneously and they may get the same
+* seq num in the uclass_resolve_seq() during device_probe(). To avoid
+* this, set req_seq to the reg number in the device tree in advance.
+*/
+   cpu->req_seq = dev_read_u32_default(cpu, "reg", -1);
+   plat->ucode_version = microcode_read_rev();
+   plat->device_id = gd->arch.x86_device;
+
+   return device_probe(cpu);
+}
+
+static struct mp_flight_record mp_steps[] = {
+   MP_FR_BLOCK_APS(mp_init_cpu, NULL, mp_init_cpu, NULL),
+};
+
 int mp_init(void)
 {
int num_aps;
@@ -495,19 +511,3 @@ int mp_init(void)
 
return 0;
 }
-
-int mp_init_cpu(struct udevice *cpu, void *unused)
-{
-   struct cpu_platdata *plat = dev_get_parent_platdata(cpu);
-
-   /*
-* Multiple APs are brought up simultaneously and they may get the same
-* seq num in the uclass_resolve_seq() during device_probe(). To avoid
-* this, set req_seq to the reg number in the device tree in advance.
-*/
-   cpu->req_seq = dev_read_u32_default(cpu, "reg", -1);
-   plat->ucode_version = microcode_read_rev();
-   plat->device_id = gd->arch.x86_device;
-
-   return device_probe(cpu);
-}
diff --git a/arch/x86/include/asm/mp.h b/arch/x86/include/asm/mp.h
index db02904ecb..94af819ad9 100644
--- a/arch/x86/include/asm/mp.h
+++ b/arch/x86/include/asm/mp.h
@@ -72,9 +72,6 @@ struct mp_flight_record {
  */
 int mp_init(void);
 
-/* Probes the CPU device */
-int mp_init_cpu(struct udevice *cpu, void *unused);
-
 /* Set up additional CPUs */
 int x86_mp_init(void);
 
-- 
2.28.0.rc0.105.gf9edc3c819-goog



[PATCH v6 02/25] x86: Move MP code into mp_init

2020-07-17 Thread Simon Glass
At present the 'flight plan' for CPUs is passed into mp_init. But it is
always the same. Move it into the mp_init file so everything is in one
place. Also drop the SMI function since it does nothing. If we implement
SMIs, more refactoring will be needed anyway.

Signed-off-by: Simon Glass 
Reviewed-by: Wolfgang Wallner 
Reviewed-by: Bin Meng 
---

(no changes since v1)

 arch/x86/cpu/i386/cpu.c   | 24 +---
 arch/x86/cpu/mp_init.c| 22 ++
 arch/x86/include/asm/mp.h | 17 +
 3 files changed, 16 insertions(+), 47 deletions(-)

diff --git a/arch/x86/cpu/i386/cpu.c b/arch/x86/cpu/i386/cpu.c
index a6a6afec8c..55a0907bc8 100644
--- a/arch/x86/cpu/i386/cpu.c
+++ b/arch/x86/cpu/i386/cpu.c
@@ -21,6 +21,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -631,29 +632,14 @@ int cpu_jump_to_64bit_uboot(ulong target)
 }
 
 #ifdef CONFIG_SMP
-static int enable_smis(struct udevice *cpu, void *unused)
-{
-   return 0;
-}
-
-static struct mp_flight_record mp_steps[] = {
-   MP_FR_BLOCK_APS(mp_init_cpu, NULL, mp_init_cpu, NULL),
-   /* Wait for APs to finish initialization before proceeding */
-   MP_FR_BLOCK_APS(NULL, NULL, enable_smis, NULL),
-};
-
 int x86_mp_init(void)
 {
-   struct mp_params mp_params;
-
-   mp_params.parallel_microcode_load = 0,
-   mp_params.flight_plan = &mp_steps[0];
-   mp_params.num_records = ARRAY_SIZE(mp_steps);
-   mp_params.microcode_pointer = 0;
+   int ret;
 
-   if (mp_init(&mp_params)) {
+   ret = mp_init();
+   if (ret) {
printf("Warning: MP init failure\n");
-   return -EIO;
+   return log_ret(ret);
}
 
return 0;
diff --git a/arch/x86/cpu/mp_init.c b/arch/x86/cpu/mp_init.c
index c25d17c647..831fd7035d 100644
--- a/arch/x86/cpu/mp_init.c
+++ b/arch/x86/cpu/mp_init.c
@@ -41,6 +41,9 @@ struct saved_msr {
uint32_t hi;
 } __packed;
 
+static struct mp_flight_record mp_steps[] = {
+   MP_FR_BLOCK_APS(mp_init_cpu, NULL, mp_init_cpu, NULL),
+};
 
 struct mp_flight_plan {
int num_records;
@@ -372,7 +375,7 @@ static int start_aps(int ap_count, atomic_t *num_aps)
return 0;
 }
 
-static int bsp_do_flight_plan(struct udevice *cpu, struct mp_params *mp_params)
+static int bsp_do_flight_plan(struct udevice *cpu, struct mp_flight_plan *plan)
 {
int i;
int ret = 0;
@@ -380,8 +383,8 @@ static int bsp_do_flight_plan(struct udevice *cpu, struct 
mp_params *mp_params)
const int step_us = 100;
int num_aps = num_cpus - 1;
 
-   for (i = 0; i < mp_params->num_records; i++) {
-   struct mp_flight_record *rec = &mp_params->flight_plan[i];
+   for (i = 0; i < plan->num_records; i++) {
+   struct mp_flight_record *rec = &plan->records[i];
 
/* Wait for APs if the record is not released */
if (atomic_read(&rec->barrier) == 0) {
@@ -420,7 +423,7 @@ static int init_bsp(struct udevice **devp)
return 0;
 }
 
-int mp_init(struct mp_params *p)
+int mp_init(void)
 {
int num_aps;
atomic_t *ap_count;
@@ -445,11 +448,6 @@ int mp_init(struct mp_params *p)
return ret;
}
 
-   if (p == NULL || p->flight_plan == NULL || p->num_records < 1) {
-   printf("Invalid MP parameters\n");
-   return -EINVAL;
-   }
-
num_cpus = cpu_get_count(cpu);
if (num_cpus < 0) {
debug("Cannot get number of CPUs: err=%d\n", num_cpus);
@@ -464,8 +462,8 @@ int mp_init(struct mp_params *p)
debug("Warning: Device tree does not describe all CPUs. Extra 
ones will not be started correctly\n");
 
/* Copy needed parameters so that APs have a reference to the plan */
-   mp_info.num_records = p->num_records;
-   mp_info.records = p->flight_plan;
+   mp_info.num_records = ARRAY_SIZE(mp_steps);
+   mp_info.records = mp_steps;
 
/* Load the SIPI vector */
ret = load_sipi_vector(&ap_count, num_cpus);
@@ -489,7 +487,7 @@ int mp_init(struct mp_params *p)
}
 
/* Walk the flight plan for the BSP */
-   ret = bsp_do_flight_plan(cpu, p);
+   ret = bsp_do_flight_plan(cpu, &mp_info);
if (ret) {
debug("CPU init failed: err=%d\n", ret);
return ret;
diff --git a/arch/x86/include/asm/mp.h b/arch/x86/include/asm/mp.h
index 9dddf88b5a..db02904ecb 100644
--- a/arch/x86/include/asm/mp.h
+++ b/arch/x86/include/asm/mp.h
@@ -51,21 +51,6 @@ struct mp_flight_record {
 #define MP_FR_NOBLOCK_APS(ap_func, ap_arg, bsp_func, bsp_arg) \
MP_FLIGHT_RECORD(1, ap_func, ap_arg, bsp_func, bsp_arg)
 
-/*
- * The mp_params structure provides the arguments to the mp subsystem
- * for bringing up APs.
- *
- * At present this is overkill for U-Boot, but it may make it easier to add
- * SMM support.
- */
-struct mp_params {
-   int parallel_microc

[PATCH v6 08/25] x86: mp_init: Adjust bsp_init() to return more information

2020-07-17 Thread Simon Glass
This function is misnamed since it does not actually init the BSP. Also
it is convenient to adjust it to return a little more information.

Rename and update the function, to allow it to return the BSP CPU device
and number, as well as the total number of CPUs.

Signed-off-by: Simon Glass 
Reviewed-by: Wolfgang Wallner 
Reviewed-by: Bin Meng 
---

(no changes since v4)

Changes in v4:
- Update get_bsp() to return zero when SMP is not inited

Changes in v2:
- Drop change to include/dm/uclass.h
- Mention error return in get_bsp()

 arch/x86/cpu/mp_init.c | 36 +++-
 1 file changed, 23 insertions(+), 13 deletions(-)

diff --git a/arch/x86/cpu/mp_init.c b/arch/x86/cpu/mp_init.c
index 6f6de49df0..9fdde7832a 100644
--- a/arch/x86/cpu/mp_init.c
+++ b/arch/x86/cpu/mp_init.c
@@ -421,9 +421,18 @@ static int bsp_do_flight_plan(struct udevice *cpu, struct 
mp_flight_plan *plan,
return ret;
 }
 
-static int init_bsp(struct udevice **devp)
+/**
+ * get_bsp() - Get information about the bootstrap processor
+ *
+ * @devp: If non-NULL, returns CPU device corresponding to the BSP
+ * @cpu_countp: If non-NULL, returns the total number of CPUs
+ * @return CPU number of the BSP, or -ve on error. If multiprocessing is not
+ * enabled, returns 0
+ */
+static int get_bsp(struct udevice **devp, int *cpu_countp)
 {
char processor_name[CPU_MAX_NAME_LEN];
+   struct udevice *dev;
int apic_id;
int ret;
 
@@ -431,13 +440,20 @@ static int init_bsp(struct udevice **devp)
debug("CPU: %s\n", processor_name);
 
apic_id = lapicid();
-   ret = find_cpu_by_apic_id(apic_id, devp);
-   if (ret) {
+   ret = find_cpu_by_apic_id(apic_id, &dev);
+   if (ret < 0) {
printf("Cannot find boot CPU, APIC ID %d\n", apic_id);
return ret;
}
+   ret = cpu_get_count(dev);
+   if (ret < 0)
+   return log_msg_ret("count", ret);
+   if (devp)
+   *devp = dev;
+   if (cpu_countp)
+   *cpu_countp = ret;
 
-   return 0;
+   return dev->req_seq >= 0 ? dev->req_seq : 0;
 }
 
 static int mp_init_cpu(struct udevice *cpu, void *unused)
@@ -476,24 +492,18 @@ int mp_init(void)
uclass_id_foreach_dev(UCLASS_CPU, cpu, uc)
cpu->req_seq = dev_read_u32_default(cpu, "reg", -1);
 
-   ret = init_bsp(&cpu);
-   if (ret) {
+   ret = get_bsp(&cpu, &num_cpus);
+   if (ret < 0) {
debug("Cannot init boot CPU: err=%d\n", ret);
return ret;
}
 
-   num_cpus = cpu_get_count(cpu);
-   if (num_cpus < 0) {
-   debug("Cannot get number of CPUs: err=%d\n", num_cpus);
-   return num_cpus;
-   }
-
if (num_cpus < 2)
debug("Warning: Only 1 CPU is detected\n");
 
ret = check_cpu_devices(num_cpus);
if (ret)
-   debug("Warning: Device tree does not describe all CPUs. Extra 
ones will not be started correctly\n");
+   log_warning("Warning: Device tree does not describe all CPUs. 
Extra ones will not be started correctly\n");
 
/* Copy needed parameters so that APs have a reference to the plan */
mp_info.num_records = ARRAY_SIZE(mp_steps);
-- 
2.28.0.rc0.105.gf9edc3c819-goog



[PATCH v6 04/25] x86: mp_init: Switch parameter names in start_aps()

2020-07-17 Thread Simon Glass
These parameters are named differently from elsewhere in this file. Switch
them to avoid confusion.

Also add comments to this function.

Signed-off-by: Simon Glass 
Reviewed-by: Bin Meng 
Reviewed-by: Wolfgang Wallner 
---

(no changes since v2)

Changes in v2:
- Add comments to explain what start_aps() does

 arch/x86/cpu/mp_init.c | 25 +++--
 1 file changed, 19 insertions(+), 6 deletions(-)

diff --git a/arch/x86/cpu/mp_init.c b/arch/x86/cpu/mp_init.c
index e77d7f2cd6..8b00d57c88 100644
--- a/arch/x86/cpu/mp_init.c
+++ b/arch/x86/cpu/mp_init.c
@@ -308,13 +308,26 @@ static int apic_wait_timeout(int total_delay, const char 
*msg)
return 0;
 }
 
-static int start_aps(int ap_count, atomic_t *num_aps)
+/**
+ * start_aps() - Start up the APs and count how many we find
+ *
+ * This is called on the boot processor to start up all the other processors
+ * (here called APs).
+ *
+ * @num_aps: Number of APs we expect to find
+ * @ap_count: Initially zero. Incremented by this function for each AP found
+ * @return 0 if all APs were set up correctly or there are none to set up,
+ * -ENOSPC if the SIPI vector is too high in memory,
+ * -ETIMEDOUT if the ICR is busy or the second SIPI fails to complete
+ * -EIO if not all APs check in correctly
+ */
+static int start_aps(int num_aps, atomic_t *ap_count)
 {
int sipi_vector;
/* Max location is 4KiB below 1MiB */
const int max_vector_loc = ((1 << 20) - (1 << 12)) >> 12;
 
-   if (ap_count == 0)
+   if (num_aps == 0)
return 0;
 
/* The vector is sent as a 4k aligned address in one byte */
@@ -326,7 +339,7 @@ static int start_aps(int ap_count, atomic_t *num_aps)
return -ENOSPC;
}
 
-   debug("Attempting to start %d APs\n", ap_count);
+   debug("Attempting to start %d APs\n", num_aps);
 
if (apic_wait_timeout(1000, "ICR not to be busy"))
return -ETIMEDOUT;
@@ -349,7 +362,7 @@ static int start_aps(int ap_count, atomic_t *num_aps)
return -ETIMEDOUT;
 
/* Wait for CPUs to check in up to 200 us */
-   wait_for_aps(num_aps, ap_count, 200, 15);
+   wait_for_aps(ap_count, num_aps, 200, 15);
 
/* Send 2nd SIPI */
if (apic_wait_timeout(1000, "ICR not to be busy"))
@@ -362,9 +375,9 @@ static int start_aps(int ap_count, atomic_t *num_aps)
return -ETIMEDOUT;
 
/* Wait for CPUs to check in */
-   if (wait_for_aps(num_aps, ap_count, 1, 50)) {
+   if (wait_for_aps(ap_count, num_aps, 1, 50)) {
debug("Not all APs checked in: %d/%d\n",
- atomic_read(num_aps), ap_count);
+ atomic_read(ap_count), num_aps);
return -EIO;
}
 
-- 
2.28.0.rc0.105.gf9edc3c819-goog



[PATCH v6 07/25] x86: mp_init: Set up the CPU numbers at the start

2020-07-17 Thread Simon Glass
At present each CPU is given a number when it starts itself up. While this
saves a tiny amount of time by doing the device-tree read in parallel, it
is confusing that the numbering happens on the fly.

Move this code into mp_init() and do it at the start.

Signed-off-by: Simon Glass 
Reviewed-by: Wolfgang Wallner 
Reviewed-by: Bin Meng 
---

(no changes since v1)

 arch/x86/cpu/mp_init.c | 21 +
 1 file changed, 9 insertions(+), 12 deletions(-)

diff --git a/arch/x86/cpu/mp_init.c b/arch/x86/cpu/mp_init.c
index df43f71572..6f6de49df0 100644
--- a/arch/x86/cpu/mp_init.c
+++ b/arch/x86/cpu/mp_init.c
@@ -444,12 +444,6 @@ static int mp_init_cpu(struct udevice *cpu, void *unused)
 {
struct cpu_platdata *plat = dev_get_parent_platdata(cpu);
 
-   /*
-* Multiple APs are brought up simultaneously and they may get the same
-* seq num in the uclass_resolve_seq() during device_probe(). To avoid
-* this, set req_seq to the reg number in the device tree in advance.
-*/
-   cpu->req_seq = dev_read_u32_default(cpu, "reg", -1);
plat->ucode_version = microcode_read_rev();
plat->device_id = gd->arch.x86_device;
 
@@ -465,13 +459,8 @@ int mp_init(void)
int num_aps, num_cpus;
atomic_t *ap_count;
struct udevice *cpu;
-   int ret;
-
-   /* This will cause the CPUs devices to be bound */
struct uclass *uc;
-   ret = uclass_get(UCLASS_CPU, &uc);
-   if (ret)
-   return ret;
+   int ret;
 
if (IS_ENABLED(CONFIG_QFW)) {
ret = qemu_cpu_fixup();
@@ -479,6 +468,14 @@ int mp_init(void)
return ret;
}
 
+   /*
+* Multiple APs are brought up simultaneously and they may get the same
+* seq num in the uclass_resolve_seq() during device_probe(). To avoid
+* this, set req_seq to the reg number in the device tree in advance.
+*/
+   uclass_id_foreach_dev(UCLASS_CPU, cpu, uc)
+   cpu->req_seq = dev_read_u32_default(cpu, "reg", -1);
+
ret = init_bsp(&cpu);
if (ret) {
debug("Cannot init boot CPU: err=%d\n", ret);
-- 
2.28.0.rc0.105.gf9edc3c819-goog



[PATCH v6 06/25] x86: mtrr: Fix 'ensable' typo

2020-07-17 Thread Simon Glass
Fix a typo in the command help.

Signed-off-by: Simon Glass 
Reviewed-by: Wolfgang Wallner 
Reviewed-by: Bin Meng 
---

(no changes since v1)

 cmd/x86/mtrr.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/cmd/x86/mtrr.c b/cmd/x86/mtrr.c
index 084d7315f4..5d25c5802a 100644
--- a/cmd/x86/mtrr.c
+++ b/cmd/x86/mtrr.c
@@ -135,5 +135,5 @@ U_BOOT_CMD(
"set   - set a register\n"
"\t is Uncacheable, Combine, Through, Protect, Back\n"
"disable   - disable a register\n"
-   "ensable   - enable a register"
+   "enable- enable a register"
 );
-- 
2.28.0.rc0.105.gf9edc3c819-goog



[PATCH v6 09/25] x86: cpu: Remove unnecessary #ifdefs

2020-07-17 Thread Simon Glass
Drop some #ifdefs that are not needed or can be converted to compile-time
checks.

Signed-off-by: Simon Glass 
Reviewed-by: Wolfgang Wallner 
Reviewed-by: Bin Meng 
---

(no changes since v1)

 arch/x86/cpu/cpu.c  | 53 -
 arch/x86/cpu/i386/cpu.c |  2 --
 2 files changed, 26 insertions(+), 29 deletions(-)

diff --git a/arch/x86/cpu/cpu.c b/arch/x86/cpu/cpu.c
index 98ed66e67d..c343586e04 100644
--- a/arch/x86/cpu/cpu.c
+++ b/arch/x86/cpu/cpu.c
@@ -67,10 +67,8 @@ static const char *const x86_vendor_name[] = {
 
 int __weak x86_cleanup_before_linux(void)
 {
-#ifdef CONFIG_BOOTSTAGE_STASH
bootstage_stash((void *)CONFIG_BOOTSTAGE_STASH_ADDR,
CONFIG_BOOTSTAGE_STASH_SIZE);
-#endif
 
return 0;
 }
@@ -201,18 +199,19 @@ int last_stage_init(void)
 
write_tables();
 
-#ifdef CONFIG_GENERATE_ACPI_TABLE
-   fadt = acpi_find_fadt();
+   if (IS_ENABLED(CONFIG_GENERATE_ACPI_TABLE)) {
+   fadt = acpi_find_fadt();
 
-   /* Don't touch ACPI hardware on HW reduced platforms */
-   if (fadt && !(fadt->flags & ACPI_FADT_HW_REDUCED_ACPI)) {
-   /*
-* Other than waiting for OSPM to request us to switch to ACPI
-* mode, do it by ourselves, since SMI will not be triggered.
-*/
-   enter_acpi_mode(fadt->pm1a_cnt_blk);
+   /* Don't touch ACPI hardware on HW reduced platforms */
+   if (fadt && !(fadt->flags & ACPI_FADT_HW_REDUCED_ACPI)) {
+   /*
+* Other than waiting for OSPM to request us to switch
+* to ACPI * mode, do it by ourselves, since SMI will
+* not be triggered.
+*/
+   enter_acpi_mode(fadt->pm1a_cnt_blk);
+   }
}
-#endif
 
return 0;
 }
@@ -220,19 +219,20 @@ int last_stage_init(void)
 
 static int x86_init_cpus(void)
 {
-#ifdef CONFIG_SMP
-   debug("Init additional CPUs\n");
-   x86_mp_init();
-#else
-   struct udevice *dev;
+   if (IS_ENABLED(CONFIG_SMP)) {
+   debug("Init additional CPUs\n");
+   x86_mp_init();
+   } else {
+   struct udevice *dev;
 
-   /*
-* This causes the cpu-x86 driver to be probed.
-* We don't check return value here as we want to allow boards
-* which have not been converted to use cpu uclass driver to boot.
-*/
-   uclass_first_device(UCLASS_CPU, &dev);
-#endif
+   /*
+* This causes the cpu-x86 driver to be probed.
+* We don't check return value here as we want to allow boards
+* which have not been converted to use cpu uclass driver to
+* boot.
+*/
+   uclass_first_device(UCLASS_CPU, &dev);
+   }
 
return 0;
 }
@@ -276,9 +276,8 @@ int reserve_arch(void)
if (IS_ENABLED(CONFIG_ENABLE_MRC_CACHE))
mrccache_reserve();
 
-#ifdef CONFIG_SEABIOS
-   high_table_reserve();
-#endif
+   if (IS_ENABLED(CONFIG_SEABIOS))
+   high_table_reserve();
 
if (IS_ENABLED(CONFIG_HAVE_ACPI_RESUME)) {
acpi_s3_reserve();
diff --git a/arch/x86/cpu/i386/cpu.c b/arch/x86/cpu/i386/cpu.c
index 55a0907bc8..8f342dd06e 100644
--- a/arch/x86/cpu/i386/cpu.c
+++ b/arch/x86/cpu/i386/cpu.c
@@ -631,7 +631,6 @@ int cpu_jump_to_64bit_uboot(ulong target)
return -EFAULT;
 }
 
-#ifdef CONFIG_SMP
 int x86_mp_init(void)
 {
int ret;
@@ -644,4 +643,3 @@ int x86_mp_init(void)
 
return 0;
 }
-#endif
-- 
2.28.0.rc0.105.gf9edc3c819-goog



[PATCH v6 10/25] x86: mp: Support APs waiting for instructions

2020-07-17 Thread Simon Glass
At present the APs (non-boot CPUs) are inited once and then parked ready
for the OS to use them. However in some cases we want to send new requests
through, such as to change MTRRs and keep them consistent across CPUs.

Change the last state of the flight plan to go into a wait loop, accepting
instructions from the main CPU.

Drop cpu_map since it is not used.

Signed-off-by: Simon Glass 
Reviewed-by: Wolfgang Wallner 
---

(no changes since v4)

Changes in v4:
- Add a Kconfig to control this feature, enabled only on APL

Changes in v3:
- s/slow/slot/
- Use C code instead of assembler to read/write callback pointers
- Update commit message to mention dropping of cpu_map

Changes in v2:
- Add more comments

 arch/x86/Kconfig|   7 ++
 arch/x86/cpu/apollolake/Kconfig |   1 +
 arch/x86/cpu/mp_init.c  | 123 +---
 arch/x86/include/asm/mp.h   |  11 +++
 4 files changed, 134 insertions(+), 8 deletions(-)

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 27295ef384..ff4f06ed79 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -603,6 +603,13 @@ config SMP
  only one CPU will be enabled regardless of the number of CPUs
  available.
 
+config SMP_AP_WORK
+   bool
+   depends on SMP
+   help
+Allow APs to do other work after initialisation instead of going
+to sleep.
+
 config MAX_CPUS
int "Maximum number of CPUs permitted"
depends on SMP
diff --git a/arch/x86/cpu/apollolake/Kconfig b/arch/x86/cpu/apollolake/Kconfig
index 942f11f566..99d4e105c2 100644
--- a/arch/x86/cpu/apollolake/Kconfig
+++ b/arch/x86/cpu/apollolake/Kconfig
@@ -15,6 +15,7 @@ config INTEL_APOLLOLAKE
select TPL_PCH_SUPPORT
select PCH_SUPPORT
select P2SB
+   select SMP_AP_WORK
imply ENABLE_MRC_CACHE
imply AHCI_PCI
imply SCSI
diff --git a/arch/x86/cpu/mp_init.c b/arch/x86/cpu/mp_init.c
index 9fdde7832a..787de92fa3 100644
--- a/arch/x86/cpu/mp_init.c
+++ b/arch/x86/cpu/mp_init.c
@@ -15,6 +15,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -43,13 +44,38 @@ struct mp_flight_plan {
struct mp_flight_record *records;
 };
 
+/**
+ * struct mp_callback - Callback information for APs
+ *
+ * @func: Function to run
+ * @arg: Argument to pass to the function
+ * @logical_cpu_number: Either a CPU number (i.e. dev->req_seq) or a special
+ * value like MP_SELECT_BSP. It tells the AP whether it should process this
+ * callback
+ */
+struct mp_callback {
+   /**
+* func() - Function to call on the AP
+*
+* @arg: Argument to pass
+*/
+   void (*func)(void *arg);
+   void *arg;
+   int logical_cpu_number;
+};
+
 static struct mp_flight_plan mp_info;
 
-struct cpu_map {
-   struct udevice *dev;
-   int apic_id;
-   int err_code;
-};
+/*
+ * ap_callbacks - Callback mailbox array
+ *
+ * Array of callback, one entry for each available CPU, indexed by the CPU
+ * number, which is dev->req_seq. The entry for the main CPU is never used.
+ * When this is NULL, there is no pending work for the CPU to run. When
+ * non-NULL it points to the mp_callback structure. This is shared between all
+ * CPUs, so should only be written by the main CPU.
+ */
+static struct mp_callback **ap_callbacks;
 
 static inline void barrier_wait(atomic_t *b)
 {
@@ -147,11 +173,12 @@ static void ap_init(unsigned int cpu_index)
debug("AP: slot %d apic_id %x, dev %s\n", cpu_index, apic_id,
  dev ? dev->name : "(apic_id not found)");
 
-   /* Walk the flight plan */
+   /*
+* Walk the flight plan, which only returns if CONFIG_SMP_AP_WORK is not
+* enabled
+*/
ap_do_flight_plan(dev);
 
-   /* Park the AP */
-   debug("parking\n");
 done:
stop_this_cpu();
 }
@@ -456,6 +483,81 @@ static int get_bsp(struct udevice **devp, int *cpu_countp)
return dev->req_seq >= 0 ? dev->req_seq : 0;
 }
 
+/**
+ * read_callback() - Read the pointer in a callback slot
+ *
+ * This is called by APs to read their callback slot to see if there is a
+ * pointer to new instructions
+ *
+ * @slot: Pointer to the AP's callback slot
+ * @return value of that pointer
+ */
+static struct mp_callback *read_callback(struct mp_callback **slot)
+{
+   dmb();
+
+   return *slot;
+}
+
+/**
+ * store_callback() - Store a pointer to the callback slot
+ *
+ * This is called by APs to write NULL into the callback slot when they have
+ * finished the work requested by the BSP.
+ *
+ * @slot: Pointer to the AP's callback slot
+ * @val: Value to write (e.g. NULL)
+ */
+static void store_callback(struct mp_callback **slot, struct mp_callback *val)
+{
+   *slot = val;
+   dmb();
+}
+
+/**
+ * ap_wait_for_instruction() - Wait for and process requests from the main CPU
+ *
+ * This is called by APs (here, everything other than the main boot CPU) to
+ * await instructions

[PATCH v6 12/25] x86: Set the SMP flag when MP init is complete

2020-07-17 Thread Simon Glass
Set this flag so we can track when it is safe to use CPUs other than the
main one.

Signed-off-by: Simon Glass 
Reviewed-by: Wolfgang Wallner 
Reviewed-by: Bin Meng 
---

(no changes since v3)

Changes in v3:
- Rename flag to GD_FLG_SMP_READY

 arch/x86/cpu/mp_init.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/x86/cpu/mp_init.c b/arch/x86/cpu/mp_init.c
index 787de92fa3..69a23829b9 100644
--- a/arch/x86/cpu/mp_init.c
+++ b/arch/x86/cpu/mp_init.c
@@ -643,6 +643,7 @@ int mp_init(void)
debug("CPU init failed: err=%d\n", ret);
return ret;
}
+   gd->flags |= GD_FLG_SMP_READY;
 
return 0;
 }
-- 
2.28.0.rc0.105.gf9edc3c819-goog



[PATCH v6 13/25] x86: mp: Allow running functions on multiple CPUs

2020-07-17 Thread Simon Glass
Add a way to run a function on a selection of CPUs. This supports either
a single CPU, all CPUs, just the main CPU or just the 'APs', in Intel
terminology.

It works by writing into a mailbox and then waiting for the CPUs to notice
it, take action and indicate they are done.

When SMP is not yet enabled, this just calls the function on the main CPU.

Signed-off-by: Simon Glass 
Reviewed-by: Wolfgang Wallner 
---

(no changes since v4)

Changes in v4:
- Only enable this feature of CONFIG_SMP_AP_WORK is enabled
- Allow running on the BSP if SMP is not enabled

Changes in v3:
- Add a comment to run_ap_work()
- Rename flag to GD_FLG_SMP_READY
- Update the comment for run_ap_work() to explain logical_cpu_number
- Clarify meaning of @cpu_select in mp_run_on_cpus() comment

 arch/x86/cpu/mp_init.c| 107 +++---
 arch/x86/include/asm/mp.h |  33 
 2 files changed, 134 insertions(+), 6 deletions(-)

diff --git a/arch/x86/cpu/mp_init.c b/arch/x86/cpu/mp_init.c
index 69a23829b9..dd6d6bfab7 100644
--- a/arch/x86/cpu/mp_init.c
+++ b/arch/x86/cpu/mp_init.c
@@ -54,12 +54,7 @@ struct mp_flight_plan {
  * callback
  */
 struct mp_callback {
-   /**
-* func() - Function to call on the AP
-*
-* @arg: Argument to pass
-*/
-   void (*func)(void *arg);
+   mp_run_func func;
void *arg;
int logical_cpu_number;
 };
@@ -514,6 +509,70 @@ static void store_callback(struct mp_callback **slot, 
struct mp_callback *val)
dmb();
 }
 
+/**
+ * run_ap_work() - Run a callback on selected APs
+ *
+ * This writes @callback to all APs and waits for them all to acknowledge it,
+ * Note that whether each AP actually calls the callback depends on the value
+ * of logical_cpu_number (see struct mp_callback). The logical CPU number is
+ * the CPU device's req->seq value.
+ *
+ * @callback: Callback information to pass to all APs
+ * @bsp: CPU device for the BSP
+ * @num_cpus: The number of CPUs in the system (= number of APs + 1)
+ * @expire_ms: Timeout to wait for all APs to finish, in milliseconds, or 0 for
+ * no timeout
+ * @return 0 if OK, -ETIMEDOUT if one or more APs failed to respond in time
+ */
+static int run_ap_work(struct mp_callback *callback, struct udevice *bsp,
+  int num_cpus, uint expire_ms)
+{
+   int cur_cpu = bsp->req_seq;
+   int num_aps = num_cpus - 1; /* number of non-BSPs to get this message */
+   int cpus_accepted;
+   ulong start;
+   int i;
+
+   if (!IS_ENABLED(CONFIG_SMP_AP_WORK)) {
+   printf("APs already parked. CONFIG_SMP_AP_WORK not enabled\n");
+   return -ENOTSUPP;
+   }
+
+   /* Signal to all the APs to run the func. */
+   for (i = 0; i < num_cpus; i++) {
+   if (cur_cpu != i)
+   store_callback(&ap_callbacks[i], callback);
+   }
+   mfence();
+
+   /* Wait for all the APs to signal back that call has been accepted. */
+   start = get_timer(0);
+
+   do {
+   mdelay(1);
+   cpus_accepted = 0;
+
+   for (i = 0; i < num_cpus; i++) {
+   if (cur_cpu == i)
+   continue;
+   if (!read_callback(&ap_callbacks[i]))
+   cpus_accepted++;
+   }
+
+   if (expire_ms && get_timer(start) >= expire_ms) {
+   log(UCLASS_CPU, LOGL_CRIT,
+   "AP call expired; %d/%d CPUs accepted\n",
+   cpus_accepted, num_aps);
+   return -ETIMEDOUT;
+   }
+   } while (cpus_accepted != num_aps);
+
+   /* Make sure we can see any data written by the APs */
+   mfence();
+
+   return 0;
+}
+
 /**
  * ap_wait_for_instruction() - Wait for and process requests from the main CPU
  *
@@ -573,6 +632,42 @@ static struct mp_flight_record mp_steps[] = {
MP_FR_BLOCK_APS(ap_wait_for_instruction, NULL, NULL, NULL),
 };
 
+int mp_run_on_cpus(int cpu_select, mp_run_func func, void *arg)
+{
+   struct mp_callback lcb = {
+   .func = func,
+   .arg = arg,
+   .logical_cpu_number = cpu_select,
+   };
+   struct udevice *dev;
+   int num_cpus;
+   int ret;
+
+   ret = get_bsp(&dev, &num_cpus);
+   if (ret < 0)
+   return log_msg_ret("bsp", ret);
+   if (cpu_select == MP_SELECT_ALL || cpu_select == MP_SELECT_BSP ||
+   cpu_select == ret) {
+   /* Run on BSP first */
+   func(arg);
+   }
+
+   if (!IS_ENABLED(CONFIG_SMP_AP_WORK) ||
+   !(gd->flags & GD_FLG_SMP_READY)) {
+   /* Allow use of this function on the BSP only */
+   if (cpu_select == MP_SELECT_BSP || !cpu_select)
+   return 0;
+   return -ENOTSUPP;
+   }
+
+   /* Allow up to 1 second for all APs 

[PATCH v6 11/25] global_data: Add a generic global_data flag for SMP state

2020-07-17 Thread Simon Glass
Allow keeping track of whether all CPUs have been enabled yet. This allows
us to know whether other CPUs need to be considered when updating
CPU-specific settings such as MTRRs on x86.

Signed-off-by: Simon Glass 
Reviewed-by: Wolfgang Wallner 
---

(no changes since v3)

Changes in v3:
- Rename flag to GD_FLG_SMP_READY

 include/asm-generic/global_data.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/asm-generic/global_data.h 
b/include/asm-generic/global_data.h
index 8c78792cc9..d4a4e2215d 100644
--- a/include/asm-generic/global_data.h
+++ b/include/asm-generic/global_data.h
@@ -167,5 +167,6 @@ typedef struct global_data {
 #define GD_FLG_LOG_READY   0x08000 /* Log system is ready for use */
 #define GD_FLG_WDT_READY   0x1 /* Watchdog is ready for use   */
 #define GD_FLG_SKIP_LL_INIT0x2 /* Don't perform low-level init*/
+#define GD_FLG_SMP_READY   0x4 /* SMP init is complete*/
 
 #endif /* __ASM_GENERIC_GBL_DATA_H */
-- 
2.28.0.rc0.105.gf9edc3c819-goog



[PATCH v6 17/25] x86: Don't enable SMP in SPL

2020-07-17 Thread Simon Glass
SMP should be set up in U-Boot where possible, not SPL. Disable it in SPL.
For 64-bit U-Boot we should find a way to allow SMP operations in U-Boot,
but this is somewhat more complicated. For now that is disabled too.

Signed-off-by: Simon Glass 
Reviewed-by: Bin Meng 
Reviewed-by: Wolfgang Wallner 
---

(no changes since v2)

Changes in v2:
- Add a new patch to avoid enabling SMP in SPL

 arch/x86/cpu/Makefile | 2 +-
 arch/x86/include/asm/mp.h | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/x86/cpu/Makefile b/arch/x86/cpu/Makefile
index ee0499f5d7..16e67e3da2 100644
--- a/arch/x86/cpu/Makefile
+++ b/arch/x86/cpu/Makefile
@@ -60,7 +60,7 @@ ifndef CONFIG_SYS_COREBOOT
 obj-$(CONFIG_$(SPL_TPL_)X86_32BIT_INIT) += irq.o
 endif
 ifndef CONFIG_$(SPL_)X86_64
-obj-$(CONFIG_SMP) += mp_init.o
+obj-$(CONFIG_$(SPL_)SMP) += mp_init.o
 endif
 obj-y += mtrr.o
 obj-$(CONFIG_PCI) += pci.o
diff --git a/arch/x86/include/asm/mp.h b/arch/x86/include/asm/mp.h
index 9379826b6b..ff49004222 100644
--- a/arch/x86/include/asm/mp.h
+++ b/arch/x86/include/asm/mp.h
@@ -93,7 +93,7 @@ int x86_mp_init(void);
  */
 typedef void (*mp_run_func)(void *arg);
 
-#if defined(CONFIG_SMP) && !CONFIG_IS_ENABLED(X86_64)
+#if CONFIG_IS_ENABLED(SMP) && !CONFIG_IS_ENABLED(X86_64)
 /**
  * mp_run_on_cpus() - Run a function on one or all CPUs
  *
-- 
2.28.0.rc0.105.gf9edc3c819-goog



[PATCH v6 21/25] x86: mtrr: Update the command to use the new mtrr calls

2020-07-17 Thread Simon Glass
Use the multi-CPU calls to set the MTRR values. This still supports only
the boot CPU for now.

Signed-off-by: Simon Glass 
Reviewed-by: Wolfgang Wallner 
Reviewed-by: Bin Meng 
---

(no changes since v2)

Changes in v2:
- Drop the renamed mtrr_set_valid_() instead of mtrr_set_valid()

 cmd/x86/mtrr.c | 34 --
 1 file changed, 8 insertions(+), 26 deletions(-)

diff --git a/cmd/x86/mtrr.c b/cmd/x86/mtrr.c
index 46ef6a2830..b047a9897c 100644
--- a/cmd/x86/mtrr.c
+++ b/cmd/x86/mtrr.c
@@ -59,14 +59,14 @@ static int do_mtrr_list(int cpu_select)
return 0;
 }
 
-static int do_mtrr_set(uint reg, int argc, char *const argv[])
+static int do_mtrr_set(int cpu_select, uint reg, int argc, char *const argv[])
 {
const char *typename = argv[0];
-   struct mtrr_state state;
uint32_t start, size;
uint64_t base, mask;
int i, type = -1;
bool valid;
+   int ret;
 
if (argc < 3)
return CMD_RET_USAGE;
@@ -88,27 +88,9 @@ static int do_mtrr_set(uint reg, int argc, char *const 
argv[])
if (valid)
mask |= MTRR_PHYS_MASK_VALID;
 
-   mtrr_open(&state, true);
-   wrmsrl(MTRR_PHYS_BASE_MSR(reg), base);
-   wrmsrl(MTRR_PHYS_MASK_MSR(reg), mask);
-   mtrr_close(&state, true);
-
-   return 0;
-}
-
-static int mtrr_set_valid_(int reg, bool valid)
-{
-   struct mtrr_state state;
-   uint64_t mask;
-
-   mtrr_open(&state, true);
-   mask = native_read_msr(MTRR_PHYS_MASK_MSR(reg));
-   if (valid)
-   mask |= MTRR_PHYS_MASK_VALID;
-   else
-   mask &= ~MTRR_PHYS_MASK_VALID;
-   wrmsrl(MTRR_PHYS_MASK_MSR(reg), mask);
-   mtrr_close(&state, true);
+   ret = mtrr_set(cpu_select, reg, base, mask);
+   if (ret)
+   return CMD_RET_FAILURE;
 
return 0;
 }
@@ -134,11 +116,11 @@ static int do_mtrr(struct cmd_tbl *cmdtp, int flag, int 
argc,
return CMD_RET_USAGE;
}
if (*cmd == 'e')
-   return mtrr_set_valid_(reg, true);
+   return mtrr_set_valid(cpu_select, reg, true);
else if (*cmd == 'd')
-   return mtrr_set_valid_(reg, false);
+   return mtrr_set_valid(cpu_select, reg, false);
else if (*cmd == 's')
-   return do_mtrr_set(reg, argc - 1, argv + 1);
+   return do_mtrr_set(cpu_select, reg, argc - 1, argv + 1);
else
return CMD_RET_USAGE;
 
-- 
2.28.0.rc0.105.gf9edc3c819-goog



[PATCH v6 15/25] x86: mp: Add iterators for CPUs

2020-07-17 Thread Simon Glass
It is convenient to iterate through the CPUs performing work on each one
and processing the result. Add a few iterator functions which handle this.
These can be used by any client code. It can call mp_run_on_cpus() on
each CPU that is returned, handling them one at a time.

Signed-off-by: Simon Glass 
Reviewed-by: Wolfgang Wallner 
---

(no changes since v4)

Changes in v4:
- Update mp_next_cpu() to stop if CONFIG_SMP_AP_WORK is not enabled

Changes in v3:
- Add more comments on how the iterators work

 arch/x86/cpu/mp_init.c| 63 +++
 arch/x86/include/asm/mp.h | 42 ++
 2 files changed, 105 insertions(+)

diff --git a/arch/x86/cpu/mp_init.c b/arch/x86/cpu/mp_init.c
index 427ec8fc23..c373c3099a 100644
--- a/arch/x86/cpu/mp_init.c
+++ b/arch/x86/cpu/mp_init.c
@@ -684,6 +684,69 @@ int mp_park_aps(void)
return 0;
 }
 
+int mp_first_cpu(int cpu_select)
+{
+   struct udevice *dev;
+   int num_cpus;
+   int ret;
+
+   /*
+* This assumes that CPUs are numbered from 0. This function tries to
+* avoid assuming the CPU 0 is the boot CPU
+*/
+   if (cpu_select == MP_SELECT_ALL)
+   return 0;   /* start with the first one */
+
+   ret = get_bsp(&dev, &num_cpus);
+   if (ret < 0)
+   return log_msg_ret("bsp", ret);
+
+   /* Return boot CPU if requested */
+   if (cpu_select == MP_SELECT_BSP)
+   return ret;
+
+   /* Return something other than the boot CPU, if APs requested */
+   if (cpu_select == MP_SELECT_APS && num_cpus > 1)
+   return ret == 0 ? 1 : 0;
+
+   /* Try to check for an invalid value */
+   if (cpu_select < 0 || cpu_select >= num_cpus)
+   return -EINVAL;
+
+   return cpu_select;  /* return the only selected one */
+}
+
+int mp_next_cpu(int cpu_select, int prev_cpu)
+{
+   struct udevice *dev;
+   int num_cpus;
+   int ret;
+   int bsp;
+
+   /* If we selected the BSP or a particular single CPU, we are done */
+   if (!IS_ENABLED(CONFIG_SMP_AP_WORK) || cpu_select == MP_SELECT_BSP ||
+   cpu_select >= 0)
+   return -EFBIG;
+
+   /* Must be doing MP_SELECT_ALL or MP_SELECT_APS; return the next CPU */
+   ret = get_bsp(&dev, &num_cpus);
+   if (ret < 0)
+   return log_msg_ret("bsp", ret);
+   bsp = ret;
+
+   /* Move to the next CPU */
+   assert(prev_cpu >= 0);
+   ret = prev_cpu + 1;
+
+   /* Skip the BSP if needed */
+   if (cpu_select == MP_SELECT_APS && ret == bsp)
+   ret++;
+   if (ret >= num_cpus)
+   return -EFBIG;
+
+   return ret;
+}
+
 int mp_init(void)
 {
int num_aps, num_cpus;
diff --git a/arch/x86/include/asm/mp.h b/arch/x86/include/asm/mp.h
index f9d6c8e6bf..9379826b6b 100644
--- a/arch/x86/include/asm/mp.h
+++ b/arch/x86/include/asm/mp.h
@@ -118,6 +118,33 @@ int mp_run_on_cpus(int cpu_select, mp_run_func func, void 
*arg);
  * @return 0 if OK, -ve on error
  */
 int mp_park_aps(void);
+
+/**
+ * mp_first_cpu() - Get the first CPU to process, from a selection
+ *
+ * This is used to iterate through selected CPUs. Call this function first, 
then
+ * call mp_next_cpu() repeatedly (with the same @cpu_select) until it returns
+ * -EFBIG.
+ *
+ * @cpu_select: Selected CPUs (either a CPU number or MP_SELECT_...)
+ * @return next CPU number to run on (e.g. 0)
+ */
+int mp_first_cpu(int cpu_select);
+
+/**
+ * mp_next_cpu() - Get the next CPU to process, from a selection
+ *
+ * This is used to iterate through selected CPUs. After first calling
+ * mp_first_cpu() once, call this function repeatedly until it returns -EFBIG.
+ *
+ * The value of @cpu_select must be the same for all calls and must match the
+ * value passed to mp_first_cpu(), otherwise the behaviour is undefined.
+ *
+ * @cpu_select: Selected CPUs (either a CPU number or MP_SELECT_...)
+ * @prev_cpu: Previous value returned by mp_first_cpu()/mp_next_cpu()
+ * @return next CPU number to run on (e.g. 0)
+ */
+int mp_next_cpu(int cpu_select, int prev_cpu);
 #else
 static inline int mp_run_on_cpus(int cpu_select, mp_run_func func, void *arg)
 {
@@ -134,6 +161,21 @@ static inline int mp_park_aps(void)
return 0;
 }
 
+static inline int mp_first_cpu(int cpu_select)
+{
+   /* We cannot run on any APs, nor a selected CPU */
+   return cpu_select == MP_SELECT_APS ? -EFBIG : MP_SELECT_BSP;
+}
+
+static inline int mp_next_cpu(int cpu_select, int prev_cpu)
+{
+   /*
+* When MP is not enabled, there is only one CPU and we did it in
+* mp_first_cpu()
+*/
+   return -EFBIG;
+}
+
 #endif
 
 #endif /* _X86_MP_H_ */
-- 
2.28.0.rc0.105.gf9edc3c819-goog



[PATCH v6 19/25] x86: mtrr: Update MTRRs on all CPUs

2020-07-17 Thread Simon Glass
When the boot CPU MTRRs are updated, perform the same update on all other
CPUs so they are kept in sync.

This avoids kernel warnings about mismatched MTRRs.

Signed-off-by: Simon Glass 
Reviewed-by: Wolfgang Wallner 
---

(no changes since v2)

Changes in v2:
- Rename function to mtrr_write_all()

 arch/x86/cpu/mtrr.c | 57 +
 1 file changed, 57 insertions(+)

diff --git a/arch/x86/cpu/mtrr.c b/arch/x86/cpu/mtrr.c
index c9b4e7d06e..5c567551e5 100644
--- a/arch/x86/cpu/mtrr.c
+++ b/arch/x86/cpu/mtrr.c
@@ -74,10 +74,61 @@ void mtrr_read_all(struct mtrr_info *info)
}
 }
 
+void mtrr_write_all(struct mtrr_info *info)
+{
+   struct mtrr_state state;
+   int i;
+
+   for (i = 0; i < MTRR_COUNT; i++) {
+   mtrr_open(&state, true);
+   wrmsrl(MTRR_PHYS_BASE_MSR(i), info->mtrr[i].base);
+   wrmsrl(MTRR_PHYS_MASK_MSR(i), info->mtrr[i].mask);
+   mtrr_close(&state, true);
+   }
+}
+
+static void write_mtrrs(void *arg)
+{
+   struct mtrr_info *info = arg;
+
+   mtrr_write_all(info);
+}
+
+static void read_mtrrs(void *arg)
+{
+   struct mtrr_info *info = arg;
+
+   mtrr_read_all(info);
+}
+
+/**
+ * mtrr_copy_to_aps() - Copy the MTRRs from the boot CPU to other CPUs
+ *
+ * @return 0 on success, -ve on failure
+ */
+static int mtrr_copy_to_aps(void)
+{
+   struct mtrr_info info;
+   int ret;
+
+   ret = mp_run_on_cpus(MP_SELECT_BSP, read_mtrrs, &info);
+   if (ret == -ENXIO)
+   return 0;
+   else if (ret)
+   return log_msg_ret("bsp", ret);
+
+   ret = mp_run_on_cpus(MP_SELECT_APS, write_mtrrs, &info);
+   if (ret)
+   return log_msg_ret("bsp", ret);
+
+   return 0;
+}
+
 int mtrr_commit(bool do_caches)
 {
struct mtrr_request *req = gd->arch.mtrr_req;
struct mtrr_state state;
+   int ret;
int i;
 
debug("%s: enabled=%d, count=%d\n", __func__, gd->arch.has_mtrr,
@@ -99,6 +150,12 @@ int mtrr_commit(bool do_caches)
mtrr_close(&state, do_caches);
debug("mtrr done\n");
 
+   if (gd->flags & GD_FLG_RELOC) {
+   ret = mtrr_copy_to_aps();
+   if (ret)
+   return log_msg_ret("copy", ret);
+   }
+
return 0;
 }
 
-- 
2.28.0.rc0.105.gf9edc3c819-goog



[PATCH v6 22/25] x86: mtrr: Restructure so command execution is in one place

2020-07-17 Thread Simon Glass
At present do_mtrr() does the 'list' subcommand at the top and the rest
below. Update it to do them all in the same place so we can (in a later
patch) add parsing of the CPU number for all subcommands.

Signed-off-by: Simon Glass 
Reviewed-by: Wolfgang Wallner 
Reviewed-by: Bin Meng 
---

(no changes since v1)

 cmd/x86/mtrr.c | 55 +-
 1 file changed, 36 insertions(+), 19 deletions(-)

diff --git a/cmd/x86/mtrr.c b/cmd/x86/mtrr.c
index b047a9897c..b51b1cd7e2 100644
--- a/cmd/x86/mtrr.c
+++ b/cmd/x86/mtrr.c
@@ -98,31 +98,48 @@ static int do_mtrr_set(int cpu_select, uint reg, int argc, 
char *const argv[])
 static int do_mtrr(struct cmd_tbl *cmdtp, int flag, int argc,
   char *const argv[])
 {
-   const char *cmd;
+   int cmd;
int cpu_select;
uint reg;
+   int ret;
 
cpu_select = MP_SELECT_BSP;
-   cmd = argv[1];
-   if (argc < 2 || *cmd == 'l')
+   argc--;
+   argv++;
+   cmd = argv[0] ? *argv[0] : 0;
+   if (argc < 1 || !cmd) {
+   cmd = 'l';
+   reg = 0;
+   } else {
+   if (argc < 2)
+   return CMD_RET_USAGE;
+   reg = simple_strtoul(argv[1], NULL, 16);
+   if (reg >= MTRR_COUNT) {
+   printf("Invalid register number\n");
+   return CMD_RET_USAGE;
+   }
+   }
+   if (cmd == 'l') {
return do_mtrr_list(cpu_select);
-   argc -= 2;
-   argv += 2;
-   if (argc <= 0)
-   return CMD_RET_USAGE;
-   reg = simple_strtoul(argv[0], NULL, 16);
-   if (reg >= MTRR_COUNT) {
-   printf("Invalid register number\n");
-   return CMD_RET_USAGE;
+   } else {
+   switch (cmd) {
+   case 'e':
+   ret = mtrr_set_valid(cpu_select, reg, true);
+   break;
+   case 'd':
+   ret = mtrr_set_valid(cpu_select, reg, false);
+   break;
+   case 's':
+   ret = do_mtrr_set(cpu_select, reg, argc - 2, argv + 2);
+   break;
+   default:
+   return CMD_RET_USAGE;
+   }
+   if (ret) {
+   printf("Operation failed (err=%d)\n", ret);
+   return CMD_RET_FAILURE;
+   }
}
-   if (*cmd == 'e')
-   return mtrr_set_valid(cpu_select, reg, true);
-   else if (*cmd == 'd')
-   return mtrr_set_valid(cpu_select, reg, false);
-   else if (*cmd == 's')
-   return do_mtrr_set(cpu_select, reg, argc - 1, argv + 1);
-   else
-   return CMD_RET_USAGE;
 
return 0;
 }
-- 
2.28.0.rc0.105.gf9edc3c819-goog



Re: Please pull u-boot-x86

2020-07-17 Thread Tom Rini
On Fri, Jul 17, 2020 at 06:15:17PM +0800, Bin Meng wrote:

> Hi Tom,
> 
> This PR includes the following changes for v2020.10 release:
> 
> - New timer API to allow delays with a 32-bit microsecond timer
> - Add dynamic ACPI structs (DSDT/SSDT) generations to the DM core
> - x86: Enable ACPI table generation by default
> - x86: Enable the copy framebuffer on Coral
> - x86: A few fixes to FSP2 with ApolloLake
> - x86: Drop setup_pcat_compatibility()
> - x86: Primary-to-Sideband Bus minor fixes
> 
> Azure results: PASS
> https://dev.azure.com/bmeng/GitHub/_build/results?buildId=263&view=results
> 
> The following changes since commit fee68b98fe3890631a9bdf8f8db328179011ee3f:
> 
>   Merge tag 'efi-2020-10-rc1-4' of
> https://gitlab.denx.de/u-boot/custodians/u-boot-efi (2020-07-16
> 16:35:15 -0400)
> 
> are available in the git repository at:
> 
>   https://gitlab.denx.de/u-boot/custodians/u-boot-x86
> 
> for you to fetch changes up to d40d2c570600396b54dece16429727ef50cfeef0:
> 
>   acpi: Enable ACPI table generation by default on x86 (2020-07-17
> 14:32:24 +0800)
> 

Applied to u-boot/master, thanks!

-- 
Tom


signature.asc
Description: PGP signature


[PATCH v6 23/25] x86: mtrr: Update 'mtrr' to allow setting MTRRs on any CPU

2020-07-17 Thread Simon Glass
Add a -c option to mtrr to allow any CPU to be updated with this command.

Signed-off-by: Simon Glass 
Reviewed-by: Wolfgang Wallner 
Reviewed-by: Bin Meng 
---

(no changes since v3)

Changes in v3:
- Mention that the CPU number is in hex

 cmd/x86/mtrr.c | 18 --
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/cmd/x86/mtrr.c b/cmd/x86/mtrr.c
index b51b1cd7e2..d8a7e56d5a 100644
--- a/cmd/x86/mtrr.c
+++ b/cmd/x86/mtrr.c
@@ -104,6 +104,17 @@ static int do_mtrr(struct cmd_tbl *cmdtp, int flag, int 
argc,
int ret;
 
cpu_select = MP_SELECT_BSP;
+   if (argc >= 3 && !strcmp("-c", argv[1])) {
+   const char *cpustr;
+
+   cpustr = argv[2];
+   if (*cpustr == 'a')
+   cpu_select = MP_SELECT_ALL;
+   else
+   cpu_select = simple_strtol(cpustr, NULL, 16);
+   argc -= 2;
+   argv += 2;
+   }
argc--;
argv++;
cmd = argv[0] ? *argv[0] : 0;
@@ -145,11 +156,14 @@ static int do_mtrr(struct cmd_tbl *cmdtp, int flag, int 
argc,
 }
 
 U_BOOT_CMD(
-   mtrr,   6,  1,  do_mtrr,
+   mtrr,   8,  1,  do_mtrr,
"Use x86 memory type range registers (32-bit only)",
"[list]- list current registers\n"
"set   - set a register\n"
"\t is Uncacheable, Combine, Through, Protect, Back\n"
"disable   - disable a register\n"
-   "enable- enable a register"
+   "enable- enable a register\n"
+   "\n"
+   "Precede command with '-c |all' to access a particular hex CPU, 
e.g.\n"
+   "   mtrr -c all list; mtrr -c 2e list"
 );
-- 
2.28.0.rc0.105.gf9edc3c819-goog



[PATCH v6 14/25] x86: mp: Park CPUs before running the OS

2020-07-17 Thread Simon Glass
With the new MP features the CPUs are no-longer parked when the OS is run.
Fix this by calling a special function to park them, just before the OS is
started.

Signed-off-by: Simon Glass 
Reviewed-by: Wolfgang Wallner 
---

(no changes since v5)

Changes in v5:
- Drop timing in mp_park_aps()

Changes in v3:
- Update the comment for mp_park_aps()

 arch/x86/cpu/cpu.c|  5 +
 arch/x86/cpu/mp_init.c| 16 
 arch/x86/include/asm/mp.h | 17 +
 3 files changed, 38 insertions(+)

diff --git a/arch/x86/cpu/cpu.c b/arch/x86/cpu/cpu.c
index c343586e04..69c14189d1 100644
--- a/arch/x86/cpu/cpu.c
+++ b/arch/x86/cpu/cpu.c
@@ -67,6 +67,11 @@ static const char *const x86_vendor_name[] = {
 
 int __weak x86_cleanup_before_linux(void)
 {
+   int ret;
+
+   ret = mp_park_aps();
+   if (ret)
+   return log_msg_ret("park", ret);
bootstage_stash((void *)CONFIG_BOOTSTAGE_STASH_ADDR,
CONFIG_BOOTSTAGE_STASH_SIZE);
 
diff --git a/arch/x86/cpu/mp_init.c b/arch/x86/cpu/mp_init.c
index dd6d6bfab7..427ec8fc23 100644
--- a/arch/x86/cpu/mp_init.c
+++ b/arch/x86/cpu/mp_init.c
@@ -668,6 +668,22 @@ int mp_run_on_cpus(int cpu_select, mp_run_func func, void 
*arg)
return 0;
 }
 
+static void park_this_cpu(void *unused)
+{
+   stop_this_cpu();
+}
+
+int mp_park_aps(void)
+{
+   int ret;
+
+   ret = mp_run_on_cpus(MP_SELECT_APS, park_this_cpu, NULL);
+   if (ret)
+   return log_ret(ret);
+
+   return 0;
+}
+
 int mp_init(void)
 {
int num_aps, num_cpus;
diff --git a/arch/x86/include/asm/mp.h b/arch/x86/include/asm/mp.h
index eb49e690f2..f9d6c8e6bf 100644
--- a/arch/x86/include/asm/mp.h
+++ b/arch/x86/include/asm/mp.h
@@ -109,6 +109,15 @@ typedef void (*mp_run_func)(void *arg);
  * @return 0 on success, -ve on error
  */
 int mp_run_on_cpus(int cpu_select, mp_run_func func, void *arg);
+
+/**
+ * mp_park_aps() - Park the APs ready for the OS
+ *
+ * This halts all CPUs except the main one, ready for the OS to use them
+ *
+ * @return 0 if OK, -ve on error
+ */
+int mp_park_aps(void);
 #else
 static inline int mp_run_on_cpus(int cpu_select, mp_run_func func, void *arg)
 {
@@ -117,6 +126,14 @@ static inline int mp_run_on_cpus(int cpu_select, 
mp_run_func func, void *arg)
 
return 0;
 }
+
+static inline int mp_park_aps(void)
+{
+   /* No APs to park */
+
+   return 0;
+}
+
 #endif
 
 #endif /* _X86_MP_H_ */
-- 
2.28.0.rc0.105.gf9edc3c819-goog



[PATCH v6 25/25] x86: mtrr: Enhance 'mtrr' command to list MTRRs on any CPU

2020-07-17 Thread Simon Glass
Update this command so it can list the MTRRs on a selected CPU. If
'-c all' is used, then all CPUs are listed.

Signed-off-by: Simon Glass 
Reviewed-by: Wolfgang Wallner 
---

Changes in v6:
- Rebase to x86/master

 cmd/x86/mtrr.c | 22 +-
 1 file changed, 21 insertions(+), 1 deletion(-)

diff --git a/cmd/x86/mtrr.c b/cmd/x86/mtrr.c
index d8a7e56d5a..e118bba5a2 100644
--- a/cmd/x86/mtrr.c
+++ b/cmd/x86/mtrr.c
@@ -131,7 +131,27 @@ static int do_mtrr(struct cmd_tbl *cmdtp, int flag, int 
argc,
}
}
if (cmd == 'l') {
-   return do_mtrr_list(cpu_select);
+   bool first;
+   int i;
+
+   i = mp_first_cpu(cpu_select);
+   if (i < 0) {
+   printf("Invalid CPU (err=%d)\n", i);
+   return CMD_RET_FAILURE;
+   }
+   first = true;
+   for (; i >= 0; i = mp_next_cpu(cpu_select, i)) {
+   if (!first)
+   printf("\n");
+   printf("CPU %d:\n", i);
+   ret = do_mtrr_list(i);
+   if (ret) {
+   printf("Failed to read CPU %d (err=%d)\n", i,
+  ret);
+   return CMD_RET_FAILURE;
+   }
+   first = false;
+   }
} else {
switch (cmd) {
case 'e':
-- 
2.28.0.rc0.105.gf9edc3c819-goog



[PATCH v6 24/25] x86: mp: Add more comments to the module

2020-07-17 Thread Simon Glass
Add a description of how this module works and also some missing function
comments.

Reviewed-by: Wolfgang Wallner 
Signed-off-by: Simon Glass 
Reviewed-by: Bin Meng 
---

(no changes since v3)

Changes in v3:
- Remove stray asterisk from comments
- Drop mention of cpu_map which was handled in a previous patch

Changes in v2:
- Add a new patch with more comments

 arch/x86/cpu/mp_init.c| 91 ++-
 arch/x86/include/asm/mp.h | 14 +-
 2 files changed, 102 insertions(+), 3 deletions(-)

diff --git a/arch/x86/cpu/mp_init.c b/arch/x86/cpu/mp_init.c
index c373c3099a..d2f1ee38cf 100644
--- a/arch/x86/cpu/mp_init.c
+++ b/arch/x86/cpu/mp_init.c
@@ -32,13 +32,99 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
+/*
+ * Setting up multiprocessing
+ *
+ * See 
https://www.intel.com/content/www/us/en/intelligent-systems/intel-boot-loader-development-kit/minimal-intel-architecture-boot-loader-paper.html
+ *
+ * Note that this file refers to the boot CPU (the one U-Boot is running on) as
+ * the BSP (BootStrap Processor) and the others as APs (Application 
Processors).
+ *
+ * This module works by loading some setup code into RAM at AP_DEFAULT_BASE and
+ * telling each AP to execute it. The code that each AP runs is in
+ * sipi_vector.S (see ap_start16) which includes a struct sipi_params at the
+ * end of it. Those parameters are set up by the C code.
+
+ * Setting up is handled by load_sipi_vector(). It inits the common block of
+ * parameters (sipi_params) which tell the APs what to do. This block includes
+ * microcode and the MTTRs (Memory-Type-Range Registers) from the main CPU.
+ * There is also an ap_count which each AP increments as it starts up, so the
+ * BSP can tell how many checked in.
+ *
+ * The APs are started with a SIPI (Startup Inter-Processor Interrupt) which
+ * tells an AP to start executing at a particular address, in this case
+ * AP_DEFAULT_BASE which contains the code copied from ap_start16. This 
protocol
+ * is handled by start_aps().
+ *
+ * After being started, each AP runs the code in ap_start16, switches to 32-bit
+ * mode, runs the code at ap_start, then jumps to c_handler which is ap_init().
+ * This runs a very simple 'flight plan' described in mp_steps(). This sets up
+ * the CPU and waits for further instructions by looking at its entry in
+ * ap_callbacks[]. Note that the flight plan is only actually run for each CPU
+ * in bsp_do_flight_plan(): once the BSP completes each flight record, it sets
+ * mp_flight_record->barrier to 1 to allow the APs to executed the record one
+ * by one.
+ *
+ * CPUS are numbered sequentially from 0 using the device tree:
+ *
+ * cpus {
+ * u-boot,dm-pre-reloc;
+ * #address-cells = <1>;
+ * #size-cells = <0>;
+ *
+ * cpu@0 {
+ * u-boot,dm-pre-reloc;
+ * device_type = "cpu";
+ * compatible = "intel,apl-cpu";
+ * reg = <0>;
+ * intel,apic-id = <0>;
+ * };
+ *
+ * cpu@1 {
+ * device_type = "cpu";
+ * compatible = "intel,apl-cpu";
+ * reg = <1>;
+ * intel,apic-id = <2>;
+ * };
+ *
+ * Here the 'reg' property is the CPU number and then is placed in dev->req_seq
+ * so that we can index into ap_callbacks[] using that. The APIC ID is 
different
+ * and may not be sequential (it typically is if hyperthreading is supported).
+ *
+ * Once APs are inited they wait in ap_wait_for_instruction() for instructions.
+ * Instructions come in the form of a function to run. This logic is in
+ * mp_run_on_cpus() which supports running on any one AP, all APs, just the BSP
+ * or all CPUs. The BSP logic is handled directly in mp_run_on_cpus(), by
+ * calling the function. For the APs, callback information is stored in a
+ * single, common struct mp_callback and a pointer to this is written to each
+ * AP's slot in ap_callbacks[] by run_ap_work(). All APs get the message even
+ * if it is only for one of them. When an AP notices a message it checks 
whether
+ * it should call the function (see check in ap_wait_for_instruction()) and 
then
+ * does so if needed. After that it sets its slot to NULL to indicate it is
+ * done.
+ *
+ * While U-Boot is running it can use mp_run_on_cpus() to run code on the APs.
+ * An example of this is the 'mtrr' command which allows reading and changing
+ * the MTRRs on all CPUs.
+ *
+ * Before U-Boot exits it calls mp_park_aps() which tells all CPUs to halt by
+ * executing a 'hlt' instruction. That allows them to be used by Linux when it
+ * starts up.
+ */
+
 /* This also needs to match the sipi.S assembly code for saved MSR encoding */
-struct saved_msr {
+struct __packed saved_msr {
uint32_t index;
uint32_t lo;
uint32_t hi;
-} __packed;
+};
 
+/**
+ * struct mp_flight_plan - Holds the flight plan
+ *
+ * @num_records: Number of fl

[PATCH v6 18/25] x86: coral: Update the memory map

2020-07-17 Thread Simon Glass
This currently excludes the temporary memory used to start up the APs.
Add it.

Signed-off-by: Simon Glass 
Reviewed-by: Bin Meng 
Reviewed-by: Wolfgang Wallner 
---

(no changes since v2)

Changes in v2:
- Add new patch to add AP_DEFAULT_BASE to coral's memory map

 doc/board/google/chromebook_coral.rst | 1 +
 1 file changed, 1 insertion(+)

diff --git a/doc/board/google/chromebook_coral.rst 
b/doc/board/google/chromebook_coral.rst
index 40bd9397d4..c39f1e310c 100644
--- a/doc/board/google/chromebook_coral.rst
+++ b/doc/board/google/chromebook_coral.rst
@@ -188,6 +188,7 @@ Partial memory map
 fef0  1000 CONFIG_BOOTSTAGE_STASH_ADDR
 fef0   Base of CAR region
 
+   3   AP_DEFAULT_BASE (used to start up additional CPUs)
f   CONFIG_ROM_TABLE_ADDR
   12   BSS (defined in u-boot-spl.lds)
   20   FSP-S (which is run after U-Boot is relocated)
-- 
2.28.0.rc0.105.gf9edc3c819-goog



Re: [GIT PULL] Pull request: u-boot-imx u-boot-imx-20200716

2020-07-17 Thread Tom Rini
On Thu, Jul 16, 2020 at 10:01:19PM +0200, Stefano Babic wrote:

> Hi Tom,
> 
> please pull from u-boot-imx, thanks !
> 
> The following changes since commit 497c7598c4e713eb9ad88fd7963e57b21b8b35e1:
> 
>   Merge branch 'master' of
> https://gitlab.denx.de/u-boot/custodians/u-boot-spi (2020-07-11 17:40:00
> -0400)
> 
> are available in the Git repository at:
> 
>   https://gitlab.denx.de/u-boot/custodians/u-boot-imx.git
> tags/u-boot-imx-20200716
> 
> for you to fetch changes up to ab8b4e818cbc3846672c13b12f1d75daccfac519:
> 
>   mx6memcal: fix build (2020-07-16 15:11:18 +0200)
> 

Please note there's a bunch of whitespace errors in
drivers/ddr/imx/imx8m/ddrphy_utils.c, a single one in
arch/arm/mach-imx/imx8m/soc.c and
drivers/pinctrl/nxp/pinctrl-imx*.c has some warnings about using
__section(..) vs __attribute__((section(..))) but these are all things
that can be addressed with this merged.  So, applied to u-boot/master,
thanks!

-- 
Tom


signature.asc
Description: PGP signature


[PATCH] dm: core: Don't show an ACPI warning if there is no ordering

2020-07-17 Thread Simon Glass
Some boards don't care about the ordering of ACPI code fragments. Change
the warning to a debug message.

Signed-off-by: Simon Glass 
---

 drivers/core/acpi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/core/acpi.c b/drivers/core/acpi.c
index cdbc2c5cf5..7fe93992b5 100644
--- a/drivers/core/acpi.c
+++ b/drivers/core/acpi.c
@@ -195,7 +195,7 @@ static int sort_acpi_item_type(struct acpi_ctx *ctx, void 
*start,
"u-boot,acpi-dsdt-order" :
"u-boot,acpi-ssdt-order", &size);
if (!order) {
-   log_warning("Failed to find ordering, leaving as is\n");
+   log_debug("Failed to find ordering, leaving as is\n");
return 0;
}
 
-- 
2.28.0.rc0.105.gf9edc3c819-goog



[PATCH v6 20/25] x86: mtrr: Add support for writing to MTRRs on any CPU

2020-07-17 Thread Simon Glass
To enable support for the 'mtrr' command, add a way to perform MTRR
operations on selected CPUs.

This works by setting up a little 'operation' structure and sending it
around the CPUs for action.

Signed-off-by: Simon Glass 
Reviewed-by: Bin Meng 
Reviewed-by: Wolfgang Wallner 
---

(no changes since v2)

Changes in v2:
- Keep things building by temporarily renaming the function in cmd/

 arch/x86/cpu/mtrr.c | 81 +
 arch/x86/include/asm/mtrr.h | 21 ++
 cmd/x86/mtrr.c  |  6 +--
 3 files changed, 105 insertions(+), 3 deletions(-)

diff --git a/arch/x86/cpu/mtrr.c b/arch/x86/cpu/mtrr.c
index 5c567551e5..2468d88a80 100644
--- a/arch/x86/cpu/mtrr.c
+++ b/arch/x86/cpu/mtrr.c
@@ -221,3 +221,84 @@ int mtrr_set_next_var(uint type, uint64_t start, uint64_t 
size)
 
return 0;
 }
+
+/** enum mtrr_opcode - supported operations for mtrr_do_oper() */
+enum mtrr_opcode {
+   MTRR_OP_SET,
+   MTRR_OP_SET_VALID,
+};
+
+/**
+ * struct mtrr_oper - An MTRR operation to perform on a CPU
+ *
+ * @opcode: Indicates operation to perform
+ * @reg: MTRR reg number to select (0-7, -1 = all)
+ * @valid: Valid value to write for MTRR_OP_SET_VALID
+ * @base: Base value to write for MTRR_OP_SET
+ * @mask: Mask value to write for MTRR_OP_SET
+ */
+struct mtrr_oper {
+   enum mtrr_opcode opcode;
+   int reg;
+   bool valid;
+   u64 base;
+   u64 mask;
+};
+
+static void mtrr_do_oper(void *arg)
+{
+   struct mtrr_oper *oper = arg;
+   u64 mask;
+
+   switch (oper->opcode) {
+   case MTRR_OP_SET_VALID:
+   mask = native_read_msr(MTRR_PHYS_MASK_MSR(oper->reg));
+   if (oper->valid)
+   mask |= MTRR_PHYS_MASK_VALID;
+   else
+   mask &= ~MTRR_PHYS_MASK_VALID;
+   wrmsrl(MTRR_PHYS_MASK_MSR(oper->reg), mask);
+   break;
+   case MTRR_OP_SET:
+   wrmsrl(MTRR_PHYS_BASE_MSR(oper->reg), oper->base);
+   wrmsrl(MTRR_PHYS_MASK_MSR(oper->reg), oper->mask);
+   break;
+   }
+}
+
+static int mtrr_start_op(int cpu_select, struct mtrr_oper *oper)
+{
+   struct mtrr_state state;
+   int ret;
+
+   mtrr_open(&state, true);
+   ret = mp_run_on_cpus(cpu_select, mtrr_do_oper, oper);
+   mtrr_close(&state, true);
+   if (ret)
+   return log_msg_ret("run", ret);
+
+   return 0;
+}
+
+int mtrr_set_valid(int cpu_select, int reg, bool valid)
+{
+   struct mtrr_oper oper;
+
+   oper.opcode = MTRR_OP_SET_VALID;
+   oper.reg = reg;
+   oper.valid = valid;
+
+   return mtrr_start_op(cpu_select, &oper);
+}
+
+int mtrr_set(int cpu_select, int reg, u64 base, u64 mask)
+{
+   struct mtrr_oper oper;
+
+   oper.opcode = MTRR_OP_SET;
+   oper.reg = reg;
+   oper.base = base;
+   oper.mask = mask;
+
+   return mtrr_start_op(cpu_select, &oper);
+}
diff --git a/arch/x86/include/asm/mtrr.h b/arch/x86/include/asm/mtrr.h
index e1f1a44643..48db1dd82f 100644
--- a/arch/x86/include/asm/mtrr.h
+++ b/arch/x86/include/asm/mtrr.h
@@ -159,6 +159,27 @@ int mtrr_set_next_var(uint type, uint64_t base, uint64_t 
size);
  */
 void mtrr_read_all(struct mtrr_info *info);
 
+/**
+ * mtrr_set_valid() - Set the valid flag for a selected MTRR and CPU(s)
+ *
+ * @cpu_select: Selected CPUs (either a CPU number or MP_SELECT_...)
+ * @reg: MTRR register to write (0-7)
+ * @valid: Valid flag to write
+ * @return 0 on success, -ve on error
+ */
+int mtrr_set_valid(int cpu_select, int reg, bool valid);
+
+/**
+ * mtrr_set() - Set the valid flag for a selected MTRR and CPU(s)
+ *
+ * @cpu_select: Selected CPUs (either a CPU number or MP_SELECT_...)
+ * @reg: MTRR register to write (0-7)
+ * @base: Base address and MTRR_BASE_TYPE_MASK
+ * @mask: Mask and MTRR_PHYS_MASK_VALID
+ * @return 0 on success, -ve on error
+ */
+int mtrr_set(int cpu_select, int reg, u64 base, u64 mask);
+
 #endif
 
 #if ((CONFIG_XIP_ROM_SIZE & (CONFIG_XIP_ROM_SIZE - 1)) != 0)
diff --git a/cmd/x86/mtrr.c b/cmd/x86/mtrr.c
index f357f58767..46ef6a2830 100644
--- a/cmd/x86/mtrr.c
+++ b/cmd/x86/mtrr.c
@@ -96,7 +96,7 @@ static int do_mtrr_set(uint reg, int argc, char *const argv[])
return 0;
 }
 
-static int mtrr_set_valid(int reg, bool valid)
+static int mtrr_set_valid_(int reg, bool valid)
 {
struct mtrr_state state;
uint64_t mask;
@@ -134,9 +134,9 @@ static int do_mtrr(struct cmd_tbl *cmdtp, int flag, int 
argc,
return CMD_RET_USAGE;
}
if (*cmd == 'e')
-   return mtrr_set_valid(reg, true);
+   return mtrr_set_valid_(reg, true);
else if (*cmd == 'd')
-   return mtrr_set_valid(reg, false);
+   return mtrr_set_valid_(reg, false);
else if (*cmd == 's')
return do_mtrr_set(reg, argc - 1, argv + 1);
else
-- 
2.28.0.rc0.105.gf9edc3c819-goog



[PATCH v6 16/25] x86: mtrr: Use MP calls to list the MTRRs

2020-07-17 Thread Simon Glass
Update the mtrr command to use mp_run_on_cpus() to obtain its information.
Since the selected CPU is the boot CPU this does not change the result,
but it sets the stage for supporting other CPUs.

Signed-off-by: Simon Glass 
Reviewed-by: Wolfgang Wallner 
Reviewed-by: Bin Meng 
---

(no changes since v2)

Changes in v2:
- Rename mtrr_save_all() to mtrr_read_all()

 arch/x86/cpu/mtrr.c | 11 +++
 arch/x86/include/asm/mtrr.h | 30 ++
 cmd/x86/mtrr.c  | 25 +
 3 files changed, 62 insertions(+), 4 deletions(-)

diff --git a/arch/x86/cpu/mtrr.c b/arch/x86/cpu/mtrr.c
index 7ec077..c9b4e7d06e 100644
--- a/arch/x86/cpu/mtrr.c
+++ b/arch/x86/cpu/mtrr.c
@@ -21,6 +21,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -63,6 +64,16 @@ static void set_var_mtrr(uint reg, uint type, uint64_t 
start, uint64_t size)
wrmsrl(MTRR_PHYS_MASK_MSR(reg), mask | MTRR_PHYS_MASK_VALID);
 }
 
+void mtrr_read_all(struct mtrr_info *info)
+{
+   int i;
+
+   for (i = 0; i < MTRR_COUNT; i++) {
+   info->mtrr[i].base = native_read_msr(MTRR_PHYS_BASE_MSR(i));
+   info->mtrr[i].mask = native_read_msr(MTRR_PHYS_MASK_MSR(i));
+   }
+}
+
 int mtrr_commit(bool do_caches)
 {
struct mtrr_request *req = gd->arch.mtrr_req;
diff --git a/arch/x86/include/asm/mtrr.h b/arch/x86/include/asm/mtrr.h
index 212a699c1b..e1f1a44643 100644
--- a/arch/x86/include/asm/mtrr.h
+++ b/arch/x86/include/asm/mtrr.h
@@ -70,6 +70,26 @@ struct mtrr_state {
bool enable_cache;
 };
 
+/**
+ * struct mtrr - Information about a single MTRR
+ *
+ * @base: Base address and MTRR_BASE_TYPE_MASK
+ * @mask: Mask and MTRR_PHYS_MASK_VALID
+ */
+struct mtrr {
+   u64 base;
+   u64 mask;
+};
+
+/**
+ * struct mtrr_info - Information about all MTRRs
+ *
+ * @mtrr: Information about each mtrr
+ */
+struct mtrr_info {
+   struct mtrr mtrr[MTRR_COUNT];
+};
+
 /**
  * mtrr_open() - Prepare to adjust MTRRs
  *
@@ -129,6 +149,16 @@ int mtrr_commit(bool do_caches);
  */
 int mtrr_set_next_var(uint type, uint64_t base, uint64_t size);
 
+/**
+ * mtrr_read_all() - Save all the MTRRs
+ *
+ * This reads all MTRRs from the boot CPU into a struct so they can be loaded
+ * onto other CPUs
+ *
+ * @info: Place to put the MTRR info
+ */
+void mtrr_read_all(struct mtrr_info *info);
+
 #endif
 
 #if ((CONFIG_XIP_ROM_SIZE & (CONFIG_XIP_ROM_SIZE - 1)) != 0)
diff --git a/cmd/x86/mtrr.c b/cmd/x86/mtrr.c
index 5d25c5802a..f357f58767 100644
--- a/cmd/x86/mtrr.c
+++ b/cmd/x86/mtrr.c
@@ -5,7 +5,9 @@
 
 #include 
 #include 
+#include 
 #include 
+#include 
 #include 
 
 static const char *const mtrr_type_name[MTRR_TYPE_COUNT] = {
@@ -18,19 +20,32 @@ static const char *const mtrr_type_name[MTRR_TYPE_COUNT] = {
"Back",
 };
 
-static int do_mtrr_list(void)
+static void read_mtrrs(void *arg)
 {
+   struct mtrr_info *info = arg;
+
+   mtrr_read_all(info);
+}
+
+static int do_mtrr_list(int cpu_select)
+{
+   struct mtrr_info info;
+   int ret;
int i;
 
printf("Reg Valid Write-type   %-16s %-16s %-16s\n", "Base   ||",
   "Mask   ||", "Size   ||");
+   memset(&info, '\0', sizeof(info));
+   ret = mp_run_on_cpus(cpu_select, read_mtrrs, &info);
+   if (ret)
+   return log_msg_ret("run", ret);
for (i = 0; i < MTRR_COUNT; i++) {
const char *type = "Invalid";
uint64_t base, mask, size;
bool valid;
 
-   base = native_read_msr(MTRR_PHYS_BASE_MSR(i));
-   mask = native_read_msr(MTRR_PHYS_MASK_MSR(i));
+   base = info.mtrr[i].base;
+   mask = info.mtrr[i].mask;
size = ~mask & ((1ULL << CONFIG_CPU_ADDR_BITS) - 1);
size |= (1 << 12) - 1;
size += 1;
@@ -102,11 +117,13 @@ static int do_mtrr(struct cmd_tbl *cmdtp, int flag, int 
argc,
   char *const argv[])
 {
const char *cmd;
+   int cpu_select;
uint reg;
 
+   cpu_select = MP_SELECT_BSP;
cmd = argv[1];
if (argc < 2 || *cmd == 'l')
-   return do_mtrr_list();
+   return do_mtrr_list(cpu_select);
argc -= 2;
argv += 2;
if (argc <= 0)
-- 
2.28.0.rc0.105.gf9edc3c819-goog



Re: [PATCH] dm: core: Don't show an ACPI warning if there is no ordering

2020-07-17 Thread Bin Meng
On Fri, Jul 17, 2020 at 10:49 PM Simon Glass  wrote:
>
> Some boards don't care about the ordering of ACPI code fragments. Change
> the warning to a debug message.
>
> Signed-off-by: Simon Glass 
> ---
>
>  drivers/core/acpi.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>

Reviewed-by: Bin Meng 


[PATCH 2/4] dt-bindings: arm: SCMI bindings documentation

2020-07-17 Thread Etienne Carriere
Dump SCMI DT bindings documentation from Linux kernel source
tree v5.8-rc1.

Signed-off-by: Etienne Carriere 
---

 doc/device-tree-bindings/arm/arm,scmi.txt | 197 ++
 1 file changed, 197 insertions(+)
 create mode 100644 doc/device-tree-bindings/arm/arm,scmi.txt

diff --git a/doc/device-tree-bindings/arm/arm,scmi.txt 
b/doc/device-tree-bindings/arm/arm,scmi.txt
new file mode 100644
index 000..1f293ea24cd
--- /dev/null
+++ b/doc/device-tree-bindings/arm/arm,scmi.txt
@@ -0,0 +1,197 @@
+System Control and Management Interface (SCMI) Message Protocol
+--
+
+The SCMI is intended to allow agents such as OSPM to manage various functions
+that are provided by the hardware platform it is running on, including power
+and performance functions.
+
+This binding is intended to define the interface the firmware implementing
+the SCMI as described in ARM document number ARM DEN 0056A ("ARM System Control
+and Management Interface Platform Design Document")[0] provide for OSPM in
+the device tree.
+
+Required properties:
+
+The scmi node with the following properties shall be under the /firmware/ node.
+
+- compatible : shall be "arm,scmi" or "arm,scmi-smc" for smc/hvc transports
+- mboxes: List of phandle and mailbox channel specifiers. It should contain
+ exactly one or two mailboxes, one for transmitting messages("tx")
+ and another optional for receiving the notifications("rx") if
+ supported.
+- shmem : List of phandle pointing to the shared memory(SHM) area as per
+ generic mailbox client binding.
+- #address-cells : should be '1' if the device has sub-nodes, maps to
+ protocol identifier for a given sub-node.
+- #size-cells : should be '0' as 'reg' property doesn't have any size
+ associated with it.
+- arm,smc-id : SMC id required when using smc or hvc transports
+
+Optional properties:
+
+- mbox-names: shall be "tx" or "rx" depending on mboxes entries.
+
+See Documentation/devicetree/bindings/mailbox/mailbox.txt for more details
+about the generic mailbox controller and client driver bindings.
+
+The mailbox is the only permitted method of calling the SCMI firmware.
+Mailbox doorbell is used as a mechanism to alert the presence of a
+messages and/or notification.
+
+Each protocol supported shall have a sub-node with corresponding compatible
+as described in the following sections. If the platform supports dedicated
+communication channel for a particular protocol, the 3 properties namely:
+mboxes, mbox-names and shmem shall be present in the sub-node corresponding
+to that protocol.
+
+Clock/Performance bindings for the clocks/OPPs based on SCMI Message Protocol
+
+
+This binding uses the common clock binding[1].
+
+Required properties:
+- #clock-cells : Should be 1. Contains the Clock ID value used by SCMI 
commands.
+
+Power domain bindings for the power domains based on SCMI Message Protocol
+
+
+This binding for the SCMI power domain providers uses the generic power
+domain binding[2].
+
+Required properties:
+ - #power-domain-cells : Should be 1. Contains the device or the power
+domain ID value used by SCMI commands.
+
+Sensor bindings for the sensors based on SCMI Message Protocol
+--
+SCMI provides an API to access the various sensors on the SoC.
+
+Required properties:
+- #thermal-sensor-cells: should be set to 1. This property follows the
+thermal device tree bindings[3].
+
+Valid cell values are raw identifiers (Sensor ID)
+as used by the firmware. Refer to  platform details
+for your implementation for the IDs to use.
+
+Reset signal bindings for the reset domains based on SCMI Message Protocol
+
+
+This binding for the SCMI reset domain providers uses the generic reset
+signal binding[5].
+
+Required properties:
+ - #reset-cells : Should be 1. Contains the reset domain ID value used
+ by SCMI commands.
+
+SRAM and Shared Memory for SCMI
+---
+
+A small area of SRAM is reserved for SCMI communication between application
+processors and SCP.
+
+The properties should follow the generic mmio-sram description found in [4]
+
+Each sub-node represents the reserved area for SCMI.
+
+Required sub-node properties:
+- reg : The base offset and size of the reserved area with the SRAM
+- compatible : should be "arm,scmi-shmem" for Non-secure SRAM based
+  shared memory
+
+[0] http://infocenter.arm.com/help/topic/com.arm.doc.den0056a/index.html
+[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
+[2] Documentation/devicetree/bindings/power/power-domain.yaml
+[3] D

  1   2   >