When the serial port uses I/O ports, it is expected to be on an ISA bus.
Handle this by creating a suitable node and putting the serial port in
that node.

Add a reference to the serial port in the /chosen node.

Signed-off-by: Simon Glass <s...@chromium.org>
---

 boot/upl_write.c | 46 ++++++++++++++++++++++++++++++++++++++++------
 include/upl.h    |  3 +++
 test/boot/upl.c  |  1 +
 3 files changed, 44 insertions(+), 6 deletions(-)

diff --git a/boot/upl_write.c b/boot/upl_write.c
index eecb56214df..c43a588dc40 100644
--- a/boot/upl_write.c
+++ b/boot/upl_write.c
@@ -482,19 +482,48 @@ static int add_upl_serial(const struct upl *upl, ofnode 
root,
 {
        const struct upl_serial *ser = &upl->serial;
        const struct memregion *first;
-       char name[26];
-       ofnode node;
+       char name[26], alias[36];
+       ofnode node, parent;
        int ret;
 
-       if (!ser->compatible || skip_existing)
+       if (!ser->compatible)
                return 0;
        if (!ser->reg.count)
                return log_msg_ret("ser", -EINVAL);
+
+       ret = ofnode_add_subnode(root, UPLN_CHOSEN, &node);
+       if (ret)
+               return log_msg_ret("uch", ret);
+
+       parent = root;
+       if (ser->access_type == UPLAT_IO) {
+               ret = ofnode_write_string(node, UPLP_STDOUT_PATH, 
"/isa/serial");
+               if (ret)
+                       return log_msg_ret("uc0", ret);
+
+               ret = ofnode_add_subnode(root, "isa", &node);
+               if (ret)
+                       return log_msg_ret("uc1", ret);
+               if (ofnode_write_string(node, UPLP_UPL_PARAMS_COMPAT, "isa") ||
+                   add_addr_size_cells(node, 2, 1))
+                       return log_msg_ret("uc2", -EINVAL);
+               parent = node;
+               strcpy(alias, "/isa");
+       }
+
        first = alist_get(&ser->reg, 0, struct memregion);
        sprintf(name, UPLN_SERIAL "@%llx", first->base);
-       ret = ofnode_add_subnode(root, name, &node);
-       if (ret)
-               return log_msg_ret("img", ret);
+       ret = ofnode_add_subnode(parent, name, &node);
+       if (ret) {
+               if (ret == -EEXIST) {
+                       if (skip_existing)
+                               return 0;
+               } else {
+                       return log_msg_ret("img", ret);
+               }
+       }
+
+       // ret = ofnode_write_string(node, UPLP_COMPATIBLE, "ns8250");
        ret = ofnode_write_string(node, UPLP_COMPATIBLE, ser->compatible);
        if (!ret)
                ret = ofnode_write_u32(node, UPLP_CLOCK_FREQUENCY,
@@ -527,6 +556,11 @@ static int add_upl_serial(const struct upl *upl, ofnode 
root,
                                         ARRAY_SIZE(access_types),
                                         ser->access_type);
        }
+       if (!ret) {
+               strlcat(alias, "/", sizeof(alias));
+               strlcat(alias, name, sizeof(alias));
+               ret = ofnode_write_string(node, UPLP_STDOUT_PATH, alias);
+       }
        if (ret)
                return log_msg_ret("ser", ret);
 
diff --git a/include/upl.h b/include/upl.h
index 62341f2f719..d5b2cad7196 100644
--- a/include/upl.h
+++ b/include/upl.h
@@ -21,6 +21,9 @@ struct unit_test_state;
 #define UPLP_ADDRESS_CELLS     "#address-cells"
 #define UPLP_SIZE_CELLS                "#size-cells"
 
+#define UPLN_CHOSEN            "chosen"
+#define UPLP_STDOUT_PATH       "stdout-path"
+
 #define UPLN_OPTIONS           "options"
 #define UPLN_UPL_PARAMS                "upl-params"
 #define UPLP_UPL_PARAMS_COMPAT "upl"
diff --git a/test/boot/upl.c b/test/boot/upl.c
index 7171f16e42e..91b7baa75e2 100644
--- a/test/boot/upl.c
+++ b/test/boot/upl.c
@@ -6,6 +6,7 @@
  * Written by Simon Glass <s...@chromium.org>
  */
 
+#define LOG_DEBUG
 #define LOG_CATEGORY UCLASS_BOOTSTD
 
 #include <abuf.h>
-- 
2.43.0

Reply via email to