1 INTERFACE [arm && outer_cache_l2cxx0]:
3 #include "mem_layout.h"
6 EXTENSION class Outer_cache
13 CACHE_ID = Mem_layout::L2cxx0_map_base + 0x000,
14 CACHE_TYPE = Mem_layout::L2cxx0_map_base + 0x004,
15 CONTROL = Mem_layout::L2cxx0_map_base + 0x100,
16 AUX_CONTROL = Mem_layout::L2cxx0_map_base + 0x104,
17 TAG_RAM_CONTROL = Mem_layout::L2cxx0_map_base + 0x108,
18 DATA_RAM_CONTROL = Mem_layout::L2cxx0_map_base + 0x10c,
19 EVENT_COUNTER_CONTROL = Mem_layout::L2cxx0_map_base + 0x200,
20 EVENT_COUTNER1_CONFIG = Mem_layout::L2cxx0_map_base + 0x204,
21 EVENT_COUNTER0_CONFIG = Mem_layout::L2cxx0_map_base + 0x208,
22 EVENT_COUNTER1_VALUE = Mem_layout::L2cxx0_map_base + 0x20c,
23 EVENT_COUNTER0_VALUE = Mem_layout::L2cxx0_map_base + 0x210,
24 INTERRUPT_MASK = Mem_layout::L2cxx0_map_base + 0x214,
25 MASKED_INTERRUPT_STATUS = Mem_layout::L2cxx0_map_base + 0x218,
26 RAW_INTERRUPT_STATUS = Mem_layout::L2cxx0_map_base + 0x21c,
27 INTERRUPT_CLEAR = Mem_layout::L2cxx0_map_base + 0x220,
28 CACHE_SYNC = Mem_layout::L2cxx0_map_base + 0x730,
29 INVALIDATE_LINE_BY_PA = Mem_layout::L2cxx0_map_base + 0x770,
30 INVALIDATE_BY_WAY = Mem_layout::L2cxx0_map_base + 0x77c,
31 CLEAN_LINE_BY_PA = Mem_layout::L2cxx0_map_base + 0x7b0,
32 CLEAN_LINE_BY_INDEXWAY = Mem_layout::L2cxx0_map_base + 0x7bb,
33 CLEAN_BY_WAY = Mem_layout::L2cxx0_map_base + 0x7bc,
34 CLEAN_AND_INV_LINE_BY_PA = Mem_layout::L2cxx0_map_base + 0x7f0,
35 CLEAN_AND_INV_LINE_BY_INDEXWAY = Mem_layout::L2cxx0_map_base + 0x7f8,
36 CLEAN_AND_INV_BY_WAY = Mem_layout::L2cxx0_map_base + 0x7fc,
37 LOCKDOWN_BY_WAY_D_SIDE = Mem_layout::L2cxx0_map_base + 0x900,
38 LOCKDOWN_BY_WAY_I_SIDE = Mem_layout::L2cxx0_map_base + 0x904,
39 TEST_OPERATION = Mem_layout::L2cxx0_map_base + 0xf00,
40 LINE_TAG = Mem_layout::L2cxx0_map_base + 0xf30,
41 DEBUG_CONTROL_REGISTER = Mem_layout::L2cxx0_map_base + 0xf40,
44 static Spin_lock<> _lock;
46 static Mword platform_init(Mword aux);
48 static bool need_sync;
49 static unsigned waymask;
54 Cache_line_size = 1 << Cache_line_shift,
55 Cache_line_mask = Cache_line_size - 1,
59 // ------------------------------------------------------------------------
60 IMPLEMENTATION [arm && outer_cache_l2cxx0]:
63 #include "lock_guard.h"
64 #include "static_init.h"
66 Spin_lock<> Outer_cache::_lock;
67 bool Outer_cache::need_sync;
68 unsigned Outer_cache::waymask;
70 IMPLEMENT inline NEEDS ["io.h"]
74 while (Io::read<Mword>(CACHE_SYNC))
75 Proc::preemption_point();
78 PRIVATE static inline NEEDS ["io.h", "lock_guard.h"]
80 Outer_cache::write(Address reg, Mword val, bool before = false)
82 auto guard = lock_guard(_lock);
84 while (Io::read<Mword>(reg) & 1)
86 Io::write<Mword>(val, reg);
88 while (Io::read<Mword>(reg) & 1)
92 IMPLEMENT inline NEEDS[Outer_cache::write]
96 write(CLEAN_BY_WAY, waymask);
100 IMPLEMENT inline NEEDS[Outer_cache::write]
102 Outer_cache::clean(Mword phys_addr, bool do_sync = true)
104 write(CLEAN_LINE_BY_PA, phys_addr & (~0UL << Cache_line_shift));
105 if (need_sync && do_sync)
109 IMPLEMENT inline NEEDS[Outer_cache::write]
113 write(CLEAN_AND_INV_BY_WAY, waymask);
117 IMPLEMENT inline NEEDS[Outer_cache::write]
119 Outer_cache::flush(Mword phys_addr, bool do_sync = true)
121 write(CLEAN_AND_INV_LINE_BY_PA, phys_addr & (~0UL << Cache_line_shift));
122 if (need_sync && do_sync)
126 IMPLEMENT inline NEEDS[Outer_cache::write]
128 Outer_cache::invalidate()
130 write(INVALIDATE_BY_WAY, waymask);
134 IMPLEMENT inline NEEDS[Outer_cache::write]
136 Outer_cache::invalidate(Address phys_addr, bool do_sync = true)
138 write(INVALIDATE_LINE_BY_PA, phys_addr & (~0UL << Cache_line_shift));
139 if (need_sync && do_sync)
145 Outer_cache::initialize(bool v)
147 Mword cache_id = Io::read<Mword>(CACHE_ID);
148 Mword aux = Io::read<Mword>(AUX_CONTROL);
153 aux = platform_init(aux);
155 switch ((cache_id >> 6) & 0xf)
158 ways = (aux >> 13) & 0xf;
162 ways = aux & (1 << 16) ? 16 : 8;
168 waymask = (1 << ways) - 1;
170 Io::write<Mword>(0, INTERRUPT_MASK);
171 Io::write<Mword>(~0UL, INTERRUPT_CLEAR);
173 if (!(Io::read<Mword>(CONTROL) & 1))
175 Io::write(aux, AUX_CONTROL);
177 Io::write<Mword>(1, CONTROL);
181 show_info(ways, cache_id, aux);
191 STATIC_INITIALIZE_P(Outer_cache, STARTUP_INIT_PRIO);
193 // ------------------------------------------------------------------------
194 IMPLEMENTATION [arm && outer_cache_l2cxx0 && !debug]:
198 Outer_cache::show_info(unsigned, Mword, Mword)
201 // ------------------------------------------------------------------------
202 IMPLEMENTATION [arm && outer_cache_l2cxx0 && debug]:
209 Outer_cache::show_info(unsigned ways, Mword cache_id, Mword aux)
211 printf("L2: ID=%08lx Type=%08lx Aux=%08lx WMask=%x S=%d\n",
212 cache_id, Io::read<Mword>(CACHE_TYPE), aux, waymask, need_sync);
215 switch ((cache_id >> 6) & 0xf)
225 if (cache_id & 0x3f == 5)
226 printf("L2: r3p0\n");
233 unsigned waysize = 16 << (((aux >> 17) & 7) - 1);
234 printf("L2: Type L2C-%s Size = %dkB\n", type, ways * waysize);