[PATCH v3 01/12] lib: utils: Add cache flush library
Anup Patel
anup at brainfault.org
Mon Aug 4 01:36:14 PDT 2025
On Tue, Jul 8, 2025 at 1:19 PM Nick Hu <nick.hu at sifive.com> wrote:
>
> The current RISC-V CMO only defines how to flush a cache block. However,
> certain use cases, such as power management, may require flushing the
> entire cache. Therefore, a framework is being introduced to allow vendors
> to flush the entire cache using their own methods.
>
> Signed-off-by: Nick Hu <nick.hu at sifive.com>
> Reviewed-by: Samuel Holland <samuel.holland at sifive.com>
LGTM.
Reviewed-by: Anup Patel <anup at brainfault.org>
Regards,
Anup
> ---
> include/sbi_utils/cache/cache.h | 69 +++++++++++++++++++++++++++++++++
> lib/utils/Kconfig | 2 +
> lib/utils/cache/Kconfig | 9 +++++
> lib/utils/cache/cache.c | 46 ++++++++++++++++++++++
> lib/utils/cache/objects.mk | 7 ++++
> 5 files changed, 133 insertions(+)
> create mode 100644 include/sbi_utils/cache/cache.h
> create mode 100644 lib/utils/cache/Kconfig
> create mode 100644 lib/utils/cache/cache.c
> create mode 100644 lib/utils/cache/objects.mk
>
> diff --git a/include/sbi_utils/cache/cache.h b/include/sbi_utils/cache/cache.h
> new file mode 100644
> index 00000000..70d9286f
> --- /dev/null
> +++ b/include/sbi_utils/cache/cache.h
> @@ -0,0 +1,69 @@
> +/*
> + * SPDX-License-Identifier: BSD-2-Clause
> + *
> + * Copyright (c) 2025 SiFive Inc.
> + */
> +
> +#ifndef __CACHE_H__
> +#define __CACHE_H__
> +
> +#include <sbi/sbi_list.h>
> +#include <sbi/sbi_types.h>
> +
> +#define CACHE_NAME_LEN 32
> +
> +struct cache_device;
> +
> +struct cache_ops {
> + /** Warm init **/
> + int (*warm_init)(struct cache_device *dev);
> + /** Flush entire cache **/
> + int (*cache_flush_all)(struct cache_device *dev);
> +};
> +
> +struct cache_device {
> + /** Name of the device **/
> + char name[CACHE_NAME_LEN];
> + /** List node for search **/
> + struct sbi_dlist node;
> + /** Point to the next level cache **/
> + struct cache_device *next;
> + /** Cache Management Operations **/
> + struct cache_ops *ops;
> + /** CPU private cache **/
> + bool cpu_private;
> + /** The unique id of this cache device **/
> + u32 id;
> +};
> +
> +/**
> + * Find a registered cache device
> + *
> + * @param id unique ID of the cache device
> + *
> + * @return the cache device or NULL
> + */
> +struct cache_device *cache_find(u32 id);
> +
> +/**
> + * Register a cache device
> + *
> + * cache_device->id must be initialized already and must not change during the life
> + * of the cache_device object.
> + *
> + * @param dev the cache device to register
> + *
> + * @return 0 on success, or a negative error code on failure
> + */
> +int cache_add(struct cache_device *dev);
> +
> +/**
> + * Flush the entire cache
> + *
> + * @param dev the cache to flush
> + *
> + * @return 0 on success, or a negative error code on failure
> + */
> +int cache_flush_all(struct cache_device *dev);
> +
> +#endif
> diff --git a/lib/utils/Kconfig b/lib/utils/Kconfig
> index 901ba564..5a5b3b1e 100644
> --- a/lib/utils/Kconfig
> +++ b/lib/utils/Kconfig
> @@ -2,6 +2,8 @@
>
> menu "Utils and Drivers Support"
>
> +source "$(OPENSBI_SRC_DIR)/lib/utils/cache/Kconfig"
> +
> source "$(OPENSBI_SRC_DIR)/lib/utils/cppc/Kconfig"
>
> source "$(OPENSBI_SRC_DIR)/lib/utils/fdt/Kconfig"
> diff --git a/lib/utils/cache/Kconfig b/lib/utils/cache/Kconfig
> new file mode 100644
> index 00000000..24aa41bc
> --- /dev/null
> +++ b/lib/utils/cache/Kconfig
> @@ -0,0 +1,9 @@
> +# SPDX-License-Identifier: BSD-2-Clause
> +
> +menu "Cache Support"
> +
> +config CACHE
> + bool "Cache support"
> + default n
> +
> +endmenu
> diff --git a/lib/utils/cache/cache.c b/lib/utils/cache/cache.c
> new file mode 100644
> index 00000000..6bc3d10e
> --- /dev/null
> +++ b/lib/utils/cache/cache.c
> @@ -0,0 +1,46 @@
> +/*
> + * SPDX-License-Identifier: BSD-2-Clause
> + *
> + * Copyright (c) 2025 SiFive Inc.
> + */
> +
> +#include <sbi/sbi_error.h>
> +#include <sbi_utils/cache/cache.h>
> +
> +static SBI_LIST_HEAD(cache_list);
> +
> +struct cache_device *cache_find(u32 id)
> +{
> + struct cache_device *dev;
> +
> + sbi_list_for_each_entry(dev, &cache_list, node) {
> + if (dev->id == id)
> + return dev;
> + }
> +
> + return NULL;
> +}
> +
> +int cache_add(struct cache_device *dev)
> +{
> + if (!dev)
> + return SBI_ENODEV;
> +
> + if (cache_find(dev->id))
> + return SBI_EALREADY;
> +
> + sbi_list_add(&dev->node, &cache_list);
> +
> + return SBI_OK;
> +}
> +
> +int cache_flush_all(struct cache_device *dev)
> +{
> + if (!dev)
> + return SBI_ENODEV;
> +
> + if (!dev->ops || !dev->ops->cache_flush_all)
> + return SBI_ENOTSUPP;
> +
> + return dev->ops->cache_flush_all(dev);
> +}
> diff --git a/lib/utils/cache/objects.mk b/lib/utils/cache/objects.mk
> new file mode 100644
> index 00000000..21d30ce8
> --- /dev/null
> +++ b/lib/utils/cache/objects.mk
> @@ -0,0 +1,7 @@
> +#
> +# SPDX-License-Identifier: BSD-2-Clause
> +#
> +# Copyright (c) 2025 SiFive
> +#
> +
> +libsbiutils-objs-$(CONFIG_CACHE) += cache/cache.o
> --
> 2.17.1
>
More information about the opensbi
mailing list