/* * \brief CPU driver for core * \author Martin stein * \date 2011-11-03 */ /* * Copyright (C) 2011-2013 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 _SPEC__ARM_V7__CPU_SUPPORT_H_ #define _SPEC__ARM_V7__CPU_SUPPORT_H_ /* core includes */ #include #include #include namespace Genode { /** * CPU driver for core */ class Arm_v7; } class Genode::Arm_v7 : public Arm { public: /** * Secure configuration register */ struct Scr : Register<32> { struct Ns : Bitfield<0, 1> { }; /* not secure */ struct Fw : Bitfield<4, 1> { }; /* F bit writeable */ struct Aw : Bitfield<5, 1> { }; /* A bit writeable */ struct Scd : Bitfield<7, 1> { }; /* smc call disable */ struct Hce : Bitfield<8, 1> { }; /* hyp call enable */ struct Sif : Bitfield<9, 1> { }; /* secure instruction fetch */ /** * Read register value */ static access_t read() { access_t v; asm volatile ("mrc p15, 0, %[v], c1, c1, 0" : [v]"=r"(v) ::); return v; } /** * Write register value */ static void write(access_t const v) { asm volatile ("mcr p15, 0, %[v], c1, c1, 0 \n" "isb" : : [v] "r" (v)); } }; /** * Non-secure access control register */ struct Nsacr : Register<32> { struct Cpnsae10 : Bitfield<10, 1> { }; struct Cpnsae11 : Bitfield<11, 1> { }; /** * Write register value */ static void write(access_t const v) { asm volatile ("mcr p15, 0, %[v], c1, c1, 2" : : [v] "r" (v)); } }; /** * System control register */ struct Sctlr : Arm::Sctlr { struct Z : Bitfield<11,1> { }; /* enable program flow prediction */ static access_t init_value() { access_t v = read(); C::set(v, 1); I::set(v, 1); V::set(v, 1); A::set(v, 0); M::set(v, 1); Z::set(v, 1); return v; } static void enable_mmu_and_caches() { write(init_value()); } }; /** * Memory attribute indirection register 0 */ struct Mair0 : Register<32> { struct Attr0 : Bitfield<0, 8> { }; struct Attr1 : Bitfield<8, 8> { }; struct Attr2 : Bitfield<16, 8> { }; struct Attr3 : Bitfield<24, 8> { }; static void write(access_t v) { asm volatile ("mcr p15, 0, %[v], c10, c2, 0" :: [v]"r"(v) : ); } }; /** * Invalidate all branch predictions */ static void invalidate_branch_predicts() { asm volatile ("mcr p15, 0, r0, c7, c5, 6" ::: "r0"); }; /** * Switch on MMU and caches * * \param pd kernel's pd object */ void enable_mmu_and_caches(Kernel::Pd& pd); /** * Finish all previous data transfers */ static void data_synchronization_barrier() { asm volatile ("dsb"); } /** * Wait for the next interrupt as cheap as possible */ static void wait_for_interrupt() { asm volatile ("wfi"); } /** * Write back dirty lines of inner data cache and invalidate all */ void clean_invalidate_inner_data_cache(); /** * Invalidate all lines of the inner data cache */ void invalidate_inner_data_cache(); /** * Invalidate all lines of the instruction cache */ void invalidate_instruction_cache() { asm volatile("mcr p15, 0, r0, c7, c5, 0"); } /****************************** ** Trustzone specific API ** ******************************/ /** * Wether we are in secure mode */ static bool secure_mode() { if (!Board::SECURITY_EXTENSION) return 0; return !Scr::Ns::get(Scr::read()); } /** * Set exception-vector's address for monitor mode to 'a' */ static void mon_exception_entry_at(addr_t const a) { asm volatile ("mcr p15, 0, %[rd], c12, c0, 1" : : [rd] "r" (a)); } /*********************************** ** Virtualization specific API ** ***********************************/ /** * Set exception-vector's address for hypervisor mode to 'a' */ static void hyp_exception_entry_at(void * a) { asm volatile ("mcr p15, 4, %[rd], c12, c0, 0" :: [rd] "r" (a)); } }; #endif /* _SPEC__ARM_V7__CPU_SUPPORT_H_ */