2020-04-02 23:48:05 +02:00
|
|
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
2015-03-26 20:39:07 +01:00
|
|
|
|
2015-12-16 00:49:12 +01:00
|
|
|
#include <commonlib/helpers.h>
|
2015-09-08 20:34:43 +02:00
|
|
|
#include <commonlib/region.h>
|
2015-03-26 20:39:07 +01:00
|
|
|
#include <string.h>
|
|
|
|
|
2017-12-14 23:22:04 +01:00
|
|
|
int region_is_subregion(const struct region *p, const struct region *c)
|
2015-03-26 20:39:07 +01:00
|
|
|
{
|
|
|
|
if (region_offset(c) < region_offset(p))
|
|
|
|
return 0;
|
|
|
|
|
2019-08-16 06:25:16 +02:00
|
|
|
if (region_end(c) > region_end(p))
|
2015-03-26 20:39:07 +01:00
|
|
|
return 0;
|
|
|
|
|
2019-08-16 06:25:16 +02:00
|
|
|
if (region_end(c) < region_offset(c))
|
2015-03-26 20:39:07 +01:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int normalize_and_ok(const struct region *outer, struct region *inner)
|
|
|
|
{
|
|
|
|
inner->offset += region_offset(outer);
|
2017-12-14 23:22:04 +01:00
|
|
|
return region_is_subregion(outer, inner);
|
2015-03-26 20:39:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static const struct region_device *rdev_root(const struct region_device *rdev)
|
|
|
|
{
|
|
|
|
if (rdev->root == NULL)
|
|
|
|
return rdev;
|
|
|
|
return rdev->root;
|
|
|
|
}
|
|
|
|
|
2015-12-15 20:29:41 +01:00
|
|
|
ssize_t rdev_relative_offset(const struct region_device *p,
|
|
|
|
const struct region_device *c)
|
|
|
|
{
|
|
|
|
if (rdev_root(p) != rdev_root(c))
|
|
|
|
return -1;
|
|
|
|
|
2017-12-14 23:22:04 +01:00
|
|
|
if (!region_is_subregion(&p->region, &c->region))
|
2015-12-15 20:29:41 +01:00
|
|
|
return -1;
|
|
|
|
|
|
|
|
return region_device_offset(c) - region_device_offset(p);
|
|
|
|
}
|
|
|
|
|
2015-03-26 20:39:07 +01:00
|
|
|
void *rdev_mmap(const struct region_device *rd, size_t offset, size_t size)
|
|
|
|
{
|
|
|
|
const struct region_device *rdev;
|
|
|
|
struct region req = {
|
|
|
|
.offset = offset,
|
|
|
|
.size = size,
|
|
|
|
};
|
|
|
|
|
|
|
|
if (!normalize_and_ok(&rd->region, &req))
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
rdev = rdev_root(rd);
|
|
|
|
|
2016-08-10 18:39:00 +02:00
|
|
|
if (rdev->ops->mmap == NULL)
|
|
|
|
return NULL;
|
|
|
|
|
2015-03-26 20:39:07 +01:00
|
|
|
return rdev->ops->mmap(rdev, req.offset, req.size);
|
|
|
|
}
|
|
|
|
|
|
|
|
int rdev_munmap(const struct region_device *rd, void *mapping)
|
|
|
|
{
|
|
|
|
const struct region_device *rdev;
|
|
|
|
|
|
|
|
rdev = rdev_root(rd);
|
|
|
|
|
2016-08-10 18:39:00 +02:00
|
|
|
if (rdev->ops->munmap == NULL)
|
|
|
|
return -1;
|
|
|
|
|
2015-03-26 20:39:07 +01:00
|
|
|
return rdev->ops->munmap(rdev, mapping);
|
|
|
|
}
|
|
|
|
|
|
|
|
ssize_t rdev_readat(const struct region_device *rd, void *b, size_t offset,
|
|
|
|
size_t size)
|
|
|
|
{
|
|
|
|
const struct region_device *rdev;
|
|
|
|
struct region req = {
|
|
|
|
.offset = offset,
|
|
|
|
.size = size,
|
|
|
|
};
|
|
|
|
|
|
|
|
if (!normalize_and_ok(&rd->region, &req))
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
rdev = rdev_root(rd);
|
|
|
|
|
|
|
|
return rdev->ops->readat(rdev, b, req.offset, req.size);
|
|
|
|
}
|
|
|
|
|
2016-08-04 21:33:58 +02:00
|
|
|
ssize_t rdev_writeat(const struct region_device *rd, const void *b,
|
|
|
|
size_t offset, size_t size)
|
2016-06-22 21:09:08 +02:00
|
|
|
{
|
|
|
|
const struct region_device *rdev;
|
|
|
|
struct region req = {
|
|
|
|
.offset = offset,
|
|
|
|
.size = size,
|
|
|
|
};
|
|
|
|
|
|
|
|
if (!normalize_and_ok(&rd->region, &req))
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
rdev = rdev_root(rd);
|
|
|
|
|
|
|
|
if (rdev->ops->writeat == NULL)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
return rdev->ops->writeat(rdev, b, req.offset, req.size);
|
|
|
|
}
|
|
|
|
|
|
|
|
ssize_t rdev_eraseat(const struct region_device *rd, size_t offset,
|
|
|
|
size_t size)
|
|
|
|
{
|
|
|
|
const struct region_device *rdev;
|
|
|
|
struct region req = {
|
|
|
|
.offset = offset,
|
|
|
|
.size = size,
|
|
|
|
};
|
|
|
|
|
|
|
|
if (!normalize_and_ok(&rd->region, &req))
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
rdev = rdev_root(rd);
|
|
|
|
|
|
|
|
/* If the eraseat ptr is NULL we assume that the erase
|
|
|
|
* function was completed successfully. */
|
|
|
|
if (rdev->ops->eraseat == NULL)
|
|
|
|
return size;
|
|
|
|
|
|
|
|
return rdev->ops->eraseat(rdev, req.offset, req.size);
|
|
|
|
}
|
|
|
|
|
2015-03-26 20:39:07 +01:00
|
|
|
int rdev_chain(struct region_device *child, const struct region_device *parent,
|
|
|
|
size_t offset, size_t size)
|
|
|
|
{
|
|
|
|
struct region req = {
|
|
|
|
.offset = offset,
|
|
|
|
.size = size,
|
|
|
|
};
|
|
|
|
|
|
|
|
if (!normalize_and_ok(&parent->region, &req))
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
/* Keep track of root region device. Note the offsets are relative
|
|
|
|
* to the root device. */
|
|
|
|
child->root = rdev_root(parent);
|
|
|
|
child->ops = NULL;
|
|
|
|
child->region.offset = req.offset;
|
|
|
|
child->region.size = req.size;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2015-03-27 07:03:45 +01:00
|
|
|
|
2016-06-22 21:09:08 +02:00
|
|
|
static void mem_region_device_init(struct mem_region_device *mdev,
|
|
|
|
const struct region_device_ops *ops, void *base, size_t size)
|
2015-03-27 07:03:45 +01:00
|
|
|
{
|
|
|
|
memset(mdev, 0, sizeof(*mdev));
|
|
|
|
mdev->base = base;
|
2016-06-22 21:09:08 +02:00
|
|
|
mdev->rdev.ops = ops;
|
2015-03-27 07:03:45 +01:00
|
|
|
mdev->rdev.region.size = size;
|
|
|
|
}
|
|
|
|
|
2016-06-22 21:09:08 +02:00
|
|
|
void mem_region_device_ro_init(struct mem_region_device *mdev, void *base,
|
|
|
|
size_t size)
|
|
|
|
{
|
|
|
|
return mem_region_device_init(mdev, &mem_rdev_ro_ops, base, size);
|
|
|
|
}
|
|
|
|
|
|
|
|
void mem_region_device_rw_init(struct mem_region_device *mdev, void *base,
|
|
|
|
size_t size)
|
|
|
|
{
|
|
|
|
return mem_region_device_init(mdev, &mem_rdev_rw_ops, base, size);
|
|
|
|
}
|
|
|
|
|
2016-06-20 08:16:45 +02:00
|
|
|
void region_device_init(struct region_device *rdev,
|
|
|
|
const struct region_device_ops *ops, size_t offset,
|
|
|
|
size_t size)
|
|
|
|
{
|
|
|
|
memset(rdev, 0, sizeof(*rdev));
|
|
|
|
rdev->root = NULL;
|
|
|
|
rdev->ops = ops;
|
|
|
|
rdev->region.offset = offset;
|
|
|
|
rdev->region.size = size;
|
|
|
|
}
|
|
|
|
|
2016-06-22 21:09:08 +02:00
|
|
|
static void xlate_region_device_init(struct xlate_region_device *xdev,
|
|
|
|
const struct region_device_ops *ops,
|
commonlib/region: Allow multiple windows for xlate_region_dev
This change updates the translated region device (xlate_region_dev) to
support multiple translation windows from the 1st address space to
2nd address space. The address spaces described by the translation
windows can be non-contiguous in both spaces. This is required so that
newer x86 platforms can describe memory mapping of SPI flash into
multiple decode windows in order to support greater than 16MiB of
memory mapped space.
Since the windows can be non-contiguous, it introduces new
restrictions on the region device ops - any operation performed on the
translated region device is limited to only 1 window at a time. This
restriction is primarily because of the mmap operation. The caller
expects that the memory mapped space is contiguous, however, that is
not true anymore. Thus, even though the other operations (readat,
writeat, eraseat) can be updated to translate into multiple operations
one for each access device, all operations across multiple windows are
prohibited for the sake of consistency.
It is the responsibility of the platform to ensure that any section
that is operated on using the translated region device does not span
multiple windows in the fmap description.
One additional difference in behavior is xlate_region_device does not
perform any action in munmap call. This is because it does not keep
track of the access device that was used to service the mmap
request. Currently, xlate_region_device is used only by memory mapped
boot media on the backend. So, not doing unmap is fine. If this needs
to be changed in the future, xlate_region_device will have to accept a
pre-allocated space from the caller to keep track of all mapping
requests.
BUG=b:171534504
Change-Id: Id5b21ffca2c8d6a9dfc37a878429aed4a8301651
Signed-off-by: Furquan Shaikh <furquan@google.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/47658
Reviewed-by: Duncan Laurie <dlaurie@chromium.org>
Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
2020-11-12 08:23:13 +01:00
|
|
|
size_t window_count, const struct xlate_window *window_arr,
|
2016-06-22 21:09:08 +02:00
|
|
|
size_t parent_size)
|
2016-06-20 08:16:45 +02:00
|
|
|
{
|
|
|
|
memset(xdev, 0, sizeof(*xdev));
|
commonlib/region: Allow multiple windows for xlate_region_dev
This change updates the translated region device (xlate_region_dev) to
support multiple translation windows from the 1st address space to
2nd address space. The address spaces described by the translation
windows can be non-contiguous in both spaces. This is required so that
newer x86 platforms can describe memory mapping of SPI flash into
multiple decode windows in order to support greater than 16MiB of
memory mapped space.
Since the windows can be non-contiguous, it introduces new
restrictions on the region device ops - any operation performed on the
translated region device is limited to only 1 window at a time. This
restriction is primarily because of the mmap operation. The caller
expects that the memory mapped space is contiguous, however, that is
not true anymore. Thus, even though the other operations (readat,
writeat, eraseat) can be updated to translate into multiple operations
one for each access device, all operations across multiple windows are
prohibited for the sake of consistency.
It is the responsibility of the platform to ensure that any section
that is operated on using the translated region device does not span
multiple windows in the fmap description.
One additional difference in behavior is xlate_region_device does not
perform any action in munmap call. This is because it does not keep
track of the access device that was used to service the mmap
request. Currently, xlate_region_device is used only by memory mapped
boot media on the backend. So, not doing unmap is fine. If this needs
to be changed in the future, xlate_region_device will have to accept a
pre-allocated space from the caller to keep track of all mapping
requests.
BUG=b:171534504
Change-Id: Id5b21ffca2c8d6a9dfc37a878429aed4a8301651
Signed-off-by: Furquan Shaikh <furquan@google.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/47658
Reviewed-by: Duncan Laurie <dlaurie@chromium.org>
Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
2020-11-12 08:23:13 +01:00
|
|
|
xdev->window_count = window_count;
|
|
|
|
xdev->window_arr = window_arr;
|
2016-06-22 21:09:08 +02:00
|
|
|
region_device_init(&xdev->rdev, ops, 0, parent_size);
|
|
|
|
}
|
|
|
|
|
|
|
|
void xlate_region_device_ro_init(struct xlate_region_device *xdev,
|
commonlib/region: Allow multiple windows for xlate_region_dev
This change updates the translated region device (xlate_region_dev) to
support multiple translation windows from the 1st address space to
2nd address space. The address spaces described by the translation
windows can be non-contiguous in both spaces. This is required so that
newer x86 platforms can describe memory mapping of SPI flash into
multiple decode windows in order to support greater than 16MiB of
memory mapped space.
Since the windows can be non-contiguous, it introduces new
restrictions on the region device ops - any operation performed on the
translated region device is limited to only 1 window at a time. This
restriction is primarily because of the mmap operation. The caller
expects that the memory mapped space is contiguous, however, that is
not true anymore. Thus, even though the other operations (readat,
writeat, eraseat) can be updated to translate into multiple operations
one for each access device, all operations across multiple windows are
prohibited for the sake of consistency.
It is the responsibility of the platform to ensure that any section
that is operated on using the translated region device does not span
multiple windows in the fmap description.
One additional difference in behavior is xlate_region_device does not
perform any action in munmap call. This is because it does not keep
track of the access device that was used to service the mmap
request. Currently, xlate_region_device is used only by memory mapped
boot media on the backend. So, not doing unmap is fine. If this needs
to be changed in the future, xlate_region_device will have to accept a
pre-allocated space from the caller to keep track of all mapping
requests.
BUG=b:171534504
Change-Id: Id5b21ffca2c8d6a9dfc37a878429aed4a8301651
Signed-off-by: Furquan Shaikh <furquan@google.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/47658
Reviewed-by: Duncan Laurie <dlaurie@chromium.org>
Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
2020-11-12 08:23:13 +01:00
|
|
|
size_t window_count, const struct xlate_window *window_arr,
|
2016-06-22 21:09:08 +02:00
|
|
|
size_t parent_size)
|
|
|
|
{
|
commonlib/region: Allow multiple windows for xlate_region_dev
This change updates the translated region device (xlate_region_dev) to
support multiple translation windows from the 1st address space to
2nd address space. The address spaces described by the translation
windows can be non-contiguous in both spaces. This is required so that
newer x86 platforms can describe memory mapping of SPI flash into
multiple decode windows in order to support greater than 16MiB of
memory mapped space.
Since the windows can be non-contiguous, it introduces new
restrictions on the region device ops - any operation performed on the
translated region device is limited to only 1 window at a time. This
restriction is primarily because of the mmap operation. The caller
expects that the memory mapped space is contiguous, however, that is
not true anymore. Thus, even though the other operations (readat,
writeat, eraseat) can be updated to translate into multiple operations
one for each access device, all operations across multiple windows are
prohibited for the sake of consistency.
It is the responsibility of the platform to ensure that any section
that is operated on using the translated region device does not span
multiple windows in the fmap description.
One additional difference in behavior is xlate_region_device does not
perform any action in munmap call. This is because it does not keep
track of the access device that was used to service the mmap
request. Currently, xlate_region_device is used only by memory mapped
boot media on the backend. So, not doing unmap is fine. If this needs
to be changed in the future, xlate_region_device will have to accept a
pre-allocated space from the caller to keep track of all mapping
requests.
BUG=b:171534504
Change-Id: Id5b21ffca2c8d6a9dfc37a878429aed4a8301651
Signed-off-by: Furquan Shaikh <furquan@google.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/47658
Reviewed-by: Duncan Laurie <dlaurie@chromium.org>
Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
2020-11-12 08:23:13 +01:00
|
|
|
xlate_region_device_init(xdev, &xlate_rdev_ro_ops, window_count, window_arr,
|
|
|
|
parent_size);
|
2016-06-22 21:09:08 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void xlate_region_device_rw_init(struct xlate_region_device *xdev,
|
commonlib/region: Allow multiple windows for xlate_region_dev
This change updates the translated region device (xlate_region_dev) to
support multiple translation windows from the 1st address space to
2nd address space. The address spaces described by the translation
windows can be non-contiguous in both spaces. This is required so that
newer x86 platforms can describe memory mapping of SPI flash into
multiple decode windows in order to support greater than 16MiB of
memory mapped space.
Since the windows can be non-contiguous, it introduces new
restrictions on the region device ops - any operation performed on the
translated region device is limited to only 1 window at a time. This
restriction is primarily because of the mmap operation. The caller
expects that the memory mapped space is contiguous, however, that is
not true anymore. Thus, even though the other operations (readat,
writeat, eraseat) can be updated to translate into multiple operations
one for each access device, all operations across multiple windows are
prohibited for the sake of consistency.
It is the responsibility of the platform to ensure that any section
that is operated on using the translated region device does not span
multiple windows in the fmap description.
One additional difference in behavior is xlate_region_device does not
perform any action in munmap call. This is because it does not keep
track of the access device that was used to service the mmap
request. Currently, xlate_region_device is used only by memory mapped
boot media on the backend. So, not doing unmap is fine. If this needs
to be changed in the future, xlate_region_device will have to accept a
pre-allocated space from the caller to keep track of all mapping
requests.
BUG=b:171534504
Change-Id: Id5b21ffca2c8d6a9dfc37a878429aed4a8301651
Signed-off-by: Furquan Shaikh <furquan@google.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/47658
Reviewed-by: Duncan Laurie <dlaurie@chromium.org>
Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
2020-11-12 08:23:13 +01:00
|
|
|
size_t window_count, const struct xlate_window *window_arr,
|
2016-06-22 21:09:08 +02:00
|
|
|
size_t parent_size)
|
|
|
|
{
|
commonlib/region: Allow multiple windows for xlate_region_dev
This change updates the translated region device (xlate_region_dev) to
support multiple translation windows from the 1st address space to
2nd address space. The address spaces described by the translation
windows can be non-contiguous in both spaces. This is required so that
newer x86 platforms can describe memory mapping of SPI flash into
multiple decode windows in order to support greater than 16MiB of
memory mapped space.
Since the windows can be non-contiguous, it introduces new
restrictions on the region device ops - any operation performed on the
translated region device is limited to only 1 window at a time. This
restriction is primarily because of the mmap operation. The caller
expects that the memory mapped space is contiguous, however, that is
not true anymore. Thus, even though the other operations (readat,
writeat, eraseat) can be updated to translate into multiple operations
one for each access device, all operations across multiple windows are
prohibited for the sake of consistency.
It is the responsibility of the platform to ensure that any section
that is operated on using the translated region device does not span
multiple windows in the fmap description.
One additional difference in behavior is xlate_region_device does not
perform any action in munmap call. This is because it does not keep
track of the access device that was used to service the mmap
request. Currently, xlate_region_device is used only by memory mapped
boot media on the backend. So, not doing unmap is fine. If this needs
to be changed in the future, xlate_region_device will have to accept a
pre-allocated space from the caller to keep track of all mapping
requests.
BUG=b:171534504
Change-Id: Id5b21ffca2c8d6a9dfc37a878429aed4a8301651
Signed-off-by: Furquan Shaikh <furquan@google.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/47658
Reviewed-by: Duncan Laurie <dlaurie@chromium.org>
Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
2020-11-12 08:23:13 +01:00
|
|
|
xlate_region_device_init(xdev, &xlate_rdev_rw_ops, window_count, window_arr,
|
|
|
|
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)
|
|
|
|
{
|
|
|
|
window->access_dev = access_dev;
|
|
|
|
window->sub_region.offset = sub_region_offset;
|
|
|
|
window->sub_region.size = sub_region_size;
|
2016-06-20 08:16:45 +02:00
|
|
|
}
|
|
|
|
|
2015-03-27 07:03:45 +01:00
|
|
|
static void *mdev_mmap(const struct region_device *rd, size_t offset,
|
2015-12-16 00:49:12 +01:00
|
|
|
size_t size __unused)
|
2015-03-27 07:03:45 +01:00
|
|
|
{
|
|
|
|
const struct mem_region_device *mdev;
|
|
|
|
|
2015-12-16 00:49:12 +01:00
|
|
|
mdev = container_of(rd, __typeof__(*mdev), rdev);
|
2015-03-27 07:03:45 +01:00
|
|
|
|
|
|
|
return &mdev->base[offset];
|
|
|
|
}
|
|
|
|
|
2017-03-10 20:02:11 +01:00
|
|
|
static int mdev_munmap(const struct region_device *rd __unused,
|
2015-12-16 00:49:12 +01:00
|
|
|
void *mapping __unused)
|
2015-03-27 07:03:45 +01:00
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static ssize_t mdev_readat(const struct region_device *rd, void *b,
|
|
|
|
size_t offset, size_t size)
|
|
|
|
{
|
|
|
|
const struct mem_region_device *mdev;
|
|
|
|
|
2015-12-16 00:49:12 +01:00
|
|
|
mdev = container_of(rd, __typeof__(*mdev), rdev);
|
2015-03-27 07:03:45 +01:00
|
|
|
|
|
|
|
memcpy(b, &mdev->base[offset], size);
|
|
|
|
|
|
|
|
return size;
|
|
|
|
}
|
|
|
|
|
2016-08-04 21:33:58 +02:00
|
|
|
static ssize_t mdev_writeat(const struct region_device *rd, const void *b,
|
2016-06-22 21:09:08 +02:00
|
|
|
size_t offset, size_t size)
|
|
|
|
{
|
|
|
|
const struct mem_region_device *mdev;
|
|
|
|
|
|
|
|
mdev = container_of(rd, __typeof__(*mdev), rdev);
|
|
|
|
|
|
|
|
memcpy(&mdev->base[offset], b, size);
|
|
|
|
|
|
|
|
return size;
|
|
|
|
}
|
|
|
|
|
|
|
|
static ssize_t mdev_eraseat(const struct region_device *rd, size_t offset,
|
|
|
|
size_t size)
|
|
|
|
{
|
|
|
|
const struct mem_region_device *mdev;
|
|
|
|
|
|
|
|
mdev = container_of(rd, __typeof__(*mdev), rdev);
|
|
|
|
|
|
|
|
memset(&mdev->base[offset], 0, size);
|
|
|
|
|
|
|
|
return size;
|
|
|
|
}
|
|
|
|
|
|
|
|
const struct region_device_ops mem_rdev_ro_ops = {
|
|
|
|
.mmap = mdev_mmap,
|
|
|
|
.munmap = mdev_munmap,
|
|
|
|
.readat = mdev_readat,
|
|
|
|
};
|
|
|
|
|
|
|
|
const struct region_device_ops mem_rdev_rw_ops = {
|
2015-03-27 07:03:45 +01:00
|
|
|
.mmap = mdev_mmap,
|
|
|
|
.munmap = mdev_munmap,
|
|
|
|
.readat = mdev_readat,
|
2016-06-22 21:09:08 +02:00
|
|
|
.writeat = mdev_writeat,
|
|
|
|
.eraseat = mdev_eraseat,
|
2015-03-27 07:03:45 +01:00
|
|
|
};
|
2015-03-27 07:58:06 +01:00
|
|
|
|
|
|
|
void mmap_helper_device_init(struct mmap_helper_region_device *mdev,
|
|
|
|
void *cache, size_t cache_size)
|
|
|
|
{
|
|
|
|
mem_pool_init(&mdev->pool, cache, cache_size);
|
|
|
|
}
|
|
|
|
|
|
|
|
void *mmap_helper_rdev_mmap(const struct region_device *rd, size_t offset,
|
|
|
|
size_t size)
|
|
|
|
{
|
|
|
|
struct mmap_helper_region_device *mdev;
|
|
|
|
void *mapping;
|
|
|
|
|
2015-12-16 00:49:12 +01:00
|
|
|
mdev = container_of((void *)rd, __typeof__(*mdev), rdev);
|
2015-03-27 07:58:06 +01:00
|
|
|
|
|
|
|
mapping = mem_pool_alloc(&mdev->pool, size);
|
|
|
|
|
|
|
|
if (mapping == NULL)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
if (rd->ops->readat(rd, mapping, offset, size) != size) {
|
|
|
|
mem_pool_free(&mdev->pool, mapping);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return mapping;
|
|
|
|
}
|
|
|
|
|
|
|
|
int mmap_helper_rdev_munmap(const struct region_device *rd, void *mapping)
|
|
|
|
{
|
|
|
|
struct mmap_helper_region_device *mdev;
|
|
|
|
|
2015-12-16 00:49:12 +01:00
|
|
|
mdev = container_of((void *)rd, __typeof__(*mdev), rdev);
|
2015-03-27 07:58:06 +01:00
|
|
|
|
|
|
|
mem_pool_free(&mdev->pool, mapping);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2015-10-28 22:09:42 +01:00
|
|
|
|
commonlib/region: Allow multiple windows for xlate_region_dev
This change updates the translated region device (xlate_region_dev) to
support multiple translation windows from the 1st address space to
2nd address space. The address spaces described by the translation
windows can be non-contiguous in both spaces. This is required so that
newer x86 platforms can describe memory mapping of SPI flash into
multiple decode windows in order to support greater than 16MiB of
memory mapped space.
Since the windows can be non-contiguous, it introduces new
restrictions on the region device ops - any operation performed on the
translated region device is limited to only 1 window at a time. This
restriction is primarily because of the mmap operation. The caller
expects that the memory mapped space is contiguous, however, that is
not true anymore. Thus, even though the other operations (readat,
writeat, eraseat) can be updated to translate into multiple operations
one for each access device, all operations across multiple windows are
prohibited for the sake of consistency.
It is the responsibility of the platform to ensure that any section
that is operated on using the translated region device does not span
multiple windows in the fmap description.
One additional difference in behavior is xlate_region_device does not
perform any action in munmap call. This is because it does not keep
track of the access device that was used to service the mmap
request. Currently, xlate_region_device is used only by memory mapped
boot media on the backend. So, not doing unmap is fine. If this needs
to be changed in the future, xlate_region_device will have to accept a
pre-allocated space from the caller to keep track of all mapping
requests.
BUG=b:171534504
Change-Id: Id5b21ffca2c8d6a9dfc37a878429aed4a8301651
Signed-off-by: Furquan Shaikh <furquan@google.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/47658
Reviewed-by: Duncan Laurie <dlaurie@chromium.org>
Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
2020-11-12 08:23:13 +01:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2015-10-28 22:09:42 +01:00
|
|
|
static void *xlate_mmap(const struct region_device *rd, size_t offset,
|
|
|
|
size_t size)
|
|
|
|
{
|
|
|
|
const struct xlate_region_device *xldev;
|
|
|
|
struct region req = {
|
|
|
|
.offset = offset,
|
|
|
|
.size = size,
|
|
|
|
};
|
commonlib/region: Allow multiple windows for xlate_region_dev
This change updates the translated region device (xlate_region_dev) to
support multiple translation windows from the 1st address space to
2nd address space. The address spaces described by the translation
windows can be non-contiguous in both spaces. This is required so that
newer x86 platforms can describe memory mapping of SPI flash into
multiple decode windows in order to support greater than 16MiB of
memory mapped space.
Since the windows can be non-contiguous, it introduces new
restrictions on the region device ops - any operation performed on the
translated region device is limited to only 1 window at a time. This
restriction is primarily because of the mmap operation. The caller
expects that the memory mapped space is contiguous, however, that is
not true anymore. Thus, even though the other operations (readat,
writeat, eraseat) can be updated to translate into multiple operations
one for each access device, all operations across multiple windows are
prohibited for the sake of consistency.
It is the responsibility of the platform to ensure that any section
that is operated on using the translated region device does not span
multiple windows in the fmap description.
One additional difference in behavior is xlate_region_device does not
perform any action in munmap call. This is because it does not keep
track of the access device that was used to service the mmap
request. Currently, xlate_region_device is used only by memory mapped
boot media on the backend. So, not doing unmap is fine. If this needs
to be changed in the future, xlate_region_device will have to accept a
pre-allocated space from the caller to keep track of all mapping
requests.
BUG=b:171534504
Change-Id: Id5b21ffca2c8d6a9dfc37a878429aed4a8301651
Signed-off-by: Furquan Shaikh <furquan@google.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/47658
Reviewed-by: Duncan Laurie <dlaurie@chromium.org>
Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
2020-11-12 08:23:13 +01:00
|
|
|
const struct xlate_window *xlwindow;
|
2015-10-28 22:09:42 +01:00
|
|
|
|
2015-12-16 00:49:12 +01:00
|
|
|
xldev = container_of(rd, __typeof__(*xldev), rdev);
|
2015-10-28 22:09:42 +01:00
|
|
|
|
commonlib/region: Allow multiple windows for xlate_region_dev
This change updates the translated region device (xlate_region_dev) to
support multiple translation windows from the 1st address space to
2nd address space. The address spaces described by the translation
windows can be non-contiguous in both spaces. This is required so that
newer x86 platforms can describe memory mapping of SPI flash into
multiple decode windows in order to support greater than 16MiB of
memory mapped space.
Since the windows can be non-contiguous, it introduces new
restrictions on the region device ops - any operation performed on the
translated region device is limited to only 1 window at a time. This
restriction is primarily because of the mmap operation. The caller
expects that the memory mapped space is contiguous, however, that is
not true anymore. Thus, even though the other operations (readat,
writeat, eraseat) can be updated to translate into multiple operations
one for each access device, all operations across multiple windows are
prohibited for the sake of consistency.
It is the responsibility of the platform to ensure that any section
that is operated on using the translated region device does not span
multiple windows in the fmap description.
One additional difference in behavior is xlate_region_device does not
perform any action in munmap call. This is because it does not keep
track of the access device that was used to service the mmap
request. Currently, xlate_region_device is used only by memory mapped
boot media on the backend. So, not doing unmap is fine. If this needs
to be changed in the future, xlate_region_device will have to accept a
pre-allocated space from the caller to keep track of all mapping
requests.
BUG=b:171534504
Change-Id: Id5b21ffca2c8d6a9dfc37a878429aed4a8301651
Signed-off-by: Furquan Shaikh <furquan@google.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/47658
Reviewed-by: Duncan Laurie <dlaurie@chromium.org>
Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
2020-11-12 08:23:13 +01:00
|
|
|
xlwindow = xlate_find_window(xldev, &req);
|
|
|
|
if (!xlwindow)
|
2015-10-28 22:09:42 +01:00
|
|
|
return NULL;
|
|
|
|
|
commonlib/region: Allow multiple windows for xlate_region_dev
This change updates the translated region device (xlate_region_dev) to
support multiple translation windows from the 1st address space to
2nd address space. The address spaces described by the translation
windows can be non-contiguous in both spaces. This is required so that
newer x86 platforms can describe memory mapping of SPI flash into
multiple decode windows in order to support greater than 16MiB of
memory mapped space.
Since the windows can be non-contiguous, it introduces new
restrictions on the region device ops - any operation performed on the
translated region device is limited to only 1 window at a time. This
restriction is primarily because of the mmap operation. The caller
expects that the memory mapped space is contiguous, however, that is
not true anymore. Thus, even though the other operations (readat,
writeat, eraseat) can be updated to translate into multiple operations
one for each access device, all operations across multiple windows are
prohibited for the sake of consistency.
It is the responsibility of the platform to ensure that any section
that is operated on using the translated region device does not span
multiple windows in the fmap description.
One additional difference in behavior is xlate_region_device does not
perform any action in munmap call. This is because it does not keep
track of the access device that was used to service the mmap
request. Currently, xlate_region_device is used only by memory mapped
boot media on the backend. So, not doing unmap is fine. If this needs
to be changed in the future, xlate_region_device will have to accept a
pre-allocated space from the caller to keep track of all mapping
requests.
BUG=b:171534504
Change-Id: Id5b21ffca2c8d6a9dfc37a878429aed4a8301651
Signed-off-by: Furquan Shaikh <furquan@google.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/47658
Reviewed-by: Duncan Laurie <dlaurie@chromium.org>
Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
2020-11-12 08:23:13 +01:00
|
|
|
offset -= region_offset(&xlwindow->sub_region);
|
2015-10-28 22:09:42 +01:00
|
|
|
|
commonlib/region: Allow multiple windows for xlate_region_dev
This change updates the translated region device (xlate_region_dev) to
support multiple translation windows from the 1st address space to
2nd address space. The address spaces described by the translation
windows can be non-contiguous in both spaces. This is required so that
newer x86 platforms can describe memory mapping of SPI flash into
multiple decode windows in order to support greater than 16MiB of
memory mapped space.
Since the windows can be non-contiguous, it introduces new
restrictions on the region device ops - any operation performed on the
translated region device is limited to only 1 window at a time. This
restriction is primarily because of the mmap operation. The caller
expects that the memory mapped space is contiguous, however, that is
not true anymore. Thus, even though the other operations (readat,
writeat, eraseat) can be updated to translate into multiple operations
one for each access device, all operations across multiple windows are
prohibited for the sake of consistency.
It is the responsibility of the platform to ensure that any section
that is operated on using the translated region device does not span
multiple windows in the fmap description.
One additional difference in behavior is xlate_region_device does not
perform any action in munmap call. This is because it does not keep
track of the access device that was used to service the mmap
request. Currently, xlate_region_device is used only by memory mapped
boot media on the backend. So, not doing unmap is fine. If this needs
to be changed in the future, xlate_region_device will have to accept a
pre-allocated space from the caller to keep track of all mapping
requests.
BUG=b:171534504
Change-Id: Id5b21ffca2c8d6a9dfc37a878429aed4a8301651
Signed-off-by: Furquan Shaikh <furquan@google.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/47658
Reviewed-by: Duncan Laurie <dlaurie@chromium.org>
Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
2020-11-12 08:23:13 +01:00
|
|
|
return rdev_mmap(xlwindow->access_dev, offset, size);
|
2015-10-28 22:09:42 +01:00
|
|
|
}
|
|
|
|
|
commonlib/region: Allow multiple windows for xlate_region_dev
This change updates the translated region device (xlate_region_dev) to
support multiple translation windows from the 1st address space to
2nd address space. The address spaces described by the translation
windows can be non-contiguous in both spaces. This is required so that
newer x86 platforms can describe memory mapping of SPI flash into
multiple decode windows in order to support greater than 16MiB of
memory mapped space.
Since the windows can be non-contiguous, it introduces new
restrictions on the region device ops - any operation performed on the
translated region device is limited to only 1 window at a time. This
restriction is primarily because of the mmap operation. The caller
expects that the memory mapped space is contiguous, however, that is
not true anymore. Thus, even though the other operations (readat,
writeat, eraseat) can be updated to translate into multiple operations
one for each access device, all operations across multiple windows are
prohibited for the sake of consistency.
It is the responsibility of the platform to ensure that any section
that is operated on using the translated region device does not span
multiple windows in the fmap description.
One additional difference in behavior is xlate_region_device does not
perform any action in munmap call. This is because it does not keep
track of the access device that was used to service the mmap
request. Currently, xlate_region_device is used only by memory mapped
boot media on the backend. So, not doing unmap is fine. If this needs
to be changed in the future, xlate_region_device will have to accept a
pre-allocated space from the caller to keep track of all mapping
requests.
BUG=b:171534504
Change-Id: Id5b21ffca2c8d6a9dfc37a878429aed4a8301651
Signed-off-by: Furquan Shaikh <furquan@google.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/47658
Reviewed-by: Duncan Laurie <dlaurie@chromium.org>
Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
2020-11-12 08:23:13 +01:00
|
|
|
static int xlate_munmap(const struct region_device *rd __unused, void *mapping __unused)
|
2015-10-28 22:09:42 +01:00
|
|
|
{
|
commonlib/region: Allow multiple windows for xlate_region_dev
This change updates the translated region device (xlate_region_dev) to
support multiple translation windows from the 1st address space to
2nd address space. The address spaces described by the translation
windows can be non-contiguous in both spaces. This is required so that
newer x86 platforms can describe memory mapping of SPI flash into
multiple decode windows in order to support greater than 16MiB of
memory mapped space.
Since the windows can be non-contiguous, it introduces new
restrictions on the region device ops - any operation performed on the
translated region device is limited to only 1 window at a time. This
restriction is primarily because of the mmap operation. The caller
expects that the memory mapped space is contiguous, however, that is
not true anymore. Thus, even though the other operations (readat,
writeat, eraseat) can be updated to translate into multiple operations
one for each access device, all operations across multiple windows are
prohibited for the sake of consistency.
It is the responsibility of the platform to ensure that any section
that is operated on using the translated region device does not span
multiple windows in the fmap description.
One additional difference in behavior is xlate_region_device does not
perform any action in munmap call. This is because it does not keep
track of the access device that was used to service the mmap
request. Currently, xlate_region_device is used only by memory mapped
boot media on the backend. So, not doing unmap is fine. If this needs
to be changed in the future, xlate_region_device will have to accept a
pre-allocated space from the caller to keep track of all mapping
requests.
BUG=b:171534504
Change-Id: Id5b21ffca2c8d6a9dfc37a878429aed4a8301651
Signed-off-by: Furquan Shaikh <furquan@google.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/47658
Reviewed-by: Duncan Laurie <dlaurie@chromium.org>
Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
2020-11-12 08:23:13 +01:00
|
|
|
/*
|
|
|
|
* xlate_region_device does not keep track of the access device that was used to service
|
|
|
|
* a mmap request. So, munmap does not do anything. If munmap functionality is required,
|
|
|
|
* then xlate_region_device will have to be updated to accept some pre-allocated space
|
|
|
|
* from caller to keep track of the mapping requests. Since xlate_region_device is only
|
|
|
|
* used for memory mapped boot media on the backend right now, skipping munmap is fine.
|
|
|
|
*/
|
|
|
|
return 0;
|
2015-10-28 22:09:42 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static ssize_t xlate_readat(const struct region_device *rd, void *b,
|
|
|
|
size_t offset, size_t size)
|
|
|
|
{
|
|
|
|
struct region req = {
|
|
|
|
.offset = offset,
|
|
|
|
.size = size,
|
|
|
|
};
|
commonlib/region: Allow multiple windows for xlate_region_dev
This change updates the translated region device (xlate_region_dev) to
support multiple translation windows from the 1st address space to
2nd address space. The address spaces described by the translation
windows can be non-contiguous in both spaces. This is required so that
newer x86 platforms can describe memory mapping of SPI flash into
multiple decode windows in order to support greater than 16MiB of
memory mapped space.
Since the windows can be non-contiguous, it introduces new
restrictions on the region device ops - any operation performed on the
translated region device is limited to only 1 window at a time. This
restriction is primarily because of the mmap operation. The caller
expects that the memory mapped space is contiguous, however, that is
not true anymore. Thus, even though the other operations (readat,
writeat, eraseat) can be updated to translate into multiple operations
one for each access device, all operations across multiple windows are
prohibited for the sake of consistency.
It is the responsibility of the platform to ensure that any section
that is operated on using the translated region device does not span
multiple windows in the fmap description.
One additional difference in behavior is xlate_region_device does not
perform any action in munmap call. This is because it does not keep
track of the access device that was used to service the mmap
request. Currently, xlate_region_device is used only by memory mapped
boot media on the backend. So, not doing unmap is fine. If this needs
to be changed in the future, xlate_region_device will have to accept a
pre-allocated space from the caller to keep track of all mapping
requests.
BUG=b:171534504
Change-Id: Id5b21ffca2c8d6a9dfc37a878429aed4a8301651
Signed-off-by: Furquan Shaikh <furquan@google.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/47658
Reviewed-by: Duncan Laurie <dlaurie@chromium.org>
Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
2020-11-12 08:23:13 +01:00
|
|
|
const struct xlate_window *xlwindow;
|
2015-10-28 22:09:42 +01:00
|
|
|
const struct xlate_region_device *xldev;
|
|
|
|
|
2015-12-16 00:49:12 +01:00
|
|
|
xldev = container_of(rd, __typeof__(*xldev), rdev);
|
2015-10-28 22:09:42 +01:00
|
|
|
|
commonlib/region: Allow multiple windows for xlate_region_dev
This change updates the translated region device (xlate_region_dev) to
support multiple translation windows from the 1st address space to
2nd address space. The address spaces described by the translation
windows can be non-contiguous in both spaces. This is required so that
newer x86 platforms can describe memory mapping of SPI flash into
multiple decode windows in order to support greater than 16MiB of
memory mapped space.
Since the windows can be non-contiguous, it introduces new
restrictions on the region device ops - any operation performed on the
translated region device is limited to only 1 window at a time. This
restriction is primarily because of the mmap operation. The caller
expects that the memory mapped space is contiguous, however, that is
not true anymore. Thus, even though the other operations (readat,
writeat, eraseat) can be updated to translate into multiple operations
one for each access device, all operations across multiple windows are
prohibited for the sake of consistency.
It is the responsibility of the platform to ensure that any section
that is operated on using the translated region device does not span
multiple windows in the fmap description.
One additional difference in behavior is xlate_region_device does not
perform any action in munmap call. This is because it does not keep
track of the access device that was used to service the mmap
request. Currently, xlate_region_device is used only by memory mapped
boot media on the backend. So, not doing unmap is fine. If this needs
to be changed in the future, xlate_region_device will have to accept a
pre-allocated space from the caller to keep track of all mapping
requests.
BUG=b:171534504
Change-Id: Id5b21ffca2c8d6a9dfc37a878429aed4a8301651
Signed-off-by: Furquan Shaikh <furquan@google.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/47658
Reviewed-by: Duncan Laurie <dlaurie@chromium.org>
Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
2020-11-12 08:23:13 +01:00
|
|
|
xlwindow = xlate_find_window(xldev, &req);
|
|
|
|
if (!xlwindow)
|
2015-10-28 22:09:42 +01:00
|
|
|
return -1;
|
|
|
|
|
commonlib/region: Allow multiple windows for xlate_region_dev
This change updates the translated region device (xlate_region_dev) to
support multiple translation windows from the 1st address space to
2nd address space. The address spaces described by the translation
windows can be non-contiguous in both spaces. This is required so that
newer x86 platforms can describe memory mapping of SPI flash into
multiple decode windows in order to support greater than 16MiB of
memory mapped space.
Since the windows can be non-contiguous, it introduces new
restrictions on the region device ops - any operation performed on the
translated region device is limited to only 1 window at a time. This
restriction is primarily because of the mmap operation. The caller
expects that the memory mapped space is contiguous, however, that is
not true anymore. Thus, even though the other operations (readat,
writeat, eraseat) can be updated to translate into multiple operations
one for each access device, all operations across multiple windows are
prohibited for the sake of consistency.
It is the responsibility of the platform to ensure that any section
that is operated on using the translated region device does not span
multiple windows in the fmap description.
One additional difference in behavior is xlate_region_device does not
perform any action in munmap call. This is because it does not keep
track of the access device that was used to service the mmap
request. Currently, xlate_region_device is used only by memory mapped
boot media on the backend. So, not doing unmap is fine. If this needs
to be changed in the future, xlate_region_device will have to accept a
pre-allocated space from the caller to keep track of all mapping
requests.
BUG=b:171534504
Change-Id: Id5b21ffca2c8d6a9dfc37a878429aed4a8301651
Signed-off-by: Furquan Shaikh <furquan@google.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/47658
Reviewed-by: Duncan Laurie <dlaurie@chromium.org>
Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
2020-11-12 08:23:13 +01:00
|
|
|
offset -= region_offset(&xlwindow->sub_region);
|
2015-10-28 22:09:42 +01:00
|
|
|
|
commonlib/region: Allow multiple windows for xlate_region_dev
This change updates the translated region device (xlate_region_dev) to
support multiple translation windows from the 1st address space to
2nd address space. The address spaces described by the translation
windows can be non-contiguous in both spaces. This is required so that
newer x86 platforms can describe memory mapping of SPI flash into
multiple decode windows in order to support greater than 16MiB of
memory mapped space.
Since the windows can be non-contiguous, it introduces new
restrictions on the region device ops - any operation performed on the
translated region device is limited to only 1 window at a time. This
restriction is primarily because of the mmap operation. The caller
expects that the memory mapped space is contiguous, however, that is
not true anymore. Thus, even though the other operations (readat,
writeat, eraseat) can be updated to translate into multiple operations
one for each access device, all operations across multiple windows are
prohibited for the sake of consistency.
It is the responsibility of the platform to ensure that any section
that is operated on using the translated region device does not span
multiple windows in the fmap description.
One additional difference in behavior is xlate_region_device does not
perform any action in munmap call. This is because it does not keep
track of the access device that was used to service the mmap
request. Currently, xlate_region_device is used only by memory mapped
boot media on the backend. So, not doing unmap is fine. If this needs
to be changed in the future, xlate_region_device will have to accept a
pre-allocated space from the caller to keep track of all mapping
requests.
BUG=b:171534504
Change-Id: Id5b21ffca2c8d6a9dfc37a878429aed4a8301651
Signed-off-by: Furquan Shaikh <furquan@google.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/47658
Reviewed-by: Duncan Laurie <dlaurie@chromium.org>
Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
2020-11-12 08:23:13 +01:00
|
|
|
return rdev_readat(xlwindow->access_dev, b, offset, size);
|
2015-10-28 22:09:42 +01:00
|
|
|
}
|
|
|
|
|
2016-08-04 21:33:58 +02:00
|
|
|
static ssize_t xlate_writeat(const struct region_device *rd, const void *b,
|
2016-06-22 21:09:08 +02:00
|
|
|
size_t offset, size_t size)
|
|
|
|
{
|
|
|
|
struct region req = {
|
|
|
|
.offset = offset,
|
|
|
|
.size = size,
|
|
|
|
};
|
commonlib/region: Allow multiple windows for xlate_region_dev
This change updates the translated region device (xlate_region_dev) to
support multiple translation windows from the 1st address space to
2nd address space. The address spaces described by the translation
windows can be non-contiguous in both spaces. This is required so that
newer x86 platforms can describe memory mapping of SPI flash into
multiple decode windows in order to support greater than 16MiB of
memory mapped space.
Since the windows can be non-contiguous, it introduces new
restrictions on the region device ops - any operation performed on the
translated region device is limited to only 1 window at a time. This
restriction is primarily because of the mmap operation. The caller
expects that the memory mapped space is contiguous, however, that is
not true anymore. Thus, even though the other operations (readat,
writeat, eraseat) can be updated to translate into multiple operations
one for each access device, all operations across multiple windows are
prohibited for the sake of consistency.
It is the responsibility of the platform to ensure that any section
that is operated on using the translated region device does not span
multiple windows in the fmap description.
One additional difference in behavior is xlate_region_device does not
perform any action in munmap call. This is because it does not keep
track of the access device that was used to service the mmap
request. Currently, xlate_region_device is used only by memory mapped
boot media on the backend. So, not doing unmap is fine. If this needs
to be changed in the future, xlate_region_device will have to accept a
pre-allocated space from the caller to keep track of all mapping
requests.
BUG=b:171534504
Change-Id: Id5b21ffca2c8d6a9dfc37a878429aed4a8301651
Signed-off-by: Furquan Shaikh <furquan@google.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/47658
Reviewed-by: Duncan Laurie <dlaurie@chromium.org>
Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
2020-11-12 08:23:13 +01:00
|
|
|
const struct xlate_window *xlwindow;
|
2016-06-22 21:09:08 +02:00
|
|
|
const struct xlate_region_device *xldev;
|
|
|
|
|
|
|
|
xldev = container_of(rd, __typeof__(*xldev), rdev);
|
|
|
|
|
commonlib/region: Allow multiple windows for xlate_region_dev
This change updates the translated region device (xlate_region_dev) to
support multiple translation windows from the 1st address space to
2nd address space. The address spaces described by the translation
windows can be non-contiguous in both spaces. This is required so that
newer x86 platforms can describe memory mapping of SPI flash into
multiple decode windows in order to support greater than 16MiB of
memory mapped space.
Since the windows can be non-contiguous, it introduces new
restrictions on the region device ops - any operation performed on the
translated region device is limited to only 1 window at a time. This
restriction is primarily because of the mmap operation. The caller
expects that the memory mapped space is contiguous, however, that is
not true anymore. Thus, even though the other operations (readat,
writeat, eraseat) can be updated to translate into multiple operations
one for each access device, all operations across multiple windows are
prohibited for the sake of consistency.
It is the responsibility of the platform to ensure that any section
that is operated on using the translated region device does not span
multiple windows in the fmap description.
One additional difference in behavior is xlate_region_device does not
perform any action in munmap call. This is because it does not keep
track of the access device that was used to service the mmap
request. Currently, xlate_region_device is used only by memory mapped
boot media on the backend. So, not doing unmap is fine. If this needs
to be changed in the future, xlate_region_device will have to accept a
pre-allocated space from the caller to keep track of all mapping
requests.
BUG=b:171534504
Change-Id: Id5b21ffca2c8d6a9dfc37a878429aed4a8301651
Signed-off-by: Furquan Shaikh <furquan@google.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/47658
Reviewed-by: Duncan Laurie <dlaurie@chromium.org>
Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
2020-11-12 08:23:13 +01:00
|
|
|
xlwindow = xlate_find_window(xldev, &req);
|
|
|
|
if (!xlwindow)
|
2016-06-22 21:09:08 +02:00
|
|
|
return -1;
|
|
|
|
|
commonlib/region: Allow multiple windows for xlate_region_dev
This change updates the translated region device (xlate_region_dev) to
support multiple translation windows from the 1st address space to
2nd address space. The address spaces described by the translation
windows can be non-contiguous in both spaces. This is required so that
newer x86 platforms can describe memory mapping of SPI flash into
multiple decode windows in order to support greater than 16MiB of
memory mapped space.
Since the windows can be non-contiguous, it introduces new
restrictions on the region device ops - any operation performed on the
translated region device is limited to only 1 window at a time. This
restriction is primarily because of the mmap operation. The caller
expects that the memory mapped space is contiguous, however, that is
not true anymore. Thus, even though the other operations (readat,
writeat, eraseat) can be updated to translate into multiple operations
one for each access device, all operations across multiple windows are
prohibited for the sake of consistency.
It is the responsibility of the platform to ensure that any section
that is operated on using the translated region device does not span
multiple windows in the fmap description.
One additional difference in behavior is xlate_region_device does not
perform any action in munmap call. This is because it does not keep
track of the access device that was used to service the mmap
request. Currently, xlate_region_device is used only by memory mapped
boot media on the backend. So, not doing unmap is fine. If this needs
to be changed in the future, xlate_region_device will have to accept a
pre-allocated space from the caller to keep track of all mapping
requests.
BUG=b:171534504
Change-Id: Id5b21ffca2c8d6a9dfc37a878429aed4a8301651
Signed-off-by: Furquan Shaikh <furquan@google.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/47658
Reviewed-by: Duncan Laurie <dlaurie@chromium.org>
Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
2020-11-12 08:23:13 +01:00
|
|
|
offset -= region_offset(&xlwindow->sub_region);
|
2016-06-22 21:09:08 +02:00
|
|
|
|
commonlib/region: Allow multiple windows for xlate_region_dev
This change updates the translated region device (xlate_region_dev) to
support multiple translation windows from the 1st address space to
2nd address space. The address spaces described by the translation
windows can be non-contiguous in both spaces. This is required so that
newer x86 platforms can describe memory mapping of SPI flash into
multiple decode windows in order to support greater than 16MiB of
memory mapped space.
Since the windows can be non-contiguous, it introduces new
restrictions on the region device ops - any operation performed on the
translated region device is limited to only 1 window at a time. This
restriction is primarily because of the mmap operation. The caller
expects that the memory mapped space is contiguous, however, that is
not true anymore. Thus, even though the other operations (readat,
writeat, eraseat) can be updated to translate into multiple operations
one for each access device, all operations across multiple windows are
prohibited for the sake of consistency.
It is the responsibility of the platform to ensure that any section
that is operated on using the translated region device does not span
multiple windows in the fmap description.
One additional difference in behavior is xlate_region_device does not
perform any action in munmap call. This is because it does not keep
track of the access device that was used to service the mmap
request. Currently, xlate_region_device is used only by memory mapped
boot media on the backend. So, not doing unmap is fine. If this needs
to be changed in the future, xlate_region_device will have to accept a
pre-allocated space from the caller to keep track of all mapping
requests.
BUG=b:171534504
Change-Id: Id5b21ffca2c8d6a9dfc37a878429aed4a8301651
Signed-off-by: Furquan Shaikh <furquan@google.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/47658
Reviewed-by: Duncan Laurie <dlaurie@chromium.org>
Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
2020-11-12 08:23:13 +01:00
|
|
|
return rdev_writeat(xlwindow->access_dev, b, offset, size);
|
2016-06-22 21:09:08 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static ssize_t xlate_eraseat(const struct region_device *rd,
|
|
|
|
size_t offset, size_t size)
|
|
|
|
{
|
|
|
|
struct region req = {
|
|
|
|
.offset = offset,
|
|
|
|
.size = size,
|
|
|
|
};
|
commonlib/region: Allow multiple windows for xlate_region_dev
This change updates the translated region device (xlate_region_dev) to
support multiple translation windows from the 1st address space to
2nd address space. The address spaces described by the translation
windows can be non-contiguous in both spaces. This is required so that
newer x86 platforms can describe memory mapping of SPI flash into
multiple decode windows in order to support greater than 16MiB of
memory mapped space.
Since the windows can be non-contiguous, it introduces new
restrictions on the region device ops - any operation performed on the
translated region device is limited to only 1 window at a time. This
restriction is primarily because of the mmap operation. The caller
expects that the memory mapped space is contiguous, however, that is
not true anymore. Thus, even though the other operations (readat,
writeat, eraseat) can be updated to translate into multiple operations
one for each access device, all operations across multiple windows are
prohibited for the sake of consistency.
It is the responsibility of the platform to ensure that any section
that is operated on using the translated region device does not span
multiple windows in the fmap description.
One additional difference in behavior is xlate_region_device does not
perform any action in munmap call. This is because it does not keep
track of the access device that was used to service the mmap
request. Currently, xlate_region_device is used only by memory mapped
boot media on the backend. So, not doing unmap is fine. If this needs
to be changed in the future, xlate_region_device will have to accept a
pre-allocated space from the caller to keep track of all mapping
requests.
BUG=b:171534504
Change-Id: Id5b21ffca2c8d6a9dfc37a878429aed4a8301651
Signed-off-by: Furquan Shaikh <furquan@google.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/47658
Reviewed-by: Duncan Laurie <dlaurie@chromium.org>
Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
2020-11-12 08:23:13 +01:00
|
|
|
const struct xlate_window *xlwindow;
|
2016-06-22 21:09:08 +02:00
|
|
|
const struct xlate_region_device *xldev;
|
|
|
|
|
|
|
|
xldev = container_of(rd, __typeof__(*xldev), rdev);
|
|
|
|
|
commonlib/region: Allow multiple windows for xlate_region_dev
This change updates the translated region device (xlate_region_dev) to
support multiple translation windows from the 1st address space to
2nd address space. The address spaces described by the translation
windows can be non-contiguous in both spaces. This is required so that
newer x86 platforms can describe memory mapping of SPI flash into
multiple decode windows in order to support greater than 16MiB of
memory mapped space.
Since the windows can be non-contiguous, it introduces new
restrictions on the region device ops - any operation performed on the
translated region device is limited to only 1 window at a time. This
restriction is primarily because of the mmap operation. The caller
expects that the memory mapped space is contiguous, however, that is
not true anymore. Thus, even though the other operations (readat,
writeat, eraseat) can be updated to translate into multiple operations
one for each access device, all operations across multiple windows are
prohibited for the sake of consistency.
It is the responsibility of the platform to ensure that any section
that is operated on using the translated region device does not span
multiple windows in the fmap description.
One additional difference in behavior is xlate_region_device does not
perform any action in munmap call. This is because it does not keep
track of the access device that was used to service the mmap
request. Currently, xlate_region_device is used only by memory mapped
boot media on the backend. So, not doing unmap is fine. If this needs
to be changed in the future, xlate_region_device will have to accept a
pre-allocated space from the caller to keep track of all mapping
requests.
BUG=b:171534504
Change-Id: Id5b21ffca2c8d6a9dfc37a878429aed4a8301651
Signed-off-by: Furquan Shaikh <furquan@google.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/47658
Reviewed-by: Duncan Laurie <dlaurie@chromium.org>
Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
2020-11-12 08:23:13 +01:00
|
|
|
xlwindow = xlate_find_window(xldev, &req);
|
|
|
|
if (!xlwindow)
|
2016-06-22 21:09:08 +02:00
|
|
|
return -1;
|
|
|
|
|
commonlib/region: Allow multiple windows for xlate_region_dev
This change updates the translated region device (xlate_region_dev) to
support multiple translation windows from the 1st address space to
2nd address space. The address spaces described by the translation
windows can be non-contiguous in both spaces. This is required so that
newer x86 platforms can describe memory mapping of SPI flash into
multiple decode windows in order to support greater than 16MiB of
memory mapped space.
Since the windows can be non-contiguous, it introduces new
restrictions on the region device ops - any operation performed on the
translated region device is limited to only 1 window at a time. This
restriction is primarily because of the mmap operation. The caller
expects that the memory mapped space is contiguous, however, that is
not true anymore. Thus, even though the other operations (readat,
writeat, eraseat) can be updated to translate into multiple operations
one for each access device, all operations across multiple windows are
prohibited for the sake of consistency.
It is the responsibility of the platform to ensure that any section
that is operated on using the translated region device does not span
multiple windows in the fmap description.
One additional difference in behavior is xlate_region_device does not
perform any action in munmap call. This is because it does not keep
track of the access device that was used to service the mmap
request. Currently, xlate_region_device is used only by memory mapped
boot media on the backend. So, not doing unmap is fine. If this needs
to be changed in the future, xlate_region_device will have to accept a
pre-allocated space from the caller to keep track of all mapping
requests.
BUG=b:171534504
Change-Id: Id5b21ffca2c8d6a9dfc37a878429aed4a8301651
Signed-off-by: Furquan Shaikh <furquan@google.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/47658
Reviewed-by: Duncan Laurie <dlaurie@chromium.org>
Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
2020-11-12 08:23:13 +01:00
|
|
|
offset -= region_offset(&xlwindow->sub_region);
|
2016-06-22 21:09:08 +02:00
|
|
|
|
commonlib/region: Allow multiple windows for xlate_region_dev
This change updates the translated region device (xlate_region_dev) to
support multiple translation windows from the 1st address space to
2nd address space. The address spaces described by the translation
windows can be non-contiguous in both spaces. This is required so that
newer x86 platforms can describe memory mapping of SPI flash into
multiple decode windows in order to support greater than 16MiB of
memory mapped space.
Since the windows can be non-contiguous, it introduces new
restrictions on the region device ops - any operation performed on the
translated region device is limited to only 1 window at a time. This
restriction is primarily because of the mmap operation. The caller
expects that the memory mapped space is contiguous, however, that is
not true anymore. Thus, even though the other operations (readat,
writeat, eraseat) can be updated to translate into multiple operations
one for each access device, all operations across multiple windows are
prohibited for the sake of consistency.
It is the responsibility of the platform to ensure that any section
that is operated on using the translated region device does not span
multiple windows in the fmap description.
One additional difference in behavior is xlate_region_device does not
perform any action in munmap call. This is because it does not keep
track of the access device that was used to service the mmap
request. Currently, xlate_region_device is used only by memory mapped
boot media on the backend. So, not doing unmap is fine. If this needs
to be changed in the future, xlate_region_device will have to accept a
pre-allocated space from the caller to keep track of all mapping
requests.
BUG=b:171534504
Change-Id: Id5b21ffca2c8d6a9dfc37a878429aed4a8301651
Signed-off-by: Furquan Shaikh <furquan@google.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/47658
Reviewed-by: Duncan Laurie <dlaurie@chromium.org>
Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
2020-11-12 08:23:13 +01:00
|
|
|
return rdev_eraseat(xlwindow->access_dev, offset, size);
|
2016-06-22 21:09:08 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
const struct region_device_ops xlate_rdev_ro_ops = {
|
|
|
|
.mmap = xlate_mmap,
|
|
|
|
.munmap = xlate_munmap,
|
|
|
|
.readat = xlate_readat,
|
|
|
|
};
|
|
|
|
|
|
|
|
const struct region_device_ops xlate_rdev_rw_ops = {
|
2015-10-28 22:09:42 +01:00
|
|
|
.mmap = xlate_mmap,
|
|
|
|
.munmap = xlate_munmap,
|
|
|
|
.readat = xlate_readat,
|
2016-06-22 21:09:08 +02:00
|
|
|
.writeat = xlate_writeat,
|
|
|
|
.eraseat = xlate_eraseat,
|
2015-10-28 22:09:42 +01:00
|
|
|
};
|
2016-12-04 00:08:08 +01:00
|
|
|
|
|
|
|
static void *incoherent_mmap(const struct region_device *rd, size_t offset,
|
|
|
|
size_t size)
|
|
|
|
{
|
|
|
|
const struct incoherent_rdev *irdev;
|
|
|
|
|
|
|
|
irdev = container_of(rd, const struct incoherent_rdev, rdev);
|
|
|
|
|
|
|
|
return rdev_mmap(irdev->read, offset, size);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int incoherent_munmap(const struct region_device *rd, void *mapping)
|
|
|
|
{
|
|
|
|
const struct incoherent_rdev *irdev;
|
|
|
|
|
|
|
|
irdev = container_of(rd, const struct incoherent_rdev, rdev);
|
|
|
|
|
|
|
|
return rdev_munmap(irdev->read, mapping);
|
|
|
|
}
|
|
|
|
|
|
|
|
static ssize_t incoherent_readat(const struct region_device *rd, void *b,
|
|
|
|
size_t offset, size_t size)
|
|
|
|
{
|
|
|
|
const struct incoherent_rdev *irdev;
|
|
|
|
|
|
|
|
irdev = container_of(rd, const struct incoherent_rdev, rdev);
|
|
|
|
|
|
|
|
return rdev_readat(irdev->read, b, offset, size);
|
|
|
|
}
|
|
|
|
|
|
|
|
static ssize_t incoherent_writeat(const struct region_device *rd, const void *b,
|
|
|
|
size_t offset, size_t size)
|
|
|
|
{
|
|
|
|
const struct incoherent_rdev *irdev;
|
|
|
|
|
|
|
|
irdev = container_of(rd, const struct incoherent_rdev, rdev);
|
|
|
|
|
|
|
|
return rdev_writeat(irdev->write, b, offset, size);
|
|
|
|
}
|
|
|
|
|
|
|
|
static ssize_t incoherent_eraseat(const struct region_device *rd, size_t offset,
|
|
|
|
size_t size)
|
|
|
|
{
|
|
|
|
const struct incoherent_rdev *irdev;
|
|
|
|
|
|
|
|
irdev = container_of(rd, const struct incoherent_rdev, rdev);
|
|
|
|
|
|
|
|
return rdev_eraseat(irdev->write, offset, size);
|
|
|
|
}
|
|
|
|
|
|
|
|
static const struct region_device_ops incoherent_rdev_ops = {
|
|
|
|
.mmap = incoherent_mmap,
|
|
|
|
.munmap = incoherent_munmap,
|
|
|
|
.readat = incoherent_readat,
|
|
|
|
.writeat = incoherent_writeat,
|
|
|
|
.eraseat = incoherent_eraseat,
|
|
|
|
};
|
|
|
|
|
|
|
|
const struct region_device *incoherent_rdev_init(struct incoherent_rdev *irdev,
|
|
|
|
const struct region *r,
|
|
|
|
const struct region_device *read,
|
|
|
|
const struct region_device *write)
|
|
|
|
{
|
|
|
|
const size_t size = region_sz(r);
|
|
|
|
|
|
|
|
if (size != region_device_sz(read) || size != region_device_sz(write))
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
/* The region is represented as offset 0 to size. That way, the generic
|
|
|
|
* rdev operations can be called on the read or write implementation
|
|
|
|
* without any unnecessary translation because the offsets all start
|
|
|
|
* at 0. */
|
|
|
|
region_device_init(&irdev->rdev, &incoherent_rdev_ops, 0, size);
|
|
|
|
irdev->read = read;
|
|
|
|
irdev->write = write;
|
|
|
|
|
|
|
|
return &irdev->rdev;
|
|
|
|
}
|