From 166672fe163264ae2c0f67ee9cc05ee05c570ef9 Mon Sep 17 00:00:00 2001 From: Stefan Kalkowski Date: Mon, 7 Dec 2015 10:48:29 +0100 Subject: [PATCH] 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 --- .../base-hw/src/core/include/spec/arm/pl310.h | 101 +++++++----------- .../src/core/include/spec/panda/board.h | 68 +++++++----- .../src/core/include/spec/zynq/board.h | 2 +- .../src/core/spec/panda/platform_support.cc | 4 +- 4 files changed, 86 insertions(+), 89 deletions(-) diff --git a/repos/base-hw/src/core/include/spec/arm/pl310.h b/repos/base-hw/src/core/include/spec/arm/pl310.h index be62e40cf..f69079905 100644 --- a/repos/base-hw/src/core/include/spec/arm/pl310.h +++ b/repos/base-hw/src/core/include/spec/arm/pl310.h @@ -21,80 +21,59 @@ namespace Arm { - using Genode::addr_t; - - class Pl310; + struct Pl310; } /** * L2 outer cache controller */ -class Arm::Pl310 : Genode::Mmio +struct Arm::Pl310 : Genode::Mmio { - protected: + struct Control : Register <0x100, 32> + { + struct Enable : Bitfield<0,1> { }; + }; - struct Control : Register <0x100, 32> - { - struct Enable : Bitfield<0,1> { }; - }; + struct Aux : Register<0x104, 32> + { + struct Associativity : Bitfield<16,1> { }; + struct Way_size : Bitfield<17,3> { }; + struct Share_override : Bitfield<22,1> { }; + struct Reserved : Bitfield<25,1> { }; + struct Ns_lockdown : Bitfield<26,1> { }; + struct Ns_irq_ctrl : Bitfield<27,1> { }; + struct Data_prefetch : Bitfield<28,1> { }; + struct Inst_prefetch : Bitfield<29,1> { }; + struct Early_bresp : Bitfield<30,1> { }; + }; - struct Aux : Register<0x104, 32> - { - struct Associativity : Bitfield<16,1> { }; - struct Way_size : Bitfield<17,3> { }; - struct Share_override : Bitfield<22,1> { }; - struct Reserved : Bitfield<25,1> { }; - struct Ns_lockdown : Bitfield<26,1> { }; - struct Ns_irq_ctrl : Bitfield<27,1> { }; - struct Data_prefetch : Bitfield<28,1> { }; - struct Inst_prefetch : Bitfield<29,1> { }; - struct Early_bresp : Bitfield<30,1> { }; + struct Irq_mask : Register <0x214, 32> { }; + struct Irq_clear : Register <0x220, 32> { }; + struct Cache_sync : Register <0x730, 32> { }; + struct Invalidate_by_way : Register <0x77c, 32> { }; + struct Clean_invalidate_by_way : Register <0x7fc, 32> { }; - 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; - } - }; + Pl310(Genode::addr_t const base) : Mmio(base) { } - struct Irq_mask : Register <0x214, 32> { }; - struct Irq_clear : Register <0x220, 32> { }; - struct Cache_sync : Register <0x730, 32> { }; - struct Invalidate_by_way : Register <0x77c, 32> { }; - struct Clean_invalidate_by_way : Register <0x7fc, 32> { }; + inline void sync() { while (read()) ; } - inline void _sync() { while (read()) ; } + void flush() + { + write((1UL << 16) - 1); + sync(); + } - void _init() - { - write(0); - write(~0); - } + void invalidate() + { + write((1UL << 16) - 1); + sync(); + } - public: - - Pl310(addr_t const base) : Mmio(base) { } - - void flush() - { - write((1 << 16) - 1); - _sync(); - } - - void invalidate() - { - write((1 << 16) - 1); - _sync(); - } + void mask_interrupts() + { + write(0); + write(~0UL); + } }; #endif /* _SPEC__ARM__PL310_H_ */ diff --git a/repos/base-hw/src/core/include/spec/panda/board.h b/repos/base-hw/src/core/include/spec/panda/board.h index 711cdee90..e00d44de5 100644 --- a/repos/base-hw/src/core/include/spec/panda/board.h +++ b/repos/base-hw/src/core/include/spec/panda/board.h @@ -21,50 +21,68 @@ namespace Genode { - class Pl310; + class L2_cache; class Board; } /** * L2 outer cache controller */ -class Genode::Pl310 : public Arm::Pl310 +class Genode::L2_cache { private: - enum Secure_monitor_syscalls + struct Secure_monitor { - L2_CACHE_SET_DEBUG_REG = 0x100, - L2_CACHE_ENABLE_REG = 0x102, - L2_CACHE_AUX_REG = 0x109, - }; + enum Syscalls + { + L2_CACHE_SET_DEBUG_REG = 0x100, + L2_CACHE_ENABLE_REG = 0x102, + L2_CACHE_AUX_REG = 0x109, + }; - static inline void _secure_monitor_call(addr_t func, addr_t val) - { - register addr_t _func asm("r12") = func; - register addr_t _val asm("r0") = val; - asm volatile( - "dsb; smc #0" :: - "r" (_func), "r" (_val) : - "memory", "cc", "r1", "r2", "r3", "r4", "r5", "r6", "r7", - "r8", "r9", "r10", "r11"); - } + void call(addr_t func, addr_t val) + { + register addr_t _func asm("r12") = func; + register addr_t _val asm("r0") = val; + asm volatile( + "dsb; smc #0" :: + "r" (_func), "r" (_val) : + "memory", "cc", "r1", "r2", "r3", "r4", "r5", "r6", "r7", + "r8", "r9", "r10", "r11"); + } + } _secure_monitor; + + Arm::Pl310 _pl310; public: - void flush() + L2_cache() : _pl310(Cortex_a9::Board::PL310_MMIO_BASE) { - _secure_monitor_call(L2_CACHE_SET_DEBUG_REG, 0x3); - Arm::Pl310::flush(); - _secure_monitor_call(L2_CACHE_SET_DEBUG_REG, 0x0); + Arm::Pl310::Aux::access_t v = 0; + Arm::Pl310::Aux::Associativity::set(v, 1); + 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(L2_CACHE_ENABLE_REG, 1); - _init(); + _secure_monitor.call(Secure_monitor::L2_CACHE_SET_DEBUG_REG, 0x3); + _pl310.flush(); + _secure_monitor.call(Secure_monitor::L2_CACHE_SET_DEBUG_REG, 0x0); } + + void invalidate() { _pl310.invalidate(); } }; /** diff --git a/repos/base-hw/src/core/include/spec/zynq/board.h b/repos/base-hw/src/core/include/spec/zynq/board.h index 85c0692ac..2d4aa6fa3 100644 --- a/repos/base-hw/src/core/include/spec/zynq/board.h +++ b/repos/base-hw/src/core/include/spec/zynq/board.h @@ -33,7 +33,7 @@ class Genode::Pl310 : public Arm::Pl310 { public: - Pl310(addr_t const base) : Arm::Pl310(base) { _init(); } + Pl310(addr_t const base) : Arm::Pl310(base) { mask_interrupts(); } }; /** diff --git a/repos/base-hw/src/core/spec/panda/platform_support.cc b/repos/base-hw/src/core/spec/panda/platform_support.cc index ac7b590ac..1bd49f981 100644 --- a/repos/base-hw/src/core/spec/panda/platform_support.cc +++ b/repos/base-hw/src/core/spec/panda/platform_support.cc @@ -62,8 +62,8 @@ Native_region * Platform::_core_only_mmio_regions(unsigned const i) } -static Genode::Pl310 * l2_cache() { - return unmanaged_singleton(Board::PL310_MMIO_BASE); } +static Genode::L2_cache * l2_cache() { + return unmanaged_singleton(); } void Board::outer_cache_invalidate() { l2_cache()->invalidate(); }