| Message ID | 20250708074940.10904-3-nick.hu@sifive.com |
|---|---|
| State | Changes Requested |
| Headers | show |
| Series | Add SiFive TMC0 and SMC0 driver | expand |
On Tue, Jul 8, 2025 at 1:19 PM Nick Hu <nick.hu@sifive.com> wrote: > > Add the FDT cache library so we can build up the cache topology via the > 'next-level-cache' DT property. > > Co-developed-by: Vincent Chen <vincent.chen@sifive.com> > Signed-off-by: Vincent Chen <vincent.chen@sifive.com> > Co-developed-by: Andy Chiu <andy.chiu@sifive.com> > Signed-off-by: Andy Chiu <andy.chiu@sifive.com> > Signed-off-by: Nick Hu <nick.hu@sifive.com> > Reviewed-by: Samuel Holland <samuel.holland@sifive.com> LGTM. Reviewed-by: Anup Patel <anup@brainfault.org> Regards, Anup > --- > include/sbi_utils/cache/fdt_cache.h | 34 +++++++++ > lib/utils/cache/Kconfig | 6 ++ > lib/utils/cache/fdt_cache.c | 87 ++++++++++++++++++++++++ > lib/utils/cache/fdt_cache_drivers.carray | 3 + > lib/utils/cache/objects.mk | 3 + > platform/generic/configs/defconfig | 1 + > 6 files changed, 134 insertions(+) > create mode 100644 include/sbi_utils/cache/fdt_cache.h > create mode 100644 lib/utils/cache/fdt_cache.c > create mode 100644 lib/utils/cache/fdt_cache_drivers.carray > > diff --git a/include/sbi_utils/cache/fdt_cache.h b/include/sbi_utils/cache/fdt_cache.h > new file mode 100644 > index 00000000..b377d6f5 > --- /dev/null > +++ b/include/sbi_utils/cache/fdt_cache.h > @@ -0,0 +1,34 @@ > +/* > + * SPDX-License-Identifier: BSD-2-Clause > + * > + * Copyright (c) 2025 SiFive Inc. > + */ > + > +#ifndef __FDT_CACHE_H__ > +#define __FDT_CACHE_H__ > + > +#include <sbi_utils/cache/cache.h> > + > +/** > + * Register a cache device using information from the DT > + * > + * @param fdt devicetree blob > + * @param noff offset of a node in the devicetree blob > + * @param dev cache device to register for this devicetree node > + * > + * @return 0 on success, or a negative error code on failure > + */ > +int fdt_cache_add(const void *fdt, int noff, struct cache_device *dev); > + > +/** > + * Get the cache device referencd by the "next-level-cache" property of a DT node > + * > + * @param fdt devicetree blob > + * @param noff offset of a node in the devicetree blob > + * @param out_dev location to return the cache device > + * > + * @return 0 on success, or a negative error code on failure > + */ > +int fdt_next_cache_get(const void *fdt, int noff, struct cache_device **out_dev); > + > +#endif > diff --git a/lib/utils/cache/Kconfig b/lib/utils/cache/Kconfig > index 24aa41bc..10602176 100644 > --- a/lib/utils/cache/Kconfig > +++ b/lib/utils/cache/Kconfig > @@ -2,6 +2,12 @@ > > menu "Cache Support" > > +config FDT_CACHE > + bool "FDT based cache drivers" > + depends on FDT > + select CACHE > + default n > + > config CACHE > bool "Cache support" > default n > diff --git a/lib/utils/cache/fdt_cache.c b/lib/utils/cache/fdt_cache.c > new file mode 100644 > index 00000000..e1c6f67c > --- /dev/null > +++ b/lib/utils/cache/fdt_cache.c > @@ -0,0 +1,87 @@ > +/* > + * SPDX-License-Identifier: BSD-2-Clause > + * > + * Copyright (c) 2025 SiFive Inc. > + */ > + > +#include <libfdt.h> > +#include <sbi/sbi_console.h> > +#include <sbi/sbi_error.h> > +#include <sbi/sbi_heap.h> > +#include <sbi_utils/cache/fdt_cache.h> > +#include <sbi_utils/fdt/fdt_driver.h> > + > +/* List of FDT cache drivers generated at compile time */ > +extern const struct fdt_driver *const fdt_cache_drivers[]; > + > +int fdt_cache_add(const void *fdt, int noff, struct cache_device *dev) > +{ > + int rc; > + > + dev->id = noff; > + sbi_strncpy(dev->name, fdt_get_name(fdt, noff, NULL), sizeof(dev->name) - 1); > + sbi_dprintf("%s: %s\n", __func__, dev->name); > + > + rc = fdt_next_cache_get(fdt, noff, &dev->next); > + if (rc) > + return rc; > + > + return cache_add(dev); > +} > + > +static int fdt_cache_add_generic(const void *fdt, int noff) > +{ > + struct cache_device *dev; > + int rc; > + > + dev = sbi_zalloc(sizeof(*dev)); > + if (!dev) > + return SBI_ENOMEM; > + > + rc = fdt_cache_add(fdt, noff, dev); > + if (rc) { > + sbi_free(dev); > + return rc; > + } > + > + return 0; > +} > + > +static int fdt_cache_find(const void *fdt, int noff, struct cache_device **out_dev) > +{ > + struct cache_device *dev = cache_find(noff); > + int rc; > + > + if (!dev) { > + rc = fdt_driver_init_by_offset(fdt, noff, fdt_cache_drivers); > + if (rc == SBI_ENODEV) > + rc = fdt_cache_add_generic(fdt, noff); > + if (rc) > + return rc; > + > + dev = cache_find(noff); > + if (!dev) > + return SBI_EFAIL; > + } > + > + if (out_dev) > + *out_dev = dev; > + > + return SBI_OK; > +} > + > +int fdt_next_cache_get(const void *fdt, int noff, struct cache_device **out_dev) > +{ > + const fdt32_t *val; > + int len; > + > + val = fdt_getprop(fdt, noff, "next-level-cache", &len); > + if (!val || len < sizeof(*val)) > + return SBI_OK; > + > + noff = fdt_node_offset_by_phandle(fdt, fdt32_to_cpu(val[0])); > + if (noff < 0) > + return noff; > + > + return fdt_cache_find(fdt, noff, out_dev); > +} > diff --git a/lib/utils/cache/fdt_cache_drivers.carray b/lib/utils/cache/fdt_cache_drivers.carray > new file mode 100644 > index 00000000..c1b1791c > --- /dev/null > +++ b/lib/utils/cache/fdt_cache_drivers.carray > @@ -0,0 +1,3 @@ > +HEADER: sbi_utils/cache/fdt_cache.h > +TYPE: const struct fdt_driver > +NAME: fdt_cache_drivers > diff --git a/lib/utils/cache/objects.mk b/lib/utils/cache/objects.mk > index 21d30ce8..2fcf9666 100644 > --- a/lib/utils/cache/objects.mk > +++ b/lib/utils/cache/objects.mk > @@ -4,4 +4,7 @@ > # Copyright (c) 2025 SiFive > # > > +libsbiutils-objs-$(CONFIG_FDT_CACHE) += cache/fdt_cache.o > +libsbiutils-objs-$(CONFIG_FDT_CACHE) += cache/fdt_cache_drivers.carray.o > + > libsbiutils-objs-$(CONFIG_CACHE) += cache/cache.o > diff --git a/platform/generic/configs/defconfig b/platform/generic/configs/defconfig > index c7a6531e..b5a7993d 100644 > --- a/platform/generic/configs/defconfig > +++ b/platform/generic/configs/defconfig > @@ -7,6 +7,7 @@ CONFIG_PLATFORM_SOPHGO_SG2042=y > CONFIG_PLATFORM_STARFIVE_JH7110=y > CONFIG_PLATFORM_THEAD=y > CONFIG_PLATFORM_MIPS_P8700=y > +CONFIG_FDT_CACHE=y > CONFIG_FDT_CPPC=y > CONFIG_FDT_CPPC_RPMI=y > CONFIG_FDT_GPIO=y > -- > 2.17.1 >
diff --git a/include/sbi_utils/cache/fdt_cache.h b/include/sbi_utils/cache/fdt_cache.h new file mode 100644 index 00000000..b377d6f5 --- /dev/null +++ b/include/sbi_utils/cache/fdt_cache.h @@ -0,0 +1,34 @@ +/* + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2025 SiFive Inc. + */ + +#ifndef __FDT_CACHE_H__ +#define __FDT_CACHE_H__ + +#include <sbi_utils/cache/cache.h> + +/** + * Register a cache device using information from the DT + * + * @param fdt devicetree blob + * @param noff offset of a node in the devicetree blob + * @param dev cache device to register for this devicetree node + * + * @return 0 on success, or a negative error code on failure + */ +int fdt_cache_add(const void *fdt, int noff, struct cache_device *dev); + +/** + * Get the cache device referencd by the "next-level-cache" property of a DT node + * + * @param fdt devicetree blob + * @param noff offset of a node in the devicetree blob + * @param out_dev location to return the cache device + * + * @return 0 on success, or a negative error code on failure + */ +int fdt_next_cache_get(const void *fdt, int noff, struct cache_device **out_dev); + +#endif diff --git a/lib/utils/cache/Kconfig b/lib/utils/cache/Kconfig index 24aa41bc..10602176 100644 --- a/lib/utils/cache/Kconfig +++ b/lib/utils/cache/Kconfig @@ -2,6 +2,12 @@ menu "Cache Support" +config FDT_CACHE + bool "FDT based cache drivers" + depends on FDT + select CACHE + default n + config CACHE bool "Cache support" default n diff --git a/lib/utils/cache/fdt_cache.c b/lib/utils/cache/fdt_cache.c new file mode 100644 index 00000000..e1c6f67c --- /dev/null +++ b/lib/utils/cache/fdt_cache.c @@ -0,0 +1,87 @@ +/* + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2025 SiFive Inc. + */ + +#include <libfdt.h> +#include <sbi/sbi_console.h> +#include <sbi/sbi_error.h> +#include <sbi/sbi_heap.h> +#include <sbi_utils/cache/fdt_cache.h> +#include <sbi_utils/fdt/fdt_driver.h> + +/* List of FDT cache drivers generated at compile time */ +extern const struct fdt_driver *const fdt_cache_drivers[]; + +int fdt_cache_add(const void *fdt, int noff, struct cache_device *dev) +{ + int rc; + + dev->id = noff; + sbi_strncpy(dev->name, fdt_get_name(fdt, noff, NULL), sizeof(dev->name) - 1); + sbi_dprintf("%s: %s\n", __func__, dev->name); + + rc = fdt_next_cache_get(fdt, noff, &dev->next); + if (rc) + return rc; + + return cache_add(dev); +} + +static int fdt_cache_add_generic(const void *fdt, int noff) +{ + struct cache_device *dev; + int rc; + + dev = sbi_zalloc(sizeof(*dev)); + if (!dev) + return SBI_ENOMEM; + + rc = fdt_cache_add(fdt, noff, dev); + if (rc) { + sbi_free(dev); + return rc; + } + + return 0; +} + +static int fdt_cache_find(const void *fdt, int noff, struct cache_device **out_dev) +{ + struct cache_device *dev = cache_find(noff); + int rc; + + if (!dev) { + rc = fdt_driver_init_by_offset(fdt, noff, fdt_cache_drivers); + if (rc == SBI_ENODEV) + rc = fdt_cache_add_generic(fdt, noff); + if (rc) + return rc; + + dev = cache_find(noff); + if (!dev) + return SBI_EFAIL; + } + + if (out_dev) + *out_dev = dev; + + return SBI_OK; +} + +int fdt_next_cache_get(const void *fdt, int noff, struct cache_device **out_dev) +{ + const fdt32_t *val; + int len; + + val = fdt_getprop(fdt, noff, "next-level-cache", &len); + if (!val || len < sizeof(*val)) + return SBI_OK; + + noff = fdt_node_offset_by_phandle(fdt, fdt32_to_cpu(val[0])); + if (noff < 0) + return noff; + + return fdt_cache_find(fdt, noff, out_dev); +} diff --git a/lib/utils/cache/fdt_cache_drivers.carray b/lib/utils/cache/fdt_cache_drivers.carray new file mode 100644 index 00000000..c1b1791c --- /dev/null +++ b/lib/utils/cache/fdt_cache_drivers.carray @@ -0,0 +1,3 @@ +HEADER: sbi_utils/cache/fdt_cache.h +TYPE: const struct fdt_driver +NAME: fdt_cache_drivers diff --git a/lib/utils/cache/objects.mk b/lib/utils/cache/objects.mk index 21d30ce8..2fcf9666 100644 --- a/lib/utils/cache/objects.mk +++ b/lib/utils/cache/objects.mk @@ -4,4 +4,7 @@ # Copyright (c) 2025 SiFive # +libsbiutils-objs-$(CONFIG_FDT_CACHE) += cache/fdt_cache.o +libsbiutils-objs-$(CONFIG_FDT_CACHE) += cache/fdt_cache_drivers.carray.o + libsbiutils-objs-$(CONFIG_CACHE) += cache/cache.o diff --git a/platform/generic/configs/defconfig b/platform/generic/configs/defconfig index c7a6531e..b5a7993d 100644 --- a/platform/generic/configs/defconfig +++ b/platform/generic/configs/defconfig @@ -7,6 +7,7 @@ CONFIG_PLATFORM_SOPHGO_SG2042=y CONFIG_PLATFORM_STARFIVE_JH7110=y CONFIG_PLATFORM_THEAD=y CONFIG_PLATFORM_MIPS_P8700=y +CONFIG_FDT_CACHE=y CONFIG_FDT_CPPC=y CONFIG_FDT_CPPC_RPMI=y CONFIG_FDT_GPIO=y