Furquan Shaikh has uploaded this change for review.

View Change

Add xlate_window

Change-Id: Id5b21ffca2c8d6a9dfc37a878429aed4a8301651
Signed-off-by: Furquan Shaikh <furquan@google.com>
---
M src/commonlib/include/commonlib/region.h
M src/commonlib/region.c
M src/soc/intel/apollolake/mmap_boot.c
3 files changed, 78 insertions(+), 56 deletions(-)

git pull ssh://review.coreboot.org:29418/coreboot refs/changes/58/47658/1
diff --git a/src/commonlib/include/commonlib/region.h b/src/commonlib/include/commonlib/region.h
index b9a984f..f8e0de4 100644
--- a/src/commonlib/include/commonlib/region.h
+++ b/src/commonlib/include/commonlib/region.h
@@ -215,9 +215,14 @@
* 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 {
+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,36 +230,28 @@

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_count_, window_arr_, parent_sz_, ops_) \
{ \
- .access_dev = access_dev_, \
- .sub_region = { \
- .offset = (sub_offset_), \
- .size = (sub_size_), \
- }, \
+ .window_count = window_count_, \
+ .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_count_, window_arr_, parent_sz_) \
+ XLATE_REGION_DEV_INIT(window_count_, 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_count_, 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);

/* This type can be used for incoherent access where the read and write
diff --git a/src/commonlib/region.c b/src/commonlib/region.c
index 467e8ff..ece8848 100644
--- a/src/commonlib/region.c
+++ b/src/commonlib/region.c
@@ -188,33 +188,29 @@

static void xlate_region_device_init(struct xlate_region_device *xdev,
const struct region_device_ops *ops,
- 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)
{
memset(xdev, 0, sizeof(*xdev));
- xdev->access_dev = access_dev;
- xdev->sub_region.offset = sub_offset;
- xdev->sub_region.size = sub_size;
+ xdev->window_count = window_count;
+ xdev->window_arr = window_arr;
region_device_init(&xdev->rdev, ops, 0, parent_size);
}

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)
{
- xlate_region_device_init(xdev, &xlate_rdev_ro_ops, access_dev,
- sub_offset, sub_size, parent_size);
+ xlate_region_device_init(xdev, &xlate_rdev_ro_ops, window_count, window_arr,
+ 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)
{
- xlate_region_device_init(xdev, &xlate_rdev_rw_ops, access_dev,
- sub_offset, sub_size, parent_size);
+ xlate_region_device_init(xdev, &xlate_rdev_rw_ops, window_count, window_arr,
+ parent_size);
}

static void *mdev_mmap(const struct region_device *rd, size_t offset,
@@ -321,6 +317,21 @@
return 0;
}

+static const struct xlate_window *xlate_find_window(const struct xlate_region_device *xldev,
+ const struct region *req)
+{
+ size_t i;
+ const struct xlate_window *xlwindow;
+
+ for (i = 0; i < xldev->window_count; i++) {
+ xlwindow = &xldev->window_arr[i];
+ if (region_is_subregion(&xlwindow->sub_region, req))
+ return xlwindow;
+ }
+
+ return NULL;
+}
+
static void *xlate_mmap(const struct region_device *rd, size_t offset,
size_t size)
{
@@ -329,24 +340,22 @@
.offset = offset,
.size = size,
};
+ const struct xlate_window *xlwindow;

xldev = container_of(rd, __typeof__(*xldev), rdev);

- if (!region_is_subregion(&xldev->sub_region, &req))
+ xlwindow = xlate_find_window(xldev, &req);
+ if (!xlwindow)
return NULL;

- offset -= region_offset(&xldev->sub_region);
+ offset -= region_offset(&xlwindow->sub_region);

- return rdev_mmap(xldev->access_dev, offset, size);
+ return rdev_mmap(xlwindow->access_dev, offset, size);
}

-static int xlate_munmap(const struct region_device *rd, void *mapping)
+static int xlate_munmap(const struct region_device *rd __unused, void *mapping __unused)
{
- const struct xlate_region_device *xldev;
-
- xldev = container_of(rd, __typeof__(*xldev), rdev);
-
- return rdev_munmap(xldev->access_dev, mapping);
+ return 0;
}

static ssize_t xlate_readat(const struct region_device *rd, void *b,
@@ -356,16 +365,18 @@
.offset = offset,
.size = size,
};
+ const struct xlate_window *xlwindow;
const struct xlate_region_device *xldev;

xldev = container_of(rd, __typeof__(*xldev), rdev);

- if (!region_is_subregion(&xldev->sub_region, &req))
+ xlwindow = xlate_find_window(xldev, &req);
+ if (!xlwindow)
return -1;

- offset -= region_offset(&xldev->sub_region);
+ offset -= region_offset(&xlwindow->sub_region);

- return rdev_readat(xldev->access_dev, b, offset, size);
+ return rdev_readat(xlwindow->access_dev, b, offset, size);
}

static ssize_t xlate_writeat(const struct region_device *rd, const void *b,
@@ -375,16 +386,18 @@
.offset = offset,
.size = size,
};
+ const struct xlate_window *xlwindow;
const struct xlate_region_device *xldev;

xldev = container_of(rd, __typeof__(*xldev), rdev);

- if (!region_is_subregion(&xldev->sub_region, &req))
+ xlwindow = xlate_find_window(xldev, &req);
+ if (!xlwindow)
return -1;

- offset -= region_offset(&xldev->sub_region);
+ offset -= region_offset(&xlwindow->sub_region);

- return rdev_writeat(xldev->access_dev, b, offset, size);
+ return rdev_writeat(xlwindow->access_dev, b, offset, size);
}

static ssize_t xlate_eraseat(const struct region_device *rd,
@@ -394,16 +407,18 @@
.offset = offset,
.size = size,
};
+ const struct xlate_window *xlwindow;
const struct xlate_region_device *xldev;

xldev = container_of(rd, __typeof__(*xldev), rdev);

- if (!region_is_subregion(&xldev->sub_region, &req))
+ xlwindow = xlate_find_window(xldev, &req);
+ if (!xlwindow)
return -1;

- offset -= region_offset(&xldev->sub_region);
+ offset -= region_offset(&xlwindow->sub_region);

- return rdev_eraseat(xldev->access_dev, offset, size);
+ return rdev_eraseat(xlwindow->access_dev, offset, size);
}

const struct region_device_ops xlate_rdev_ro_ops = {
diff --git a/src/soc/intel/apollolake/mmap_boot.c b/src/soc/intel/apollolake/mmap_boot.c
index 30c629e..775354d 100644
--- a/src/soc/intel/apollolake/mmap_boot.c
+++ b/src/soc/intel/apollolake/mmap_boot.c
@@ -43,6 +43,7 @@

static struct mem_region_device shadow_dev;
static struct xlate_region_device real_dev;
+static struct xlate_window real_dev_window;

static void bios_mmap_init(void)
{
@@ -68,17 +69,26 @@
mem_region_device_ro_init(&shadow_dev, (void *)base,
bios_mapped_size);

- xlate_region_device_ro_init(&real_dev, &shadow_dev.rdev,
- start, bios_mapped_size,
- CONFIG_ROM_SIZE);
+ real_dev_window.access_dev = &shadow_dev.rdev;
+ real_dev_window.sub_region.offset = start;
+ real_dev_window.sub_region.size = bios_mapped_size;
+
+ xlate_region_device_ro_init(&real_dev, 1, &real_dev_window, CONFIG_ROM_SIZE);

bios_size = size;

/* Check that the CBFS lies within the memory mapped area. It's too
easy to forget the SRAM mapping when crafting an FMAP file. */
struct region cbfs_region;
- if (!fmap_locate_area("COREBOOT", &cbfs_region) &&
- !region_is_subregion(&real_dev.sub_region, &cbfs_region))
+ void *map;
+
+ if (fmap_locate_area("COREBOOT", &cbfs_region))
+ return;
+
+ map = rdev_mmap(&real_dev.rdev, region_offset(&cbfs_region), region_sz(&cbfs_region));
+ if (map)
+ rdev_munmap(&real_dev.rdev, map);
+ else
printk(BIOS_CRIT,
"ERROR: CBFS @ %zx size %zx exceeds mem-mapped area @ %zx size %zx\n",
region_offset(&cbfs_region), region_sz(&cbfs_region),

To view, visit change 47658. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-Change-Id: Id5b21ffca2c8d6a9dfc37a878429aed4a8301651
Gerrit-Change-Number: 47658
Gerrit-PatchSet: 1
Gerrit-Owner: Furquan Shaikh <furquan@google.com>
Gerrit-MessageType: newchange