From 05603951b6e4e3a259287ac35519399eeb1d37ee Mon Sep 17 00:00:00 2001 From: Stefan Kalkowski Date: Wed, 4 Jun 2014 15:35:54 +0200 Subject: [PATCH] hw: enable and maintain outer l2 cache Fix #1170 --- .../base-hw/src/core/arm_v7/mode_transition.s | 2 +- repos/base-hw/src/core/arndale/board.h | 2 + repos/base-hw/src/core/board.h | 2 + repos/base-hw/src/core/imx31/board.h | 3 + repos/base-hw/src/core/imx53/board.h | 3 + repos/base-hw/src/core/panda/board.h | 120 ++++++++++++++++++ .../src/core/panda/platform_support.cc | 15 ++- repos/base-hw/src/core/processor_driver/arm.h | 8 +- .../src/core/processor_driver/arm_v7.h | 2 + .../platform/panda/drivers/board_base.h | 4 + 10 files changed, 155 insertions(+), 6 deletions(-) create mode 100644 repos/base-hw/src/core/panda/board.h diff --git a/repos/base-hw/src/core/arm_v7/mode_transition.s b/repos/base-hw/src/core/arm_v7/mode_transition.s index 603bbd0b37..db9cea9f77 100644 --- a/repos/base-hw/src/core/arm_v7/mode_transition.s +++ b/repos/base-hw/src/core/arm_v7/mode_transition.s @@ -94,7 +94,7 @@ _common_constants .macro _init_ttbr0 section_table_reg /* IRGN bitfield is set to 1 to compose the TTBR0 value */ - orr \section_table_reg, \section_table_reg, #0b1000000 + orr \section_table_reg, \section_table_reg, #0b1001000 /* write translation-table-base register 0 */ mcr p15, 0, \section_table_reg, c2, c0, 0 diff --git a/repos/base-hw/src/core/arndale/board.h b/repos/base-hw/src/core/arndale/board.h index 2e95774235..791fd306a5 100644 --- a/repos/base-hw/src/core/arndale/board.h +++ b/repos/base-hw/src/core/arndale/board.h @@ -23,6 +23,8 @@ namespace Genode { public: + static void outer_cache_invalidate() { } + static void outer_cache_flush() { } static void prepare_kernel() { } /** diff --git a/repos/base-hw/src/core/board.h b/repos/base-hw/src/core/board.h index 2dbfe3327b..4a53a1f33a 100644 --- a/repos/base-hw/src/core/board.h +++ b/repos/base-hw/src/core/board.h @@ -23,6 +23,8 @@ namespace Genode { public: + static void outer_cache_invalidate() { } + static void outer_cache_flush() { } static void prepare_kernel() { } static void secondary_processors_ip(void * const ip) { } diff --git a/repos/base-hw/src/core/imx31/board.h b/repos/base-hw/src/core/imx31/board.h index eea0bf0f4a..88a7befbf2 100644 --- a/repos/base-hw/src/core/imx31/board.h +++ b/repos/base-hw/src/core/imx31/board.h @@ -92,6 +92,9 @@ namespace Genode aips_1()->prepare_kernel(); aips_2()->prepare_kernel(); } + + static void outer_cache_invalidate() { } + static void outer_cache_flush() { } }; } diff --git a/repos/base-hw/src/core/imx53/board.h b/repos/base-hw/src/core/imx53/board.h index 1b6a12f37b..65d19728e2 100644 --- a/repos/base-hw/src/core/imx53/board.h +++ b/repos/base-hw/src/core/imx53/board.h @@ -97,6 +97,9 @@ namespace Imx53 aips_2()->prepare_kernel(); } + static void outer_cache_invalidate() { } + static void outer_cache_flush() { } + /** * Tell secondary processors where to start execution from */ diff --git a/repos/base-hw/src/core/panda/board.h b/repos/base-hw/src/core/panda/board.h new file mode 100644 index 0000000000..ee63a19d08 --- /dev/null +++ b/repos/base-hw/src/core/panda/board.h @@ -0,0 +1,120 @@ +/* + * \brief Board driver for core on pandaboard + * \author Stefan Kalkowski + * \date 2014-06-02 + */ + +/* + * Copyright (C) 2014 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#ifndef _PANDA__BOARD_H_ +#define _PANDA__BOARD_H_ + +/* core includes */ +#include +#include + +namespace Genode +{ + struct Board : Board_base + { + /** + * L2 outer cache controller + */ + struct Pl310 : Mmio { + + enum Trustzone_hypervisor_syscalls { + L2_CACHE_SET_DEBUG_REG = 0x100, + L2_CACHE_ENABLE_REG = 0x102, + L2_CACHE_AUX_REG = 0x109, + }; + + static inline void + trustzone_hypervisor_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"); + } + + struct Control : Register <0x100, 32> + { + struct Enable : Bitfield<0,1> {}; + }; + + struct Aux : Register<0x104, 32> + { + struct Associativity : Bitfield<16,1> { + enum { WAY_8, WAY_16 }; }; + struct Way_size : Bitfield<17,3> { + enum { SZ_64KB = 0x3 }; }; + 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> {}; + + static access_t init_value() + { + return Associativity::bits(Associativity::WAY_16) | + Way_size::bits(Way_size::SZ_64KB) | + Share_override::bits(1) | + Reserved::bits(1) | + Ns_lockdown::bits(1) | + Ns_irq_ctrl::bits(1) | + Data_prefetch::bits(1) | + Inst_prefetch::bits(1) | + Early_bresp::bits(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> {}; + + inline void sync() { while (read()) ; } + + void invalidate() + { + write((1 << 16) - 1); + sync(); + } + + void flush() + { + trustzone_hypervisor_call(L2_CACHE_SET_DEBUG_REG, 0x3); + write((1 << 16) - 1); + sync(); + trustzone_hypervisor_call(L2_CACHE_SET_DEBUG_REG, 0x0); + } + + Pl310(addr_t const base) : Mmio(base) + { + trustzone_hypervisor_call(L2_CACHE_AUX_REG, + Pl310::Aux::init_value()); + trustzone_hypervisor_call(L2_CACHE_ENABLE_REG, 1); + write(0); + write(0xffffffff); + } + }; + + static void outer_cache_invalidate(); + static void outer_cache_flush(); + static void prepare_kernel(); + + static void secondary_processors_ip(void * const ip) { } + }; +} + +#endif /* _PANDA__BOARD_H_ */ + diff --git a/repos/base-hw/src/core/panda/platform_support.cc b/repos/base-hw/src/core/panda/platform_support.cc index 1ef20a318b..e57d78baf2 100644 --- a/repos/base-hw/src/core/panda/platform_support.cc +++ b/repos/base-hw/src/core/panda/platform_support.cc @@ -16,6 +16,7 @@ #include #include #include +#include using namespace Genode; @@ -52,10 +53,22 @@ Native_region * Platform::_core_only_mmio_regions(unsigned const i) Board::CORTEX_A9_PRIVATE_MEM_SIZE }, /* core UART */ - { Board::TL16C750_3_MMIO_BASE, Board::TL16C750_MMIO_SIZE } + { Board::TL16C750_3_MMIO_BASE, Board::TL16C750_MMIO_SIZE }, + + /* l2 cache controller */ + { Board::PL310_MMIO_BASE, Board::PL310_MMIO_SIZE } }; return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0; } Processor_driver::User_context::User_context() { cpsr = Psr::init_user(); } + + +static Board::Pl310 * l2_cache() { + return unmanaged_singleton(Board::PL310_MMIO_BASE); } + + +void Board::outer_cache_invalidate() { l2_cache()->invalidate(); } +void Board::outer_cache_flush() { l2_cache()->flush(); } +void Board::prepare_kernel() { l2_cache()->invalidate(); } diff --git a/repos/base-hw/src/core/processor_driver/arm.h b/repos/base-hw/src/core/processor_driver/arm.h index 0fecf6ada3..2c231a898d 100644 --- a/repos/base-hw/src/core/processor_driver/arm.h +++ b/repos/base-hw/src/core/processor_driver/arm.h @@ -197,7 +197,7 @@ namespace Arm struct Rgn : Bitfield<3, 2> /* outer cachable attributes */ { - enum { NON_CACHEABLE = 0 }; + enum { NON_CACHEABLE = 0, CACHEABLE = 1 }; }; struct Ba : Bitfield<14-TTBCR_N, 18+TTBCR_N> { }; /* translation @@ -227,7 +227,7 @@ namespace Arm static access_t init_virt_kernel(addr_t const sect_table) { return S::bits(0) | - Rgn::bits(Rgn::NON_CACHEABLE) | + Rgn::bits(Rgn::CACHEABLE) | Ba::masked((addr_t)sect_table); } }; @@ -657,8 +657,8 @@ namespace Arm */ static void flush_tlb_by_pid(unsigned const pid) { - asm volatile ("mcr p15, 0, %[pid], c8, c7, 2" :: [pid]"r"(pid) : ); flush_caches(); + asm volatile ("mcr p15, 0, %[pid], c8, c7, 2" :: [pid]"r"(pid) : ); } /** @@ -666,8 +666,8 @@ namespace Arm */ static void flush_tlb() { - asm volatile ("mcr p15, 0, %[rd], c8, c7, 0" :: [rd]"r"(0) : ); flush_caches(); + asm volatile ("mcr p15, 0, %[rd], c8, c7, 0" :: [rd]"r"(0) : ); } /** diff --git a/repos/base-hw/src/core/processor_driver/arm_v7.h b/repos/base-hw/src/core/processor_driver/arm_v7.h index a594956549..d1b1904bcf 100644 --- a/repos/base-hw/src/core/processor_driver/arm_v7.h +++ b/repos/base-hw/src/core/processor_driver/arm_v7.h @@ -381,6 +381,7 @@ void Arm::Processor_driver::flush_data_caches() FOR_ALL_SET_WAY_OF_ALL_DATA_CACHES_0 WRITE_DCCSW(r6) FOR_ALL_SET_WAY_OF_ALL_DATA_CACHES_1); + Board::outer_cache_flush(); } @@ -390,6 +391,7 @@ void Arm::Processor_driver::invalidate_data_caches() FOR_ALL_SET_WAY_OF_ALL_DATA_CACHES_0 WRITE_DCISW(r6) FOR_ALL_SET_WAY_OF_ALL_DATA_CACHES_1); + Board::outer_cache_invalidate(); } diff --git a/repos/base/include/platform/panda/drivers/board_base.h b/repos/base/include/platform/panda/drivers/board_base.h index 319fca6e9d..ff2410888e 100644 --- a/repos/base/include/platform/panda/drivers/board_base.h +++ b/repos/base/include/platform/panda/drivers/board_base.h @@ -60,6 +60,10 @@ namespace Genode CORTEX_A9_PRIVATE_MEM_SIZE = 0x00002000, CORTEX_A9_CLOCK = MPU_DPLL_CLOCK, + /* L2 cache */ + PL310_MMIO_BASE = 0x48242000, + PL310_MMIO_SIZE = 0x00001000, + /* display subsystem */ DSS_MMIO_BASE = 0x58000000, DSS_MMIO_SIZE = 0x00001000,