From 1207c7568fbe07714e3b75f9ebf25d7ed21612fe Mon Sep 17 00:00:00 2001 From: Nick Hu Date: Mon, 20 Oct 2025 14:34:03 +0800 Subject: [PATCH] lib: utils: Add cache flush library 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 Reviewed-by: Samuel Holland Reviewed-by: Anup Patel Link: https://lore.kernel.org/r/20251020-cache-upstream-v7-1-69a132447d8a@sifive.com Signed-off-by: Anup Patel --- 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 +#include + +#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 +#include + +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