aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArve Hjønnevåg <arve@android.com>2024-04-25 16:45:32 -0700
committerArve Hjønnevåg <arve@android.com>2024-04-25 17:22:31 -0700
commitbe9943296199b20ce2f26ba2b6b2c8de7a0b9aef (patch)
tree800df22ac5cdce0e2e27de64f0cad4af65af46bc
parente073695b339ffaf550fd3c63e8b8f930b9182b6a (diff)
downloadcommon-master.tar.gz
lib: device_tree: Add device_tree libraryHEADmastermain
Add device_tree library that adds a few wrappers on top of libfdt to help read values out of properties that can have mutiple rows of variable sized values. Bug: 297275002 Change-Id: Iac0f757f82d0b6f8e8c6b29cb41efd61ffeca589
-rw-r--r--lib/device_tree/include/lib/device_tree/libfdt_helpers.h41
-rw-r--r--lib/device_tree/libfdt_helpers.c121
-rw-r--r--lib/device_tree/rules.mk37
3 files changed, 199 insertions, 0 deletions
diff --git a/lib/device_tree/include/lib/device_tree/libfdt_helpers.h b/lib/device_tree/include/lib/device_tree/libfdt_helpers.h
new file mode 100644
index 00000000..22acce77
--- /dev/null
+++ b/lib/device_tree/include/lib/device_tree/libfdt_helpers.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2024 LK Trusty Authors. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files
+ * (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#pragma once
+
+#include <libfdt.h>
+#include <lk/types.h>
+
+status_t fdt_helper_read_cells32(const fdt32_t* fdt_prop,
+ int fdt_prop_len,
+ int row_index,
+ int before_cells,
+ int cells,
+ int after_cells,
+ uint64_t* valp);
+
+status_t fdt_helper_get_reg(const void* fdt,
+ int nodeoffset,
+ int reg_index,
+ paddr_t* addrp,
+ size_t* sizep);
diff --git a/lib/device_tree/libfdt_helpers.c b/lib/device_tree/libfdt_helpers.c
new file mode 100644
index 00000000..dc6eb17f
--- /dev/null
+++ b/lib/device_tree/libfdt_helpers.c
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2024 LK Trusty Authors. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files
+ * (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <lib/device_tree/libfdt_helpers.h>
+#include "err.h"
+#include "lk/types.h"
+
+/**
+ * fdt_helper_read_cells32 - Read and convert cells.
+ * @fdt_prop: Pointer to property to read from.
+ * @fdt_prop_len: Length of @fdt_prop in bytes (not count of 32 bit values).
+ * @row_index: Row to read from.
+ * @before_cells: Number of cells to ignore in each row before the cells we
+ * read and convert.
+ * @cells: Number of cells to read and convert to cpu endian.
+ * @after_cells: Number of cells to ignore in each row after the cell we read
+ * and convert.
+ * @valp: Pointer to store converted value in.
+ *
+ * Return:
+ * * %0: Success.
+ * * %ERR_OUT_OF_RANGE: @fdt_prop_len is too small for the requested read.
+ * * %ERR_TOO_BIG: value does not fit in uint64_t (only possible if
+ * cells > 2).
+ */
+status_t fdt_helper_read_cells32(const fdt32_t* fdt_prop,
+ int fdt_prop_len,
+ int row_index,
+ int before_cells,
+ int cells,
+ int after_cells,
+ uint64_t* valp) {
+ uint64_t ret = 0;
+ int cell_index =
+ row_index * (before_cells + cells + after_cells) + before_cells;
+ if (cell_index + cells > (fdt_prop_len / (int)sizeof(fdt32_t))) {
+ return ERR_OUT_OF_RANGE;
+ }
+ while (cells-- > 0) {
+ if (ret > UINT32_MAX) {
+ return ERR_TOO_BIG;
+ }
+ ret = ret << 32 | fdt32_to_cpu(fdt_prop[cell_index++]);
+ }
+ *valp = ret;
+ return 0;
+}
+
+/**
+ * fdt_helper_get_reg - Get address and size from reg property of a node.
+ * @fdt: Pointer to device tree.
+ * @nodeoffset: Node to use.
+ * @reg_index: Row to read from.
+ *
+ * Return:
+ * * %0: Success.
+ * * %ERR_NOT_FOUND: Node does not have a reg property.
+ * * %ERR_OUT_OF_RANGE: reg property is too small for the requested read.
+ * * %ERR_TOO_BIG: reg value does not fit in paddr_t or size_t.
+ */
+status_t fdt_helper_get_reg(const void* fdt,
+ int nodeoffset,
+ int reg_index,
+ paddr_t* addrp,
+ size_t* sizep) {
+ status_t ret = 0;
+ int parent_offset = fdt_parent_offset(fdt, nodeoffset);
+ int address_cells = fdt_address_cells(fdt, parent_offset);
+ int size_cells = fdt_size_cells(fdt, parent_offset);
+ int reg_prop_len;
+ const fdt32_t* reg_prop =
+ fdt_getprop(fdt, nodeoffset, "reg", &reg_prop_len);
+ if (!reg_prop) {
+ return ERR_NOT_FOUND;
+ }
+ if (addrp) {
+ uint64_t addr64;
+ ret = fdt_helper_read_cells32(reg_prop, reg_prop_len, reg_index, 0,
+ address_cells, size_cells, &addr64);
+ if (ret) {
+ return ret;
+ }
+ if (addr64 > PADDR_MAX) {
+ return ERR_TOO_BIG;
+ }
+ *addrp = addr64;
+ }
+ if (sizep) {
+ uint64_t size64;
+ ret = fdt_helper_read_cells32(reg_prop, reg_prop_len, reg_index,
+ address_cells, size_cells, 0, &size64);
+ if (ret) {
+ return ret;
+ }
+ if (size64 > SIZE_MAX) {
+ return ERR_TOO_BIG;
+ }
+ *sizep = size64;
+ }
+ return 0;
+}
diff --git a/lib/device_tree/rules.mk b/lib/device_tree/rules.mk
new file mode 100644
index 00000000..903de373
--- /dev/null
+++ b/lib/device_tree/rules.mk
@@ -0,0 +1,37 @@
+#
+# Copyright (c) 2024 LK Trusty Authors. All Rights Reserved.
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files
+# (the "Software"), to deal in the Software without restriction,
+# including without limitation the rights to use, copy, modify, merge,
+# publish, distribute, sublicense, and/or sell copies of the Software,
+# and to permit persons to whom the Software is furnished to do so,
+# subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+LOCAL_DIR := $(GET_LOCAL_DIR)
+
+MODULE := $(LOCAL_DIR)
+
+MODULE_LIBRARY_DEPS += \
+ external/dtc/libfdt \
+
+MODULE_EXPORT_INCLUDES += \
+ $(LOCAL_DIR)/include \
+
+MODULE_SRCS += \
+ $(LOCAL_DIR)/libfdt_helpers.c \
+
+include make/library.mk