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 <nick.hu@sifive.com>
Reviewed-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Link: https://lore.kernel.org/r/20251020-cache-upstream-v7-1-69a132447d8a@sifive.com
Signed-off-by: Anup Patel <anup@brainfault.org>
This commit is contained in:
Nick Hu 2025-10-20 14:34:03 +08:00 committed by Anup Patel
parent ac16c6b604
commit 1207c7568f
5 changed files with 133 additions and 0 deletions

69
include/sbi_utils/cache/cache.h vendored Normal file
View File

@ -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

View File

@ -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"

9
lib/utils/cache/Kconfig vendored Normal file
View File

@ -0,0 +1,9 @@
# SPDX-License-Identifier: BSD-2-Clause
menu "Cache Support"
config CACHE
bool "Cache support"
default n
endmenu

46
lib/utils/cache/cache.c vendored Normal file
View File

@ -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);
}

7
lib/utils/cache/objects.mk vendored Normal file
View File

@ -0,0 +1,7 @@
#
# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2025 SiFive
#
libsbiutils-objs-$(CONFIG_CACHE) += cache/cache.o