PSA FF-A: update RX/TX buffer as per spec
PSA FF-A v1.0 spec describes RX/TX buffers as reference to memory-region
entries in the partition manifest which is described as RX/TX buffers.
In device tree terms, RX/TX nodes points to entries in memory-region
node using phandle.
This patch introduces RX and TX pointers which points to memory-region
type structure and is populated when memory-region node is parsed.
Change-Id: Ia04b9d082bacf3e6cb227e74dbf875c5e0680648
Signed-off-by: Manish Pandey <manish.pandey2@arm.com>
diff --git a/src/manifest.c b/src/manifest.c
index e5076b6..9c98b5f 100644
--- a/src/manifest.c
+++ b/src/manifest.c
@@ -305,8 +305,10 @@
}
static enum manifest_return_code parse_ffa_memory_region_node(
- struct fdt_node *mem_node, struct memory_region *mem_regions)
+ struct fdt_node *mem_node, struct memory_region *mem_regions,
+ struct rx_tx *rxtx)
{
+ uint32_t phandle;
unsigned int i = 0;
dlog_verbose(" Partition memory regions\n");
@@ -343,6 +345,18 @@
mem_regions[i].attributes &= MM_PERM_MASK;
dlog_verbose(" Attributes: %u\n",
mem_regions[i].attributes);
+
+ TRY(read_optional_uint32(mem_node, "phandle",
+ (uint32_t)MANIFEST_INVALID_ADDRESS,
+ &phandle));
+ if (phandle == rxtx->rx_phandle) {
+ dlog_verbose(" Assigned as RX buffer\n");
+ rxtx->rx_buffer = &mem_regions[i];
+ } else if (phandle == rxtx->tx_phandle) {
+ dlog_verbose(" Assigned as TX buffer\n");
+ rxtx->tx_buffer = &mem_regions[i];
+ }
+
i++;
} while (fdt_next_sibling(mem_node) && (i < SP_MAX_MEMORY_REGIONS));
@@ -517,16 +531,17 @@
return MANIFEST_ERROR_NOT_COMPATIBLE;
}
- TRY(read_uint64(&ffa_node, "base-address",
- &vm->sp.rxtx.base_address));
+ /*
+ * Read only phandles for now, it will be used to update buffers
+ * while parsing memory regions.
+ */
+ TRY(read_uint32(&ffa_node, "rx-buffer",
+ &vm->sp.rxtx.rx_phandle));
- TRY(read_uint16(&ffa_node, "pages-count",
- &vm->sp.rxtx.pages_count));
+ TRY(read_uint32(&ffa_node, "tx-buffer",
+ &vm->sp.rxtx.tx_phandle));
- TRY(read_uint16(&ffa_node, "attributes",
- &vm->sp.rxtx.attributes));
-
- vm->sp.rxtx.rxtx_found = true;
+ vm->sp.rxtx.available = true;
}
TRY(read_uint8(&root, "messaging-method",
@@ -536,8 +551,8 @@
/* Parse memory-regions */
ffa_node = root;
if (fdt_find_child(&ffa_node, &mem_region_node_name)) {
- TRY(parse_ffa_memory_region_node(&ffa_node,
- vm->sp.mem_regions));
+ TRY(parse_ffa_memory_region_node(&ffa_node, vm->sp.mem_regions,
+ &vm->sp.rxtx));
}
/* Parse Device-regions */
diff --git a/src/manifest_test.cc b/src/manifest_test.cc
index d58cb70..7b039f9 100644
--- a/src/manifest_test.cc
+++ b/src/manifest_test.cc
@@ -217,6 +217,12 @@
return *this;
}
+ ManifestDtBuilder &Label(const std::string_view &name)
+ {
+ dts_ << name << ": ";
+ return *this;
+ }
+
ManifestDtBuilder &FfaValidManifest()
{
Compatible({"arm,ffa-manifest-1.0"});
@@ -817,6 +823,35 @@
MANIFEST_ERROR_NOT_COMPATIBLE);
}
+TEST(manifest, ffa_validate_rxtx_info)
+{
+ struct manifest m;
+
+ /* Not Compatible */
+ /* clang-format off */
+ std::vector<char> dtb = ManifestDtBuilder()
+ .FfaValidManifest()
+ .StartChild("rx_tx-info")
+ .Compatible({ "foo,bar" })
+ .EndChild()
+ .Build();
+ /* clang-format on */
+ ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
+ MANIFEST_ERROR_NOT_COMPATIBLE);
+
+ /* Missing Properties */
+ /* clang-format off */
+ dtb = ManifestDtBuilder()
+ .FfaValidManifest()
+ .StartChild("rx_tx-info")
+ .Compatible({ "arm,ffa-manifest-rx_tx-buffer" })
+ .EndChild()
+ .Build();
+ /* clang-format on */
+ ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
+ MANIFEST_ERROR_PROPERTY_NOT_FOUND);
+}
+
TEST(manifest, ffa_validate_mem_regions)
{
struct manifest m;
@@ -933,6 +968,11 @@
/* clang-format off */
std::vector<char> dtb = ManifestDtBuilder()
.FfaValidManifest()
+ .StartChild("rx_tx-info")
+ .Compatible({ "arm,ffa-manifest-rx_tx-buffer" })
+ .Property("rx-buffer", "<&rx>")
+ .Property("tx-buffer", "<&tx>")
+ .EndChild()
.StartChild("memory-regions")
.Compatible({ "arm,ffa-manifest-memory-regions" })
.StartChild("test-memory")
@@ -941,6 +981,20 @@
.Property("pages-count", "<4>")
.Property("attributes", "<7>")
.EndChild()
+ .Label("rx")
+ .StartChild("rx")
+ .Description("rx-buffer")
+ .Property("base-address", "<0x7300000>")
+ .Property("pages-count", "<1>")
+ .Property("attributes", "<1>")
+ .EndChild()
+ .Label("tx")
+ .StartChild("tx")
+ .Description("tx-buffer")
+ .Property("base-address", "<0x7310000>")
+ .Property("pages-count", "<1>")
+ .Property("attributes", "<3>")
+ .EndChild()
.EndChild()
.StartChild("device-regions")
.Compatible({ "arm,ffa-manifest-device-regions" })
@@ -973,6 +1027,13 @@
ASSERT_EQ(m.vm[0].sp.mem_regions[0].base_address, 0x7100000);
ASSERT_EQ(m.vm[0].sp.mem_regions[0].page_count, 4);
ASSERT_EQ(m.vm[0].sp.mem_regions[0].attributes, 7);
+ ASSERT_EQ(m.vm[0].sp.rxtx.available, true);
+ ASSERT_EQ(m.vm[0].sp.rxtx.rx_buffer->base_address, 0x7300000);
+ ASSERT_EQ(m.vm[0].sp.rxtx.rx_buffer->page_count, 1);
+ ASSERT_EQ(m.vm[0].sp.rxtx.rx_buffer->attributes, 1);
+ ASSERT_EQ(m.vm[0].sp.rxtx.tx_buffer->base_address, 0x7310000);
+ ASSERT_EQ(m.vm[0].sp.rxtx.tx_buffer->page_count, 1);
+ ASSERT_EQ(m.vm[0].sp.rxtx.tx_buffer->attributes, 3);
ASSERT_EQ(m.vm[0].sp.dev_regions[0].base_address, 0x7200000);
ASSERT_EQ(m.vm[0].sp.dev_regions[0].page_count, 16);
/* Attribute is ORed with MM_MODE_D */