hw: l2 cache initialization is platform specific
On ARM Cortex A9 platforms the external PL310 L2 cache controller needs to be initialized dependent on the SoC. For instance on Pandaboard it needs to call the firmware running in TrustZone's secure world, on i.MX6 it initializes it directly, on other boards it doesn't need to be initialized at all, because the bootloader already did so. Therefore, we should implement the PL310 intialization in board specific code and not in the base class implementation. Ref #1312
This commit is contained in:
parent
e05d26567d
commit
166672fe16
|
@ -21,18 +21,14 @@
|
||||||
|
|
||||||
namespace Arm
|
namespace Arm
|
||||||
{
|
{
|
||||||
using Genode::addr_t;
|
struct Pl310;
|
||||||
|
|
||||||
class Pl310;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* L2 outer cache controller
|
* L2 outer cache controller
|
||||||
*/
|
*/
|
||||||
class Arm::Pl310 : Genode::Mmio
|
struct Arm::Pl310 : Genode::Mmio
|
||||||
{
|
{
|
||||||
protected:
|
|
||||||
|
|
||||||
struct Control : Register <0x100, 32>
|
struct Control : Register <0x100, 32>
|
||||||
{
|
{
|
||||||
struct Enable : Bitfield<0,1> { };
|
struct Enable : Bitfield<0,1> { };
|
||||||
|
@ -49,21 +45,6 @@ class Arm::Pl310 : Genode::Mmio
|
||||||
struct Data_prefetch : Bitfield<28,1> { };
|
struct Data_prefetch : Bitfield<28,1> { };
|
||||||
struct Inst_prefetch : Bitfield<29,1> { };
|
struct Inst_prefetch : Bitfield<29,1> { };
|
||||||
struct Early_bresp : Bitfield<30,1> { };
|
struct Early_bresp : Bitfield<30,1> { };
|
||||||
|
|
||||||
static access_t init_value()
|
|
||||||
{
|
|
||||||
access_t v = 0;
|
|
||||||
Associativity::set(v, 1);
|
|
||||||
Way_size::set(v, 3);
|
|
||||||
Share_override::set(v, 1);
|
|
||||||
Reserved::set(v, 1);
|
|
||||||
Ns_lockdown::set(v, 1);
|
|
||||||
Ns_irq_ctrl::set(v, 1);
|
|
||||||
Data_prefetch::set(v, 1);
|
|
||||||
Inst_prefetch::set(v, 1);
|
|
||||||
Early_bresp::set(v, 1);
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Irq_mask : Register <0x214, 32> { };
|
struct Irq_mask : Register <0x214, 32> { };
|
||||||
|
@ -72,28 +53,26 @@ class Arm::Pl310 : Genode::Mmio
|
||||||
struct Invalidate_by_way : Register <0x77c, 32> { };
|
struct Invalidate_by_way : Register <0x77c, 32> { };
|
||||||
struct Clean_invalidate_by_way : Register <0x7fc, 32> { };
|
struct Clean_invalidate_by_way : Register <0x7fc, 32> { };
|
||||||
|
|
||||||
inline void _sync() { while (read<Cache_sync>()) ; }
|
Pl310(Genode::addr_t const base) : Mmio(base) { }
|
||||||
|
|
||||||
void _init()
|
inline void sync() { while (read<Cache_sync>()) ; }
|
||||||
{
|
|
||||||
write<Irq_mask>(0);
|
|
||||||
write<Irq_clear>(~0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
Pl310(addr_t const base) : Mmio(base) { }
|
|
||||||
|
|
||||||
void flush()
|
void flush()
|
||||||
{
|
{
|
||||||
write<Clean_invalidate_by_way>((1 << 16) - 1);
|
write<Clean_invalidate_by_way>((1UL << 16) - 1);
|
||||||
_sync();
|
sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
void invalidate()
|
void invalidate()
|
||||||
{
|
{
|
||||||
write<Invalidate_by_way>((1 << 16) - 1);
|
write<Invalidate_by_way>((1UL << 16) - 1);
|
||||||
_sync();
|
sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
void mask_interrupts()
|
||||||
|
{
|
||||||
|
write<Irq_mask>(0);
|
||||||
|
write<Irq_clear>(~0UL);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -21,25 +21,27 @@
|
||||||
|
|
||||||
namespace Genode
|
namespace Genode
|
||||||
{
|
{
|
||||||
class Pl310;
|
class L2_cache;
|
||||||
class Board;
|
class Board;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* L2 outer cache controller
|
* L2 outer cache controller
|
||||||
*/
|
*/
|
||||||
class Genode::Pl310 : public Arm::Pl310
|
class Genode::L2_cache
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
enum Secure_monitor_syscalls
|
struct Secure_monitor
|
||||||
|
{
|
||||||
|
enum Syscalls
|
||||||
{
|
{
|
||||||
L2_CACHE_SET_DEBUG_REG = 0x100,
|
L2_CACHE_SET_DEBUG_REG = 0x100,
|
||||||
L2_CACHE_ENABLE_REG = 0x102,
|
L2_CACHE_ENABLE_REG = 0x102,
|
||||||
L2_CACHE_AUX_REG = 0x109,
|
L2_CACHE_AUX_REG = 0x109,
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline void _secure_monitor_call(addr_t func, addr_t val)
|
void call(addr_t func, addr_t val)
|
||||||
{
|
{
|
||||||
register addr_t _func asm("r12") = func;
|
register addr_t _func asm("r12") = func;
|
||||||
register addr_t _val asm("r0") = val;
|
register addr_t _val asm("r0") = val;
|
||||||
|
@ -49,22 +51,38 @@ class Genode::Pl310 : public Arm::Pl310
|
||||||
"memory", "cc", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
|
"memory", "cc", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
|
||||||
"r8", "r9", "r10", "r11");
|
"r8", "r9", "r10", "r11");
|
||||||
}
|
}
|
||||||
|
} _secure_monitor;
|
||||||
|
|
||||||
|
Arm::Pl310 _pl310;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
void flush()
|
L2_cache() : _pl310(Cortex_a9::Board::PL310_MMIO_BASE)
|
||||||
{
|
{
|
||||||
_secure_monitor_call(L2_CACHE_SET_DEBUG_REG, 0x3);
|
Arm::Pl310::Aux::access_t v = 0;
|
||||||
Arm::Pl310::flush();
|
Arm::Pl310::Aux::Associativity::set(v, 1);
|
||||||
_secure_monitor_call(L2_CACHE_SET_DEBUG_REG, 0x0);
|
Arm::Pl310::Aux::Way_size::set(v, 3);
|
||||||
|
Arm::Pl310::Aux::Share_override::set(v, 1);
|
||||||
|
Arm::Pl310::Aux::Reserved::set(v, 1);
|
||||||
|
Arm::Pl310::Aux::Ns_lockdown::set(v, 1);
|
||||||
|
Arm::Pl310::Aux::Ns_irq_ctrl::set(v, 1);
|
||||||
|
Arm::Pl310::Aux::Data_prefetch::set(v, 1);
|
||||||
|
Arm::Pl310::Aux::Inst_prefetch::set(v, 1);
|
||||||
|
Arm::Pl310::Aux::Early_bresp::set(v, 1);
|
||||||
|
|
||||||
|
_secure_monitor.call(Secure_monitor::L2_CACHE_AUX_REG, v);
|
||||||
|
_secure_monitor.call(Secure_monitor::L2_CACHE_ENABLE_REG, 1);
|
||||||
|
_pl310.mask_interrupts();
|
||||||
}
|
}
|
||||||
|
|
||||||
Pl310(addr_t const base) : Arm::Pl310(base)
|
void flush()
|
||||||
{
|
{
|
||||||
_secure_monitor_call(L2_CACHE_AUX_REG, Aux::init_value());
|
_secure_monitor.call(Secure_monitor::L2_CACHE_SET_DEBUG_REG, 0x3);
|
||||||
_secure_monitor_call(L2_CACHE_ENABLE_REG, 1);
|
_pl310.flush();
|
||||||
_init();
|
_secure_monitor.call(Secure_monitor::L2_CACHE_SET_DEBUG_REG, 0x0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void invalidate() { _pl310.invalidate(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -33,7 +33,7 @@ class Genode::Pl310 : public Arm::Pl310
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Pl310(addr_t const base) : Arm::Pl310(base) { _init(); }
|
Pl310(addr_t const base) : Arm::Pl310(base) { mask_interrupts(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -62,8 +62,8 @@ Native_region * Platform::_core_only_mmio_regions(unsigned const i)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static Genode::Pl310 * l2_cache() {
|
static Genode::L2_cache * l2_cache() {
|
||||||
return unmanaged_singleton<Genode::Pl310>(Board::PL310_MMIO_BASE); }
|
return unmanaged_singleton<Genode::L2_cache>(); }
|
||||||
|
|
||||||
|
|
||||||
void Board::outer_cache_invalidate() { l2_cache()->invalidate(); }
|
void Board::outer_cache_invalidate() { l2_cache()->invalidate(); }
|
||||||
|
|
Loading…
Reference in New Issue
Block a user