diff --git a/include/sbi_utils/cache/cache.h b/include/sbi_utils/cache/cache.h index 70d9286f..de6cf50d 100644 --- a/include/sbi_utils/cache/cache.h +++ b/include/sbi_utils/cache/cache.h @@ -19,6 +19,8 @@ struct cache_ops { int (*warm_init)(struct cache_device *dev); /** Flush entire cache **/ int (*cache_flush_all)(struct cache_device *dev); + /** Enable/Disable cache **/ + int (*cache_enable)(struct cache_device *dev, bool enable); }; struct cache_device { @@ -66,4 +68,13 @@ int cache_add(struct cache_device *dev); */ int cache_flush_all(struct cache_device *dev); +/** + * Enable/Disable the cache + * + * @param dev the cache to enable/disable + * + * @return 0 on success, or a negative error code on failure + */ +int cache_enable(struct cache_device *dev, bool enable); + #endif diff --git a/include/sbi_utils/cache/fdt_cmo_helper.h b/include/sbi_utils/cache/fdt_cmo_helper.h index a6a28db9..8b3ec89b 100644 --- a/include/sbi_utils/cache/fdt_cmo_helper.h +++ b/include/sbi_utils/cache/fdt_cmo_helper.h @@ -22,6 +22,19 @@ int fdt_cmo_private_flc_flush_all(void); */ int fdt_cmo_llc_flush_all(void); +/** + * Enable/Disable the private first level cache of the current hart + * + * @return 0 on success, or a negative error code on failure + */ +int fdt_cmo_private_flc_enable(bool enable); + +/** + * Enable/Disable the last level cache of the current hart + * + * @return 0 on success, or a negative error code on failure + */ +int fdt_cmo_llc_enable(bool enable); /** * Initialize the cache devices for each hart * diff --git a/lib/utils/cache/cache.c b/lib/utils/cache/cache.c index 6bc3d10e..2810d5e9 100644 --- a/lib/utils/cache/cache.c +++ b/lib/utils/cache/cache.c @@ -44,3 +44,14 @@ int cache_flush_all(struct cache_device *dev) return dev->ops->cache_flush_all(dev); } + +int cache_enable(struct cache_device *dev, bool enable) +{ + if (!dev) + return SBI_ENODEV; + + if (!dev->ops || !dev->ops->cache_enable) + return SBI_ENOTSUPP; + + return dev->ops->cache_enable(dev, enable); +} diff --git a/lib/utils/cache/fdt_cmo_helper.c b/lib/utils/cache/fdt_cmo_helper.c index d87bab76..3ab8abe6 100644 --- a/lib/utils/cache/fdt_cmo_helper.c +++ b/lib/utils/cache/fdt_cmo_helper.c @@ -41,6 +41,29 @@ int fdt_cmo_llc_flush_all(void) return cache_flush_all(llc); } +int fdt_cmo_private_flc_enable(bool enable) +{ + struct cache_device *flc = get_hart_flc(sbi_scratch_thishart_ptr()); + + if (!flc || !flc->cpu_private) + return SBI_ENODEV; + + return cache_enable(flc, enable); +} + +int fdt_cmo_llc_enable(bool enable) +{ + struct cache_device *llc = get_hart_flc(sbi_scratch_thishart_ptr()); + + if (!llc) + return SBI_ENODEV; + + while (llc->next) + llc = llc->next; + + return cache_enable(llc, enable); +} + static int fdt_cmo_cold_init(const void *fdt) { struct sbi_scratch *scratch;