2012-10-23 17:12:09 +02:00
|
|
|
/*
|
2012-12-03 17:21:35 +01:00
|
|
|
* \brief CPU driver for core
|
2012-10-23 17:12:09 +02:00
|
|
|
* \author Martin stein
|
|
|
|
* \date 2011-11-03
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
2017-02-20 13:23:52 +01:00
|
|
|
* Copyright (C) 2011-2017 Genode Labs GmbH
|
2012-10-23 17:12:09 +02:00
|
|
|
*
|
|
|
|
* This file is part of the Genode OS framework, which is distributed
|
2017-02-20 13:23:52 +01:00
|
|
|
* under the terms of the GNU Affero General Public License version 3.
|
2012-10-23 17:12:09 +02:00
|
|
|
*/
|
|
|
|
|
2016-01-20 20:52:51 +01:00
|
|
|
#ifndef _CORE__INCLUDE__SPEC__ARM_V7__CPU_SUPPORT_H_
|
|
|
|
#define _CORE__INCLUDE__SPEC__ARM_V7__CPU_SUPPORT_H_
|
2012-10-23 17:12:09 +02:00
|
|
|
|
|
|
|
/* core includes */
|
2014-07-15 14:51:27 +02:00
|
|
|
#include <spec/arm/cpu_support.h>
|
2012-12-10 13:55:19 +01:00
|
|
|
#include <board.h>
|
2016-01-11 11:02:52 +01:00
|
|
|
#include <pic.h>
|
2012-10-23 17:12:09 +02:00
|
|
|
|
2014-07-09 12:03:17 +02:00
|
|
|
namespace Genode
|
2012-10-23 17:12:09 +02:00
|
|
|
{
|
|
|
|
/**
|
2012-12-03 17:21:35 +01:00
|
|
|
* CPU driver for core
|
2012-10-23 17:12:09 +02:00
|
|
|
*/
|
2014-07-09 12:03:17 +02:00
|
|
|
class Arm_v7;
|
|
|
|
}
|
|
|
|
|
2015-03-27 13:55:03 +01:00
|
|
|
|
2014-07-09 12:03:17 +02:00
|
|
|
class Genode::Arm_v7 : public Arm
|
|
|
|
{
|
2015-02-18 14:41:49 +01:00
|
|
|
public:
|
2014-07-09 12:03:17 +02:00
|
|
|
|
2012-10-23 17:12:09 +02:00
|
|
|
/**
|
|
|
|
* Secure configuration register
|
|
|
|
*/
|
|
|
|
struct Scr : Register<32>
|
|
|
|
{
|
2015-02-18 14:41:49 +01:00
|
|
|
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 */
|
2012-10-23 17:12:09 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Read register value
|
|
|
|
*/
|
|
|
|
static access_t read()
|
|
|
|
{
|
|
|
|
access_t v;
|
|
|
|
asm volatile ("mrc p15, 0, %[v], c1, c1, 0" : [v]"=r"(v) ::);
|
|
|
|
return v;
|
|
|
|
}
|
2015-02-18 14:41:49 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Write register value
|
|
|
|
*/
|
|
|
|
static void write(access_t const v)
|
|
|
|
{
|
|
|
|
asm volatile ("mcr p15, 0, %[v], c1, c1, 0 \n"
|
|
|
|
"isb" : : [v] "r" (v));
|
|
|
|
}
|
2012-10-23 17:12:09 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Non-secure access control register
|
|
|
|
*/
|
|
|
|
struct Nsacr : Register<32>
|
|
|
|
{
|
|
|
|
struct Cpnsae10 : Bitfield<10, 1> { };
|
|
|
|
struct Cpnsae11 : Bitfield<11, 1> { };
|
2015-02-18 14:41:49 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Write register value
|
|
|
|
*/
|
|
|
|
static void write(access_t const v)
|
|
|
|
{
|
|
|
|
asm volatile ("mcr p15, 0, %[v], c1, c1, 2" : : [v] "r" (v));
|
|
|
|
}
|
2012-10-23 17:12:09 +02:00
|
|
|
};
|
|
|
|
|
2015-02-19 14:50:27 +01:00
|
|
|
/**
|
|
|
|
* 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) : ); }
|
|
|
|
};
|
|
|
|
|
2015-02-18 14:41:49 +01:00
|
|
|
/**
|
|
|
|
* Wait for the next interrupt as cheap as possible
|
|
|
|
*/
|
|
|
|
static void wait_for_interrupt() { asm volatile ("wfi"); }
|
|
|
|
|
2016-01-11 11:02:52 +01:00
|
|
|
/**
|
|
|
|
* Write back dirty lines of inner data cache and invalidate all
|
|
|
|
*/
|
2017-02-21 13:46:59 +01:00
|
|
|
static void clean_invalidate_inner_data_cache();
|
2016-01-11 11:02:52 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Invalidate all lines of the inner data cache
|
|
|
|
*/
|
2017-02-21 13:46:59 +01:00
|
|
|
static void invalidate_inner_data_cache();
|
2016-01-11 11:02:52 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Invalidate all lines of the instruction cache
|
|
|
|
*/
|
|
|
|
void invalidate_instruction_cache() {
|
|
|
|
asm volatile("mcr p15, 0, r0, c7, c5, 0"); }
|
|
|
|
|
2012-10-23 17:12:09 +02:00
|
|
|
|
|
|
|
/******************************
|
|
|
|
** Trustzone specific API **
|
|
|
|
******************************/
|
|
|
|
|
|
|
|
/**
|
2015-02-18 14:41:49 +01:00
|
|
|
* Wether we are in secure mode
|
2012-10-23 17:12:09 +02:00
|
|
|
*/
|
2015-02-18 14:41:49 +01:00
|
|
|
static bool secure_mode()
|
2012-10-23 17:12:09 +02:00
|
|
|
{
|
2015-02-18 14:41:49 +01:00
|
|
|
if (!Board::SECURITY_EXTENSION) return 0;
|
|
|
|
return !Scr::Ns::get(Scr::read());
|
2013-12-17 18:10:02 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2015-02-18 14:41:49 +01:00
|
|
|
* Set exception-vector's address for monitor mode to 'a'
|
2013-12-17 18:10:02 +01:00
|
|
|
*/
|
2015-02-18 14:41:49 +01:00
|
|
|
static void mon_exception_entry_at(addr_t const a) {
|
|
|
|
asm volatile ("mcr p15, 0, %[rd], c12, c0, 1" : : [rd] "r" (a)); }
|
2013-12-17 18:10:02 +01:00
|
|
|
|
2015-02-18 14:41:49 +01:00
|
|
|
|
|
|
|
/***********************************
|
|
|
|
** Virtualization specific API **
|
|
|
|
***********************************/
|
2013-12-17 18:10:02 +01:00
|
|
|
|
|
|
|
/**
|
2015-02-18 14:41:49 +01:00
|
|
|
* Set exception-vector's address for hypervisor mode to 'a'
|
2013-12-17 18:10:02 +01:00
|
|
|
*/
|
2015-02-18 14:41:49 +01:00
|
|
|
static void hyp_exception_entry_at(void * a) {
|
|
|
|
asm volatile ("mcr p15, 4, %[rd], c12, c0, 0" :: [rd] "r" (a)); }
|
2014-07-09 12:03:17 +02:00
|
|
|
};
|
2012-10-23 17:12:09 +02:00
|
|
|
|
2016-01-20 20:52:51 +01:00
|
|
|
#endif /* _CORE__INCLUDE__SPEC__ARM_V7__CPU_SUPPORT_H_ */
|