1 INTERFACE [arm && outer_cache_l2cxx0]:
3 #include "lock_guard.h"
4 #include "mem_layout.h"
6 #include "mmio_register_block.h"
8 EXTENSION class Outer_cache
12 class L2cxx0 : public Mmio_register_block
21 TAG_RAM_CONTROL = 0x108,
22 DATA_RAM_CONTROL = 0x10c,
23 EVENT_COUNTER_CONTROL = 0x200,
24 EVENT_COUTNER1_CONFIG = 0x204,
25 EVENT_COUNTER0_CONFIG = 0x208,
26 EVENT_COUNTER1_VALUE = 0x20c,
27 EVENT_COUNTER0_VALUE = 0x210,
28 INTERRUPT_MASK = 0x214,
29 MASKED_INTERRUPT_STATUS = 0x218,
30 RAW_INTERRUPT_STATUS = 0x21c,
31 INTERRUPT_CLEAR = 0x220,
33 INVALIDATE_LINE_BY_PA = 0x770,
34 INVALIDATE_BY_WAY = 0x77c,
35 CLEAN_LINE_BY_PA = 0x7b0,
36 CLEAN_LINE_BY_INDEXWAY = 0x7bb,
38 CLEAN_AND_INV_LINE_BY_PA = 0x7f0,
39 CLEAN_AND_INV_LINE_BY_INDEXWAY = 0x7f8,
40 CLEAN_AND_INV_BY_WAY = 0x7fc,
41 LOCKDOWN_BY_WAY_D_SIDE = 0x900,
42 LOCKDOWN_BY_WAY_I_SIDE = 0x904,
43 TEST_OPERATION = 0xf00,
45 DEBUG_CONTROL_REGISTER = 0xf40,
50 Pwr_ctrl_standby_mode_en = 1 << 0,
51 Pwr_ctrl_dynamic_clk_gating_en = 1 << 1,
56 explicit L2cxx0(Address virt) : Mmio_register_block(virt) {}
58 void write_op(Address reg, Mword val)
60 Mmio_register_block::write<Mword>(val, reg);
61 while (read<Mword>(reg) & 1)
65 void write_way_op(Address reg, Mword val)
67 Mmio_register_block::write<Mword>(val, reg);
68 while (read<Mword>(reg) & val)
73 static Mword platform_init(Mword aux);
75 static Static_object<L2cxx0> l2cxx0;
76 static bool need_sync;
77 static unsigned waymask;
83 Cache_line_size = 1 << Cache_line_shift,
84 Cache_line_mask = Cache_line_size - 1,
88 // ------------------------------------------------------------------------
89 IMPLEMENTATION [arm && outer_cache_l2cxx0]:
92 #include "processor.h"
93 #include "static_init.h"
95 Static_object<Outer_cache::L2cxx0> Outer_cache::l2cxx0;
97 bool Outer_cache::need_sync;
98 unsigned Outer_cache::waymask;
104 while (l2cxx0->read<Mword>(L2cxx0::CACHE_SYNC))
105 Proc::preemption_point();
112 auto guard = lock_guard(l2cxx0->_lock);
113 l2cxx0->write_way_op(L2cxx0::CLEAN_BY_WAY, waymask);
119 Outer_cache::clean(Mword phys_addr, bool do_sync = true)
121 auto guard = lock_guard(l2cxx0->_lock);
122 l2cxx0->write_op(L2cxx0::CLEAN_LINE_BY_PA, phys_addr & (~0UL << Cache_line_shift));
123 if (need_sync && do_sync)
131 auto guard = lock_guard(l2cxx0->_lock);
132 l2cxx0->write_way_op(L2cxx0::CLEAN_AND_INV_BY_WAY, waymask);
138 Outer_cache::flush(Mword phys_addr, bool do_sync = true)
140 auto guard = lock_guard(l2cxx0->_lock);
141 l2cxx0->write_op(L2cxx0::CLEAN_AND_INV_LINE_BY_PA, phys_addr & (~0UL << Cache_line_shift));
142 if (need_sync && do_sync)
148 Outer_cache::invalidate()
150 auto guard = lock_guard(l2cxx0->_lock);
151 l2cxx0->write_way_op(L2cxx0::INVALIDATE_BY_WAY, waymask);
157 Outer_cache::invalidate(Address phys_addr, bool do_sync = true)
159 auto guard = lock_guard(l2cxx0->_lock);
160 l2cxx0->write_op(L2cxx0::INVALIDATE_LINE_BY_PA, phys_addr & (~0UL << Cache_line_shift));
161 if (need_sync && do_sync)
167 Outer_cache::initialize(bool v)
169 l2cxx0.construct(Kmem::mmio_remap(Mem_layout::L2cxx0_phys_base));
170 Mword cache_id = l2cxx0->read<Mword>(L2cxx0::CACHE_ID);
171 Mword aux = l2cxx0->read<Mword>(L2cxx0::AUX_CONTROL);
176 aux = platform_init(aux);
178 switch ((cache_id >> 6) & 0xf)
181 ways = (aux >> 13) & 0xf;
185 ways = aux & (1 << 16) ? 16 : 8;
191 waymask = (1 << ways) - 1;
193 l2cxx0->write<Mword>(0, L2cxx0::INTERRUPT_MASK);
194 l2cxx0->write<Mword>(~0UL, L2cxx0::INTERRUPT_CLEAR);
196 if (!(l2cxx0->read<Mword>(L2cxx0::CONTROL) & 1))
198 l2cxx0->write(aux, L2cxx0::AUX_CONTROL);
200 l2cxx0->write<Mword>(1, L2cxx0::CONTROL);
203 platform_init_post();
206 show_info(ways, cache_id, aux);
216 STATIC_INITIALIZE_P(Outer_cache, STARTUP_INIT_PRIO);
218 // ------------------------------------------------------------------------
219 IMPLEMENTATION [arm && outer_cache_l2cxx0 && !debug]:
223 Outer_cache::show_info(unsigned, Mword, Mword)
226 // ------------------------------------------------------------------------
227 IMPLEMENTATION [arm && outer_cache_l2cxx0 && debug]:
234 Outer_cache::show_info(unsigned ways, Mword cache_id, Mword aux)
236 printf("L2: ID=%08lx Type=%08lx Aux=%08lx WMask=%x S=%d\n",
237 cache_id, l2cxx0->read<Mword>(L2cxx0::CACHE_TYPE), aux, waymask, need_sync);
240 switch ((cache_id >> 6) & 0xf)
250 if (cache_id & 0x3f == 5)
251 printf("L2: r3p0\n");
258 unsigned waysize = 16 << (((aux >> 17) & 7) - 1);
259 printf("L2: Type L2C-%s Size = %dkB Ways=%d Waysize=%d\n",
260 type, ways * waysize, ways, waysize);