1 /* Copyright 2018 SiFive, Inc */
2 /* SPDX-License-Identifier: Apache-2.0 */
4 #include <metal/machine/platform.h>
5 #include <metal/drivers/sifive_fu540-c000_l2.h>
7 #define L2_CONFIG_WAYS_SHIFT 8
8 #define L2_CONFIG_WAYS_MASK (0xFF << L2_CONFIG_WAYS_SHIFT)
10 #ifdef CONFIG_SIFIVE_FU540_C000_L2
12 static void metal_driver_sifive_fu540_c000_l2_init(void) __attribute__((constructor));
13 static void metal_driver_sifive_fu540_c000_l2_init(void)
15 #ifdef __METAL_DT_SIFIVE_FU540_C000_L2_HANDLE
16 /* Get the handle for the L2 cache controller */
17 struct __metal_driver_sifive_fu540_c000_l2 *l2 = __METAL_DT_SIFIVE_FU540_C000_L2_HANDLE;
22 /* Get the number of available ways per bank */
23 uint32_t ways = __METAL_ACCESS_ONCE((__metal_io_u32 *)(l2->control_base + SIFIVE_FU540_C000_L2_CONFIG));
24 ways = ((ways & L2_CONFIG_WAYS_MASK) >> L2_CONFIG_WAYS_SHIFT);
26 /* Enable all the ways */
27 __metal_driver_sifive_fu540_c000_l2_init(l2, ways);
31 void __metal_driver_sifive_fu540_c000_l2_init(struct metal_cache *l2, int ways)
33 metal_cache_set_enabled_ways(l2, ways);
36 int __metal_driver_sifive_fu540_c000_l2_get_enabled_ways(struct metal_cache *cache)
38 struct __metal_driver_sifive_fu540_c000_l2 *l2 = (struct __metal_driver_sifive_fu540_c000_l2 *) cache;
43 uint32_t way_enable = __METAL_ACCESS_ONCE((__metal_io_u32 *)(l2->control_base + SIFIVE_FU540_C000_L2_WAYENABLE));
45 /* The stored number is the index, so add one */
46 return (0xFF & way_enable) + 1;
49 int __metal_driver_sifive_fu540_c000_l2_set_enabled_ways(struct metal_cache *cache, int ways)
51 struct __metal_driver_sifive_fu540_c000_l2 *l2 = (struct __metal_driver_sifive_fu540_c000_l2 *) cache;
56 /* We can't decrease the number of enabled ways */
57 if(metal_cache_get_enabled_ways(cache) > ways) {
61 /* The stored value is the index, so subtract one */
62 uint32_t value = 0xFF & (ways - 1);
64 /* Set the number of enabled ways */
65 __METAL_ACCESS_ONCE((__metal_io_u32 *)(l2->control_base + SIFIVE_FU540_C000_L2_WAYENABLE)) = value;
67 /* Make sure the number of ways was set correctly */
68 if(metal_cache_get_enabled_ways(cache) != ways) {
75 __METAL_DEFINE_VTABLE(__metal_driver_vtable_sifive_fu540_c000_l2) = {
76 .cache.init = __metal_driver_sifive_fu540_c000_l2_init,
77 .cache.get_enabled_ways = __metal_driver_sifive_fu540_c000_l2_get_enabled_ways,
78 .cache.set_enabled_ways = __metal_driver_sifive_fu540_c000_l2_set_enabled_ways,