[PATCH 61/67] upl: Handle serial on an ISA bus with /chosen node

Simon Glass sjg at chromium.org
Wed Jan 1 23:09:47 CET 2025


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 <sjg at 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 <sjg at chromium.org>
  */
 
+#define LOG_DEBUG
 #define LOG_CATEGORY UCLASS_BOOTSTD
 
 #include <abuf.h>
-- 
2.43.0



More information about the U-Boot mailing list