Furquan Shaikh has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/47658 )
Change subject: Add xlate_window ......................................................................
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),