summaryrefslogtreecommitdiff
path: root/src/commonlib/include
diff options
context:
space:
mode:
Diffstat (limited to 'src/commonlib/include')
-rw-r--r--src/commonlib/include/commonlib/region.h63
1 files changed, 38 insertions, 25 deletions
diff --git a/src/commonlib/include/commonlib/region.h b/src/commonlib/include/commonlib/region.h
index b9a984f171..4d095b731d 100644
--- a/src/commonlib/include/commonlib/region.h
+++ b/src/commonlib/include/commonlib/region.h
@@ -6,6 +6,7 @@
#include <sys/types.h>
#include <stddef.h>
#include <stdbool.h>
+#include <commonlib/bsd/helpers.h>
#include <commonlib/mem_pool.h>
/*
@@ -210,14 +211,33 @@ void mmap_helper_device_init(struct mmap_helper_region_device *mdev,
void *mmap_helper_rdev_mmap(const struct region_device *, size_t, size_t);
int mmap_helper_rdev_munmap(const struct region_device *, void *);
-/* A translated region device provides the ability to publish a region device
- * in one address space and use an access mechanism within another address
- * space. The sub region is the window within the 1st address space and
- * the request is modified prior to accessing the second address space
- * provided by access_dev. */
-struct xlate_region_device {
+/*
+ * A translated region device provides the ability to publish a region device in one address
+ * space and use an access mechanism within another address space. The sub region is the window
+ * within the 1st address space and the request is modified prior to accessing the second
+ * address space provided by access_dev.
+ *
+ * Each xlate_region_device can support multiple translation windows described using
+ * xlate_window structure. The windows need not be contiguous in either address space. However,
+ * this poses restrictions on the operations being performed i.e. callers cannot perform
+ * operations across multiple windows of a translated region device. It is possible to support
+ * readat/writeat/eraseat by translating them into multiple calls one to access device in each
+ * window. However, mmap support is tricky because the caller expects that the memory mapped
+ * region is contiguous in both address spaces. Thus, to keep the semantics consistent for all
+ * region ops, xlate_region_device does not support any operations across the window
+ * boundary.
+ *
+ * Note: The platform is expected to ensure that the fmap description does not place any
+ * section (that will be operated using the translated region device) across multiple windows.
+ */
+struct xlate_window {
const struct region_device *access_dev;
struct region sub_region;
+};
+
+struct xlate_region_device {
+ size_t window_count;
+ const struct xlate_window *window_arr;
struct region_device rdev;
};
@@ -225,38 +245,31 @@ extern const struct region_device_ops xlate_rdev_ro_ops;
extern const struct region_device_ops xlate_rdev_rw_ops;
-#define XLATE_REGION_DEV_INIT(access_dev_, sub_offset_, sub_size_, \
- parent_sz_, ops_) \
+#define XLATE_REGION_DEV_INIT(window_arr_, parent_sz_, ops_) \
{ \
- .access_dev = access_dev_, \
- .sub_region = { \
- .offset = (sub_offset_), \
- .size = (sub_size_), \
- }, \
+ .window_count = ARRAY_SIZE(window_arr_), \
+ .window_arr = window_arr_, \
.rdev = REGION_DEV_INIT((ops_), 0, (parent_sz_)), \
}
-#define XLATE_REGION_DEV_RO_INIT(access_dev_, sub_offset_, sub_size_, \
- parent_sz_) \
- XLATE_REGION_DEV_INIT(access_dev_, sub_offset_, \
- sub_size_, parent_sz_, &xlate_rdev_ro_ops), \
+#define XLATE_REGION_DEV_RO_INIT(window_arr_, parent_sz_) \
+ XLATE_REGION_DEV_INIT(window_arr_, parent_sz_, &xlate_rdev_ro_ops)
-#define XLATE_REGION_DEV_RW_INIT(access_dev_, sub_offset_, sub_size_, \
- parent_sz_) \
- XLATE_REGION_DEV_INIT(access_dev_, sub_offset_, \
- sub_size_, parent_sz_, &xlate_rdev_rw_ops), \
+#define XLATE_REGION_DEV_RW_INIT(window_count_, window_arr_, parent_sz_) \
+ XLATE_REGION_DEV_INIT(window_arr_, parent_sz_, &xlate_rdev_rw_ops)
/* Helper to dynamically initialize xlate region device. */
void xlate_region_device_ro_init(struct xlate_region_device *xdev,
- const struct region_device *access_dev,
- size_t sub_offset, size_t sub_size,
+ size_t window_count, const struct xlate_window *window_arr,
size_t parent_size);
void xlate_region_device_rw_init(struct xlate_region_device *xdev,
- const struct region_device *access_dev,
- size_t sub_offset, size_t sub_size,
+ size_t window_count, const struct xlate_window *window_arr,
size_t parent_size);
+void xlate_window_init(struct xlate_window *window, const struct region_device *access_dev,
+ size_t sub_region_offset, size_t sub_region_size);
+
/* This type can be used for incoherent access where the read and write
* operations are backed by separate drivers. An example is x86 systems
* with memory mapped media for reading but use a spi flash driver for