mirror of
https://github.com/genodelabs/genode.git
synced 2025-05-29 05:34:23 +00:00
hw: cleanup core code (Ref #2394)
This commit is contained in:
parent
bc2ef2b1b2
commit
b9549e58d0
@ -12,6 +12,7 @@ INC_DIR += $(BASE_DIR)/../base-hw/src/core/spec/arm_gic
|
|||||||
SRC_CC += spec/cortex_a15/kernel/cpu.cc
|
SRC_CC += spec/cortex_a15/kernel/cpu.cc
|
||||||
SRC_CC += spec/arm/smp/kernel/thread_update_pd.cc
|
SRC_CC += spec/arm/smp/kernel/thread_update_pd.cc
|
||||||
SRC_CC += spec/arm/smp/kernel/cpu.cc
|
SRC_CC += spec/arm/smp/kernel/cpu.cc
|
||||||
|
SRC_CC += spec/arm/cpu_context.cc
|
||||||
|
|
||||||
# include less specific configuration
|
# include less specific configuration
|
||||||
include $(BASE_DIR)/../base-hw/lib/mk/spec/smp/core-hw.inc
|
include $(BASE_DIR)/../base-hw/lib/mk/spec/smp/core-hw.inc
|
||||||
|
@ -13,6 +13,7 @@ SRC_CC += spec/cortex_a9/kernel/cpu.cc
|
|||||||
SRC_CC += spec/cortex_a9/fpu.cc
|
SRC_CC += spec/cortex_a9/fpu.cc
|
||||||
SRC_CC += spec/cortex_a9/board.cc
|
SRC_CC += spec/cortex_a9/board.cc
|
||||||
SRC_CC += spec/cortex_a9/timer.cc
|
SRC_CC += spec/cortex_a9/timer.cc
|
||||||
|
SRC_CC += spec/arm/cpu_context.cc
|
||||||
SRC_CC += spec/arm/smp/kernel/thread_update_pd.cc
|
SRC_CC += spec/arm/smp/kernel/thread_update_pd.cc
|
||||||
SRC_CC += spec/arm/smp/kernel/cpu.cc
|
SRC_CC += spec/arm/smp/kernel/cpu.cc
|
||||||
SRC_CC += spec/arm/kernel/cpu_context.cc
|
SRC_CC += spec/arm/kernel/cpu_context.cc
|
||||||
|
@ -7,7 +7,6 @@
|
|||||||
|
|
||||||
# add C++ sources
|
# add C++ sources
|
||||||
SRC_CC += kernel/vm_thread_off.cc
|
SRC_CC += kernel/vm_thread_off.cc
|
||||||
SRC_CC += spec/imx53/platform_support.cc
|
|
||||||
SRC_CC += platform_services.cc
|
SRC_CC += platform_services.cc
|
||||||
|
|
||||||
# include less specific configuration
|
# include less specific configuration
|
||||||
|
@ -10,7 +10,6 @@ INC_DIR += $(REP_DIR)/src/core/spec/arm_v7/trustzone
|
|||||||
INC_DIR += $(REP_DIR)/src/core/spec/imx53/trustzone
|
INC_DIR += $(REP_DIR)/src/core/spec/imx53/trustzone
|
||||||
|
|
||||||
# add C++ sources
|
# add C++ sources
|
||||||
SRC_CC += spec/imx53/trustzone/platform_support.cc
|
|
||||||
SRC_CC += spec/imx53/trustzone/platform_services.cc
|
SRC_CC += spec/imx53/trustzone/platform_services.cc
|
||||||
SRC_CC += kernel/vm_thread_on.cc
|
SRC_CC += kernel/vm_thread_on.cc
|
||||||
SRC_CC += spec/arm_v7/trustzone/kernel/vm.cc
|
SRC_CC += spec/arm_v7/trustzone/kernel/vm.cc
|
||||||
|
@ -10,6 +10,7 @@ INC_DIR += $(REP_DIR)/src/core/spec/imx53
|
|||||||
INC_DIR += $(REP_DIR)/src/core/spec/imx
|
INC_DIR += $(REP_DIR)/src/core/spec/imx
|
||||||
|
|
||||||
SRC_CC += spec/imx53/pic.cc
|
SRC_CC += spec/imx53/pic.cc
|
||||||
|
SRC_CC += spec/arm/cpu_context_trustzone.cc
|
||||||
|
|
||||||
# include less specific configuration
|
# include less specific configuration
|
||||||
include $(REP_DIR)/lib/mk/spec/cortex_a8/core-hw.inc
|
include $(REP_DIR)/lib/mk/spec/cortex_a8/core-hw.inc
|
||||||
|
@ -12,7 +12,6 @@ INC_DIR += $(REP_DIR)/src/core/spec/imx
|
|||||||
|
|
||||||
# add C++ sources
|
# add C++ sources
|
||||||
SRC_CC += platform_services.cc
|
SRC_CC += platform_services.cc
|
||||||
SRC_CC += spec/imx6/platform_support.cc
|
|
||||||
|
|
||||||
NR_OF_CPUS = 4
|
NR_OF_CPUS = 4
|
||||||
|
|
||||||
|
@ -11,7 +11,6 @@ INC_DIR += $(REP_DIR)/src/core/spec/tl16c750
|
|||||||
|
|
||||||
# add C++ sources
|
# add C++ sources
|
||||||
SRC_CC += platform_services.cc
|
SRC_CC += platform_services.cc
|
||||||
SRC_CC += spec/panda/platform_support.cc
|
|
||||||
|
|
||||||
NR_OF_CPUS += 2
|
NR_OF_CPUS += 2
|
||||||
|
|
||||||
|
@ -11,7 +11,6 @@ INC_DIR += $(REP_DIR)/src/core/spec/pl011
|
|||||||
|
|
||||||
# add C++ sources
|
# add C++ sources
|
||||||
SRC_CC += platform_services.cc
|
SRC_CC += platform_services.cc
|
||||||
SRC_CC += spec/pbxa9/platform_support.cc
|
|
||||||
SRC_CC += spec/pbxa9/board.cc
|
SRC_CC += spec/pbxa9/board.cc
|
||||||
|
|
||||||
NR_OF_CPUS = 1
|
NR_OF_CPUS = 1
|
||||||
|
@ -10,7 +10,7 @@ INC_DIR += $(REP_DIR)/src/core/spec/pl011
|
|||||||
|
|
||||||
# add C++ sources
|
# add C++ sources
|
||||||
SRC_CC += platform_services.cc
|
SRC_CC += platform_services.cc
|
||||||
SRC_CC += spec/rpi/platform_support.cc
|
SRC_CC += spec/arm/cpu_context.cc
|
||||||
SRC_CC += spec/rpi/timer.cc
|
SRC_CC += spec/rpi/timer.cc
|
||||||
SRC_CC += spec/rpi/pic.cc
|
SRC_CC += spec/rpi/pic.cc
|
||||||
|
|
||||||
|
@ -9,7 +9,6 @@ INC_DIR += $(BASE_DIR)/../base-hw/src/core/spec/zynq
|
|||||||
|
|
||||||
# add C++ sources
|
# add C++ sources
|
||||||
SRC_CC += platform_services.cc
|
SRC_CC += platform_services.cc
|
||||||
SRC_CC += spec/zynq/platform_support.cc
|
|
||||||
|
|
||||||
# include less specific configuration
|
# include less specific configuration
|
||||||
include $(BASE_DIR)/../base-hw/lib/mk/spec/cortex_a9/core-hw.inc
|
include $(BASE_DIR)/../base-hw/lib/mk/spec/cortex_a9/core-hw.inc
|
||||||
|
25
repos/base-hw/src/core/spec/arm/cpu_context.cc
Normal file
25
repos/base-hw/src/core/spec/arm/cpu_context.cc
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* \brief ARM cpu context initialization
|
||||||
|
* \author Stefan Kalkowski
|
||||||
|
* \date 2017-04-12
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2017 Genode Labs GmbH
|
||||||
|
*
|
||||||
|
* This file is part of the Genode OS framework, which is distributed
|
||||||
|
* under the terms of the GNU Affero General Public License version 3.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <spec/arm/cpu_support.h>
|
||||||
|
|
||||||
|
Genode::Arm_cpu::User_context::User_context()
|
||||||
|
{
|
||||||
|
using Psr = Arm_cpu::Psr;
|
||||||
|
|
||||||
|
Psr::access_t v = 0;
|
||||||
|
Psr::M::set(v, Psr::M::USR);
|
||||||
|
Psr::F::set(v, 1);
|
||||||
|
Psr::A::set(v, 1);
|
||||||
|
cpsr = v;
|
||||||
|
}
|
25
repos/base-hw/src/core/spec/arm/cpu_context_trustzone.cc
Normal file
25
repos/base-hw/src/core/spec/arm/cpu_context_trustzone.cc
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* \brief ARM cpu context initialization when TrustZone is used
|
||||||
|
* \author Stefan Kalkowski
|
||||||
|
* \date 2017-04-12
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2017 Genode Labs GmbH
|
||||||
|
*
|
||||||
|
* This file is part of the Genode OS framework, which is distributed
|
||||||
|
* under the terms of the GNU Affero General Public License version 3.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <spec/arm/cpu_support.h>
|
||||||
|
|
||||||
|
Genode::Arm_cpu::User_context::User_context()
|
||||||
|
{
|
||||||
|
using Psr = Genode::Arm_cpu::Psr;
|
||||||
|
|
||||||
|
Psr::access_t v = 0;
|
||||||
|
Psr::M::set(v, Psr::M::USR);
|
||||||
|
Psr::I::set(v, 1);
|
||||||
|
Psr::A::set(v, 1);
|
||||||
|
cpsr = v;
|
||||||
|
}
|
@ -12,485 +12,248 @@
|
|||||||
* under the terms of the GNU Affero General Public License version 3.
|
* under the terms of the GNU Affero General Public License version 3.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _CORE__SPEC__ARM__CPU_SUPPORT_H_
|
#ifndef _CORE__SPEC__ARM__CPU_H_
|
||||||
#define _CORE__SPEC__ARM__CPU_SUPPORT_H_
|
#define _CORE__SPEC__ARM__CPU_H_
|
||||||
|
|
||||||
/* Genode includes */
|
/* Genode includes */
|
||||||
#include <util/register.h>
|
#include <util/register.h>
|
||||||
#include <cpu/cpu_state.h>
|
#include <cpu/cpu_state.h>
|
||||||
|
|
||||||
|
#include <hw/spec/arm/cpu.h>
|
||||||
|
|
||||||
/* local includes */
|
/* local includes */
|
||||||
#include <kernel/kernel.h>
|
#include <kernel/kernel.h>
|
||||||
#include <board.h>
|
#include <board.h>
|
||||||
#include <util.h>
|
#include <util.h>
|
||||||
|
|
||||||
namespace Kernel { class Pd; }
|
namespace Genode {
|
||||||
|
using sizet_arithm_t = Genode::uint64_t;
|
||||||
namespace Genode
|
struct Arm_cpu;
|
||||||
{
|
|
||||||
class Arm;
|
|
||||||
|
|
||||||
typedef Genode::uint64_t sizet_arithm_t;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class Genode::Arm
|
struct Genode::Arm_cpu : public Hw::Arm_cpu
|
||||||
{
|
{
|
||||||
public:
|
static constexpr addr_t exception_entry = 0xffff0000;
|
||||||
|
static constexpr addr_t mtc_size = get_page_size();
|
||||||
|
|
||||||
static constexpr addr_t exception_entry = 0xffff0000;
|
/**
|
||||||
static constexpr addr_t mtc_size = get_page_size();
|
* Translation table base register 0
|
||||||
static constexpr addr_t data_access_align = 4;
|
*/
|
||||||
|
struct Ttbr0 : Hw::Arm_cpu::Ttbr0
|
||||||
|
{
|
||||||
|
enum Memory_region { NON_CACHEABLE = 0, CACHEABLE = 1 };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Multiprocessor affinity register
|
* Return initialized value
|
||||||
|
*
|
||||||
|
* \param table base of targeted translation table
|
||||||
*/
|
*/
|
||||||
struct Mpidr : Register<32>
|
static access_t init(addr_t const table)
|
||||||
{
|
{
|
||||||
struct Aff_0 : Bitfield<0, 8> { }; /* affinity value 0 */
|
access_t v = Ttbr::Ba::masked((addr_t)table);
|
||||||
|
Ttbr::Rgn::set(v, CACHEABLE);
|
||||||
|
Ttbr::S::set(v, Board::SMP ? 1 : 0);
|
||||||
|
if (Board::SMP) Ttbr::Irgn::set(v, CACHEABLE);
|
||||||
|
else Ttbr::C::set(v, 1);
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
static access_t read()
|
struct Dfsr : Hw::Arm_cpu::Dfsr
|
||||||
{
|
{
|
||||||
access_t v;
|
struct Wnr : Bitfield<11, 1> { }; /* write not read bit */
|
||||||
asm volatile ("mrc p15, 0, %0, c0, c0, 5" : "=r" (v) :: );
|
};
|
||||||
return v;
|
|
||||||
}
|
/**
|
||||||
};
|
* Extend basic CPU state by members relevant for 'base-hw' only
|
||||||
|
*/
|
||||||
|
struct Context : Cpu_state
|
||||||
|
{
|
||||||
|
Cidr::access_t cidr;
|
||||||
|
Ttbr0::access_t ttbr0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cache type register
|
* Return base of assigned translation table
|
||||||
*/
|
*/
|
||||||
struct Ctr : Register<32>
|
addr_t translation_table() const {
|
||||||
{
|
return Ttbr::Ba::masked(ttbr0); }
|
||||||
static access_t read()
|
|
||||||
{
|
|
||||||
access_t v;
|
|
||||||
asm volatile ("mrc p15, 0, %0, c0, c0, 1" : "=r" (v) :: );
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Translation table base register 0
|
* Assign translation-table base 'table'
|
||||||
*/
|
*/
|
||||||
struct Ttbr0 : Register<32>
|
void translation_table(addr_t const table) {
|
||||||
{
|
ttbr0 = Ttbr0::init(table); }
|
||||||
enum Memory_region { NON_CACHEABLE = 0, CACHEABLE = 1 };
|
|
||||||
|
|
||||||
struct C : Bitfield<0,1> { }; /* inner cacheable */
|
|
||||||
struct S : Bitfield<1,1> { }; /* shareable */
|
|
||||||
struct Rgn : Bitfield<3,2> { }; /* outer cachable mode */
|
|
||||||
struct Nos : Bitfield<5,1> { }; /* not outer shareable */
|
|
||||||
struct Ba : Bitfield<14, 18> { }; /* translation table base */
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************
|
|
||||||
* with multiprocessing extension **
|
|
||||||
*************************************/
|
|
||||||
|
|
||||||
struct Irgn_1 : Bitfield<0,1> { };
|
|
||||||
struct Irgn_0 : Bitfield<6,1> { };
|
|
||||||
struct Irgn : Bitset_2<Irgn_0, Irgn_1> { }; /* inner cache mode */
|
|
||||||
|
|
||||||
static void write(access_t const v) {
|
|
||||||
asm volatile ("mcr p15, 0, %0, c2, c0, 0" :: "r" (v) : ); }
|
|
||||||
|
|
||||||
static access_t read()
|
|
||||||
{
|
|
||||||
access_t v;
|
|
||||||
asm volatile ("mrc p15, 0, %0, c2, c0, 0" : "=r" (v) :: );
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return initialized value
|
|
||||||
*
|
|
||||||
* \param table base of targeted translation table
|
|
||||||
*/
|
|
||||||
static access_t init(addr_t const table)
|
|
||||||
{
|
|
||||||
access_t v = Ba::masked((addr_t)table);
|
|
||||||
Rgn::set(v, CACHEABLE);
|
|
||||||
S::set(v, Board::SMP ? 1 : 0);
|
|
||||||
if (Board::SMP) Irgn::set(v, CACHEABLE);
|
|
||||||
else C::set(v, 1);
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Domain access control register
|
* Assign protection domain
|
||||||
*/
|
*/
|
||||||
struct Dacr : Register<32>
|
void protection_domain(Genode::uint8_t const id) { cidr = id; }
|
||||||
{
|
};
|
||||||
struct D0 : Bitfield<0,2> { }; /* access mode for domain 0 */
|
|
||||||
|
|
||||||
static void write(access_t const v) {
|
/**
|
||||||
asm volatile ("mcr p15, 0, %0, c3, c0, 0" :: "r" (v) : ); }
|
* This class comprises ARM specific protection domain attributes
|
||||||
|
*/
|
||||||
|
struct Pd
|
||||||
|
{
|
||||||
|
Genode::uint8_t asid; /* address space id */
|
||||||
|
|
||||||
/**
|
Pd(Genode::uint8_t id) : asid(id) {}
|
||||||
* Return value initialized for virtual mode in kernel
|
};
|
||||||
*/
|
|
||||||
static access_t init_virt_kernel() { return D0::bits(1); }
|
/**
|
||||||
};
|
* An usermode execution state
|
||||||
|
*/
|
||||||
|
struct User_context : Context
|
||||||
|
{
|
||||||
|
User_context();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instruction Cache Invalidate by MVA to PoU
|
* Support for kernel calls
|
||||||
*/
|
*/
|
||||||
struct Icimvau : Register<32>
|
void user_arg_0(unsigned const arg) { r0 = arg; }
|
||||||
{
|
void user_arg_1(unsigned const arg) { r1 = arg; }
|
||||||
static void write(access_t const v) {
|
void user_arg_2(unsigned const arg) { r2 = arg; }
|
||||||
asm volatile ("mcr p15, 0, %0, c7, c5, 1" :: "r" (v) : ); }
|
void user_arg_3(unsigned const arg) { r3 = arg; }
|
||||||
};
|
void user_arg_4(unsigned const arg) { r4 = arg; }
|
||||||
|
void user_arg_5(unsigned const arg) { r5 = arg; }
|
||||||
|
void user_arg_6(unsigned const arg) { r6 = arg; }
|
||||||
|
void user_arg_7(unsigned const arg) { r7 = arg; }
|
||||||
|
unsigned user_arg_0() const { return r0; }
|
||||||
|
unsigned user_arg_1() const { return r1; }
|
||||||
|
unsigned user_arg_2() const { return r2; }
|
||||||
|
unsigned user_arg_3() const { return r3; }
|
||||||
|
unsigned user_arg_4() const { return r4; }
|
||||||
|
unsigned user_arg_5() const { return r5; }
|
||||||
|
unsigned user_arg_6() const { return r6; }
|
||||||
|
unsigned user_arg_7() const { return r7; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Data Cache Clean and Invalidate by MVA to PoC
|
* Initialize thread context
|
||||||
|
*
|
||||||
|
* \param table physical base of appropriate translation table
|
||||||
|
* \param pd_id kernel name of appropriate protection domain
|
||||||
*/
|
*/
|
||||||
struct Dccimvac : Register<32>
|
void init_thread(addr_t const table, unsigned const pd_id)
|
||||||
{
|
{
|
||||||
static void write(access_t const v) {
|
protection_domain(pd_id);
|
||||||
asm volatile ("mcr p15, 0, %0, c7, c14, 1" :: "r" (v) : ); }
|
translation_table(table);
|
||||||
};
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Context identification register
|
* Return if the context is in a page fault due to translation miss
|
||||||
|
*
|
||||||
|
* \param va holds the virtual fault-address if call returns 1
|
||||||
|
* \param w holds wether it's a write fault if call returns 1
|
||||||
*/
|
*/
|
||||||
struct Cidr : Register<32>
|
bool in_fault(addr_t & va, addr_t & w) const
|
||||||
{
|
{
|
||||||
static void write(access_t const v) {
|
static constexpr Fsr::access_t section = 5;
|
||||||
asm volatile ("mcr p15, 0, %0, c13, c0, 1" :: "r" (v) : ); }
|
static constexpr Fsr::access_t page = 7;
|
||||||
|
|
||||||
static access_t read()
|
switch (cpu_exception) {
|
||||||
{
|
|
||||||
access_t v;
|
|
||||||
asm volatile ("mrc p15, 0, %0, c13, c0, 1" : "=r" (v) :: );
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
case PREFETCH_ABORT:
|
||||||
* Program status register
|
{
|
||||||
*/
|
/* check if fault was caused by a translation miss */
|
||||||
struct Psr : Register<32>
|
Ifsr::access_t const fs = Fsr::Fs::get(Ifsr::read());
|
||||||
{
|
if (fs != section && fs != page)
|
||||||
/**
|
return false;
|
||||||
* CPU mode
|
|
||||||
*/
|
/* fetch fault data */
|
||||||
struct M : Bitfield<0,5>
|
w = 0;
|
||||||
{
|
va = ip;
|
||||||
enum {
|
return true;
|
||||||
USR = 16,
|
}
|
||||||
SVC = 19,
|
case DATA_ABORT:
|
||||||
MON = 22,
|
{
|
||||||
HYP = 26,
|
/* check if fault was caused by translation miss */
|
||||||
};
|
Dfsr::access_t const fs = Fsr::Fs::get(Dfsr::read());
|
||||||
|
if (fs != section && fs != page)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/* fetch fault data */
|
||||||
|
Dfsr::access_t const dfsr = Dfsr::read();
|
||||||
|
w = Dfsr::Wnr::get(dfsr);
|
||||||
|
va = Dfar::read();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct F : Bitfield<6,1> { }; /* FIQ disable */
|
|
||||||
struct I : Bitfield<7,1> { }; /* IRQ disable */
|
|
||||||
struct A : Bitfield<8,1> { }; /* async. abort disable */
|
|
||||||
|
|
||||||
static access_t read()
|
|
||||||
{
|
|
||||||
access_t v;
|
|
||||||
asm volatile ("mrs %0, cpsr" : "=r" (v) :: );
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void write(access_t const v) {
|
|
||||||
asm volatile ("msr cpsr, %0" :: "r" (v) : ); }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return value initialized for user execution with trustzone
|
|
||||||
*/
|
|
||||||
static access_t init_user_with_trustzone();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Do common initialization on register value 'v'
|
|
||||||
*/
|
|
||||||
static void init_common(access_t & v)
|
|
||||||
{
|
|
||||||
F::set(v, 1);
|
|
||||||
A::set(v, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return initial value for user execution
|
|
||||||
*/
|
|
||||||
static access_t init_user()
|
|
||||||
{
|
|
||||||
access_t v = 0;
|
|
||||||
init_common(v);
|
|
||||||
M::set(v, M::USR);
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return initial value for the kernel
|
|
||||||
*/
|
|
||||||
static access_t init_kernel()
|
|
||||||
{
|
|
||||||
access_t v = 0;
|
|
||||||
init_common(v);
|
|
||||||
M::set(v, M::SVC);
|
|
||||||
I::set(v, 1);
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Common parts of fault status registers
|
|
||||||
*/
|
|
||||||
struct Fsr : Register<32>
|
|
||||||
{
|
|
||||||
static constexpr access_t section = 5;
|
|
||||||
static constexpr access_t page = 7;
|
|
||||||
|
|
||||||
struct Fs_0 : Bitfield<0, 4> { }; /* fault status */
|
|
||||||
struct Fs_1 : Bitfield<10, 1> { }; /* fault status */
|
|
||||||
struct Fs : Bitset_2<Fs_0, Fs_1> { }; /* fault status */
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Instruction fault status register
|
|
||||||
*/
|
|
||||||
struct Ifsr : Fsr
|
|
||||||
{
|
|
||||||
static access_t read()
|
|
||||||
{
|
|
||||||
access_t v;
|
|
||||||
asm volatile ("mrc p15, 0, %0, c5, c0, 1" : "=r" (v) :: );
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Data fault status register
|
|
||||||
*/
|
|
||||||
struct Dfsr : Fsr
|
|
||||||
{
|
|
||||||
struct Wnr : Bitfield<11, 1> { }; /* write not read bit */
|
|
||||||
|
|
||||||
static access_t read()
|
|
||||||
{
|
|
||||||
access_t v;
|
|
||||||
asm volatile ("mrc p15, 0, %0, c5, c0, 0" : "=r" (v) :: );
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Data fault address register
|
|
||||||
*/
|
|
||||||
struct Dfar : Register<32>
|
|
||||||
{
|
|
||||||
static access_t read()
|
|
||||||
{
|
|
||||||
access_t v;
|
|
||||||
asm volatile ("mrc p15, 0, %[v], c6, c0, 0" : [v]"=r"(v) :: );
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Extend basic CPU state by members relevant for 'base-hw' only
|
|
||||||
*/
|
|
||||||
struct Context : Cpu_state
|
|
||||||
{
|
|
||||||
Cidr::access_t cidr;
|
|
||||||
Ttbr0::access_t ttbr0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return base of assigned translation table
|
|
||||||
*/
|
|
||||||
addr_t translation_table() const {
|
|
||||||
return Ttbr0::Ba::masked(ttbr0); }
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Assign translation-table base 'table'
|
|
||||||
*/
|
|
||||||
void translation_table(addr_t const table) {
|
|
||||||
ttbr0 = Arm::Ttbr0::init(table); }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Assign protection domain
|
|
||||||
*/
|
|
||||||
void protection_domain(Genode::uint8_t const id) { cidr = id; }
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class comprises ARM specific protection domain attributes
|
|
||||||
*/
|
|
||||||
struct Pd
|
|
||||||
{
|
|
||||||
Genode::uint8_t asid; /* address space id */
|
|
||||||
|
|
||||||
Pd(Genode::uint8_t id) : asid(id) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An usermode execution state
|
|
||||||
*/
|
|
||||||
struct User_context : Context
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Constructor
|
|
||||||
*/
|
|
||||||
User_context();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Support for kernel calls
|
|
||||||
*/
|
|
||||||
void user_arg_0(unsigned const arg) { r0 = arg; }
|
|
||||||
void user_arg_1(unsigned const arg) { r1 = arg; }
|
|
||||||
void user_arg_2(unsigned const arg) { r2 = arg; }
|
|
||||||
void user_arg_3(unsigned const arg) { r3 = arg; }
|
|
||||||
void user_arg_4(unsigned const arg) { r4 = arg; }
|
|
||||||
void user_arg_5(unsigned const arg) { r5 = arg; }
|
|
||||||
void user_arg_6(unsigned const arg) { r6 = arg; }
|
|
||||||
void user_arg_7(unsigned const arg) { r7 = arg; }
|
|
||||||
unsigned user_arg_0() const { return r0; }
|
|
||||||
unsigned user_arg_1() const { return r1; }
|
|
||||||
unsigned user_arg_2() const { return r2; }
|
|
||||||
unsigned user_arg_3() const { return r3; }
|
|
||||||
unsigned user_arg_4() const { return r4; }
|
|
||||||
unsigned user_arg_5() const { return r5; }
|
|
||||||
unsigned user_arg_6() const { return r6; }
|
|
||||||
unsigned user_arg_7() const { return r7; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize thread context
|
|
||||||
*
|
|
||||||
* \param table physical base of appropriate translation table
|
|
||||||
* \param pd_id kernel name of appropriate protection domain
|
|
||||||
*/
|
|
||||||
void init_thread(addr_t const table, unsigned const pd_id)
|
|
||||||
{
|
|
||||||
protection_domain(pd_id);
|
|
||||||
translation_table(table);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return if the context is in a page fault due to translation miss
|
|
||||||
*
|
|
||||||
* \param va holds the virtual fault-address if call returns 1
|
|
||||||
* \param w holds wether it's a write fault if call returns 1
|
|
||||||
*/
|
|
||||||
bool in_fault(addr_t & va, addr_t & w) const
|
|
||||||
{
|
|
||||||
switch (cpu_exception) {
|
|
||||||
|
|
||||||
case PREFETCH_ABORT:
|
|
||||||
{
|
|
||||||
/* check if fault was caused by a translation miss */
|
|
||||||
Ifsr::access_t const fs = Ifsr::Fs::get(Ifsr::read());
|
|
||||||
if (fs != Ifsr::section && fs != Ifsr::page)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
/* fetch fault data */
|
|
||||||
w = 0;
|
|
||||||
va = ip;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
case DATA_ABORT:
|
|
||||||
{
|
|
||||||
/* check if fault was caused by translation miss */
|
|
||||||
Dfsr::access_t const fs = Dfsr::Fs::get(Dfsr::read());
|
|
||||||
if (fs != Dfsr::section && fs != Dfsr::page)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
/* fetch fault data */
|
|
||||||
Dfsr::access_t const dfsr = Dfsr::read();
|
|
||||||
w = Dfsr::Wnr::get(dfsr);
|
|
||||||
va = Dfar::read();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if current execution context is running in user mode
|
|
||||||
*/
|
|
||||||
static bool is_user() { return Psr::M::get(Psr::read()) == Psr::M::USR; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Invalidate all entries of all instruction caches
|
|
||||||
*/
|
|
||||||
static void invalidate_instr_cache() {
|
|
||||||
asm volatile ("mcr p15, 0, %0, c7, c5, 0" :: "r" (0) : ); }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Flush all entries of all data caches
|
|
||||||
*/
|
|
||||||
static void clean_invalidate_data_cache();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Invalidate all branch predictions
|
|
||||||
*/
|
|
||||||
static void invalidate_branch_predicts() {
|
|
||||||
asm volatile ("mcr p15, 0, r0, c7, c5, 6" ::: "r0"); };
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Invalidate all TLB entries of the address space named 'pid'
|
|
||||||
*/
|
|
||||||
void invalidate_tlb_by_pid(unsigned const pid) {
|
|
||||||
asm volatile ("mcr p15, 0, %0, c8, c7, 2" :: "r" (pid) : ); }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Invalidate all TLB entries
|
|
||||||
*/
|
|
||||||
static void invalidate_tlb() {
|
|
||||||
asm volatile ("mcr p15, 0, %0, c8, c7, 0" :: "r" (0) : ); }
|
|
||||||
|
|
||||||
static constexpr addr_t line_size = 1 << Board::CACHE_LINE_SIZE_LOG2;
|
|
||||||
static constexpr addr_t line_align_mask = ~(line_size - 1);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Clean and invalidate data-cache for virtual region
|
|
||||||
* 'base' - 'base + size'
|
|
||||||
*/
|
|
||||||
void clean_invalidate_data_cache_by_virt_region(addr_t base,
|
|
||||||
size_t const size)
|
|
||||||
{
|
|
||||||
addr_t const top = base + size;
|
|
||||||
base &= line_align_mask;
|
|
||||||
for (; base < top; base += line_size) { Dccimvac::write(base); }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
};
|
||||||
* Invalidate instruction-cache for virtual region
|
|
||||||
* 'base' - 'base + size'
|
/**
|
||||||
*/
|
* Returns true if current execution context is running in user mode
|
||||||
void invalidate_instr_cache_by_virt_region(addr_t base,
|
*/
|
||||||
size_t const size)
|
static bool is_user() { return Psr::M::get(Cpsr::read()) == Psr::M::USR; }
|
||||||
{
|
|
||||||
addr_t const top = base + size;
|
/**
|
||||||
base &= line_align_mask;
|
* Invalidate all entries of all instruction caches
|
||||||
for (; base < top; base += line_size) { Icimvau::write(base); }
|
*/
|
||||||
}
|
static void invalidate_instr_cache() {
|
||||||
|
asm volatile ("mcr p15, 0, %0, c7, c5, 0" :: "r" (0) : ); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flush all entries of all data caches
|
||||||
|
*/
|
||||||
|
static void clean_invalidate_data_cache();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invalidate all branch predictions
|
||||||
|
*/
|
||||||
|
static void invalidate_branch_predicts() {
|
||||||
|
asm volatile ("mcr p15, 0, r0, c7, c5, 6" ::: "r0"); };
|
||||||
|
|
||||||
|
static constexpr addr_t line_size = 1 << Board::CACHE_LINE_SIZE_LOG2;
|
||||||
|
static constexpr addr_t line_align_mask = ~(line_size - 1);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clean and invalidate data-cache for virtual region
|
||||||
|
* 'base' - 'base + size'
|
||||||
|
*/
|
||||||
|
void clean_invalidate_data_cache_by_virt_region(addr_t base,
|
||||||
|
size_t const size)
|
||||||
|
{
|
||||||
|
addr_t const top = base + size;
|
||||||
|
base &= line_align_mask;
|
||||||
|
for (; base < top; base += line_size) { Dccimvac::write(base); }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invalidate instruction-cache for virtual region
|
||||||
|
* 'base' - 'base + size'
|
||||||
|
*/
|
||||||
|
void invalidate_instr_cache_by_virt_region(addr_t base,
|
||||||
|
size_t const size)
|
||||||
|
{
|
||||||
|
addr_t const top = base + size;
|
||||||
|
base &= line_align_mask;
|
||||||
|
for (; base < top; base += line_size) { Icimvau::write(base); }
|
||||||
|
}
|
||||||
|
|
||||||
|
static void wait_for_interrupt();
|
||||||
|
|
||||||
|
|
||||||
/*************
|
/*************
|
||||||
** Dummies **
|
** Dummies **
|
||||||
*************/
|
*************/
|
||||||
|
|
||||||
void switch_to(User_context&) { }
|
void switch_to(User_context&) { }
|
||||||
bool retry_undefined_instr(Context&) { return false; }
|
bool retry_undefined_instr(Context&) { return false; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return kernel name of the executing CPU
|
* Return kernel name of the executing CPU
|
||||||
*/
|
*/
|
||||||
static unsigned executing_id() { return 0; }
|
static unsigned executing_id() { return 0; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return kernel name of the primary CPU
|
* Return kernel name of the primary CPU
|
||||||
*/
|
*/
|
||||||
static unsigned primary_id() { return 0; }
|
static unsigned primary_id() { return 0; }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* _CORE__SPEC__ARM__CPU_SUPPORT_H_ */
|
#endif /* _CORE__SPEC__ARM__CPU_H_ */
|
||||||
|
@ -28,5 +28,8 @@ void Kernel::Cpu::init(Kernel::Pic &pic)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Kernel::Cpu_domain_update::_domain_update() {
|
void Kernel::Cpu_domain_update::_domain_update()
|
||||||
cpu_pool()->cpu(Cpu::executing_id())->invalidate_tlb_by_pid(_domain_id); }
|
{
|
||||||
|
/* flush TLB by ASID */
|
||||||
|
Cpu::Tlbiasid::write(_domain_id);
|
||||||
|
}
|
||||||
|
@ -43,7 +43,7 @@ Kernel::Pd::~Pd() {
|
|||||||
Cpu * const cpu = cpu_pool()->cpu(Cpu::executing_id());
|
Cpu * const cpu = cpu_pool()->cpu(Cpu::executing_id());
|
||||||
cpu->clean_invalidate_data_cache();
|
cpu->clean_invalidate_data_cache();
|
||||||
cpu->invalidate_instr_cache();
|
cpu->invalidate_instr_cache();
|
||||||
cpu->invalidate_tlb_by_pid(asid);
|
Cpu::Tlbiasid::write(asid); /* flush TLB by ASID */
|
||||||
alloc().free(asid);
|
alloc().free(asid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,5 +20,5 @@ void Kernel::Thread::_call_update_pd()
|
|||||||
Cpu * const cpu = cpu_pool()->cpu(Cpu::executing_id());
|
Cpu * const cpu = cpu_pool()->cpu(Cpu::executing_id());
|
||||||
cpu->invalidate_instr_cache();
|
cpu->invalidate_instr_cache();
|
||||||
cpu->clean_invalidate_data_cache();
|
cpu->clean_invalidate_data_cache();
|
||||||
cpu->invalidate_tlb_by_pid(pd->asid);
|
Cpu::Tlbiasid::write(pd->asid); /* flush TLB by ASID */
|
||||||
}
|
}
|
||||||
|
@ -25,5 +25,8 @@ Kernel::Lock & Kernel::data_lock() {
|
|||||||
return *unmanaged_singleton<Kernel::Lock>(); }
|
return *unmanaged_singleton<Kernel::Lock>(); }
|
||||||
|
|
||||||
|
|
||||||
void Kernel::Cpu_domain_update::_domain_update() {
|
void Kernel::Cpu_domain_update::_domain_update()
|
||||||
cpu_pool()->cpu(Cpu::executing_id())->invalidate_tlb_by_pid(_domain_id); }
|
{
|
||||||
|
/* flush TLB by ASID */
|
||||||
|
Cpu::Tlbiasid::write(_domain_id);
|
||||||
|
}
|
||||||
|
@ -13,7 +13,10 @@
|
|||||||
* under the terms of the GNU Affero General Public License version 3.
|
* under the terms of the GNU Affero General Public License version 3.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <cpu.h>
|
#include <spec/arm/cpu_support.h>
|
||||||
|
|
||||||
void Genode::Arm::clean_invalidate_data_cache() {
|
void Genode::Arm_cpu::clean_invalidate_data_cache() {
|
||||||
asm volatile ("mcr p15, 0, %[rd], c7, c14, 0" :: [rd]"r"(0) : ); }
|
asm volatile ("mcr p15, 0, %[rd], c7, c14, 0" :: [rd]"r"(0) : ); }
|
||||||
|
|
||||||
|
|
||||||
|
void Genode::Arm_cpu::wait_for_interrupt() { /* FIXME */ }
|
||||||
|
@ -18,33 +18,6 @@
|
|||||||
/* core includes */
|
/* core includes */
|
||||||
#include <spec/arm/cpu_support.h>
|
#include <spec/arm/cpu_support.h>
|
||||||
|
|
||||||
namespace Genode { class Cpu; }
|
namespace Genode { using Cpu = Arm_cpu; }
|
||||||
|
|
||||||
|
|
||||||
class Genode::Cpu : public Arm
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Cache type register
|
|
||||||
*/
|
|
||||||
struct Ctr : Arm::Ctr
|
|
||||||
{
|
|
||||||
struct P : Bitfield<23, 1> { }; /* page mapping restriction on */
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If page descriptor bits [13:12] are restricted
|
|
||||||
*/
|
|
||||||
static bool restricted_page_mappings() {
|
|
||||||
return Ctr::P::get(Ctr::read()); }
|
|
||||||
|
|
||||||
|
|
||||||
/*************
|
|
||||||
** Dummies **
|
|
||||||
*************/
|
|
||||||
|
|
||||||
static void wait_for_interrupt() { /* FIXME */ }
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* _CORE__SPEC__ARM_V6__CPU_H_ */
|
#endif /* _CORE__SPEC__ARM_V6__CPU_H_ */
|
||||||
|
@ -16,10 +16,9 @@
|
|||||||
#define _CORE__SPEC__ARM_V6__TRANSLATION_TABLE_H_
|
#define _CORE__SPEC__ARM_V6__TRANSLATION_TABLE_H_
|
||||||
|
|
||||||
#include <hw/spec/arm/page_table.h>
|
#include <hw/spec/arm/page_table.h>
|
||||||
|
#include <spec/arm/cpu_support.h>
|
||||||
#include <kernel/interface.h>
|
#include <kernel/interface.h>
|
||||||
|
|
||||||
#include <cpu.h>
|
|
||||||
|
|
||||||
constexpr unsigned Hw::Page_table::Descriptor_base::_device_tex() {
|
constexpr unsigned Hw::Page_table::Descriptor_base::_device_tex() {
|
||||||
return 0; }
|
return 0; }
|
||||||
|
|
||||||
@ -27,8 +26,8 @@ constexpr bool Hw::Page_table::Descriptor_base::_smp() { return false; }
|
|||||||
|
|
||||||
void Hw::Page_table::_translation_added(unsigned long addr, unsigned long size)
|
void Hw::Page_table::_translation_added(unsigned long addr, unsigned long size)
|
||||||
{
|
{
|
||||||
if (Genode::Cpu::is_user()) Kernel::update_data_region(addr, size);
|
if (Genode::Arm_cpu::is_user()) Kernel::update_data_region(addr, size);
|
||||||
else Genode::Cpu::clean_invalidate_data_cache();
|
else Genode::Arm_cpu::clean_invalidate_data_cache();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* _CORE__SPEC__ARM_V6__TRANSLATION_TABLE_H_ */
|
#endif /* _CORE__SPEC__ARM_V6__TRANSLATION_TABLE_H_ */
|
||||||
|
@ -128,7 +128,7 @@
|
|||||||
::: "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9"
|
::: "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9"
|
||||||
|
|
||||||
|
|
||||||
void Genode::Arm_v7::invalidate_inner_data_cache()
|
void Genode::Arm_v7_cpu::invalidate_inner_data_cache()
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Data Cache Invalidate by Set/Way for all Set/Way
|
* Data Cache Invalidate by Set/Way for all Set/Way
|
||||||
@ -139,7 +139,7 @@ void Genode::Arm_v7::invalidate_inner_data_cache()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Genode::Arm_v7::clean_invalidate_inner_data_cache()
|
void Genode::Arm_v7_cpu::clean_invalidate_inner_data_cache()
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Data Cache Clean by Set/Way for all Set/Way
|
* Data Cache Clean by Set/Way for all Set/Way
|
||||||
@ -148,13 +148,3 @@ void Genode::Arm_v7::clean_invalidate_inner_data_cache()
|
|||||||
WRITE_DCCSW(r6)
|
WRITE_DCCSW(r6)
|
||||||
FOR_ALL_SET_WAY_IN_R6_1);
|
FOR_ALL_SET_WAY_IN_R6_1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Genode::Arm::Psr::access_t Genode::Arm::Psr::init_user_with_trustzone()
|
|
||||||
{
|
|
||||||
access_t v = 0;
|
|
||||||
M::set(v, M::USR);
|
|
||||||
I::set(v, 1);
|
|
||||||
A::set(v, 1);
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
@ -16,136 +16,26 @@
|
|||||||
|
|
||||||
/* core includes */
|
/* core includes */
|
||||||
#include <spec/arm/cpu_support.h>
|
#include <spec/arm/cpu_support.h>
|
||||||
#include <board.h>
|
|
||||||
#include <pic.h>
|
|
||||||
|
|
||||||
namespace Genode
|
namespace Genode { struct Arm_v7_cpu; }
|
||||||
|
|
||||||
|
|
||||||
|
struct Genode::Arm_v7_cpu : Arm_cpu
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* CPU driver for core
|
* Wait for the next interrupt as cheap as possible
|
||||||
*/
|
*/
|
||||||
class Arm_v7;
|
static void wait_for_interrupt() { asm volatile ("wfi"); }
|
||||||
}
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write back dirty lines of inner data cache and invalidate all
|
||||||
|
*/
|
||||||
|
static void clean_invalidate_inner_data_cache();
|
||||||
|
|
||||||
class Genode::Arm_v7 : public Arm
|
/**
|
||||||
{
|
* Invalidate all lines of the inner data cache
|
||||||
public:
|
*/
|
||||||
|
static void invalidate_inner_data_cache();
|
||||||
/**
|
|
||||||
* 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));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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) : ); }
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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
|
|
||||||
*/
|
|
||||||
static void clean_invalidate_inner_data_cache();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Invalidate all lines of the inner data cache
|
|
||||||
*/
|
|
||||||
static 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 /* _CORE__SPEC__ARM_V7__CPU_SUPPORT_H_ */
|
#endif /* _CORE__SPEC__ARM_V7__CPU_SUPPORT_H_ */
|
||||||
|
@ -21,62 +21,17 @@
|
|||||||
namespace Genode { class Cpu; }
|
namespace Genode { class Cpu; }
|
||||||
|
|
||||||
|
|
||||||
class Genode::Cpu : public Arm_v7
|
class Genode::Cpu : public Arm_v7_cpu
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
struct Sctlr : Register<32>
|
|
||||||
{
|
|
||||||
static access_t read()
|
|
||||||
{
|
|
||||||
access_t v;
|
|
||||||
asm volatile ("mcr p15, 0, %[v], c1, c0, 0" : [v] "=r" (v));
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
struct Ttbcr : Register<32>
|
|
||||||
{
|
|
||||||
static access_t read()
|
|
||||||
{
|
|
||||||
access_t v;
|
|
||||||
asm volatile ("mcr p15, 0, %[v], c2, c0, 2" : [v] "=r" (v));
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
struct Mair0 : Register<32>
|
|
||||||
{
|
|
||||||
static access_t read()
|
|
||||||
{
|
|
||||||
access_t v;
|
|
||||||
asm volatile ("mcr p15, 0, %[v], c10, c2, 0" : [v] "=r" (v));
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Translation table base register 0 (64-bit format)
|
* Translation table base register 0 (64-bit format)
|
||||||
*/
|
*/
|
||||||
struct Ttbr0 : Register<64>
|
struct Ttbr0 : Ttbr0_64bit
|
||||||
{
|
{
|
||||||
enum Memory_region { NON_CACHEABLE = 0, CACHEABLE = 1 };
|
enum Memory_region { NON_CACHEABLE = 0, CACHEABLE = 1 };
|
||||||
|
|
||||||
struct Ba : Bitfield<5, 34> { }; /* translation table base */
|
|
||||||
struct Asid : Bitfield<48,8> { };
|
|
||||||
|
|
||||||
static void write(access_t const v)
|
|
||||||
{
|
|
||||||
asm volatile ("mcrr p15, 0, %[v0], %[v1], c2"
|
|
||||||
:: [v0]"r"(v), [v1]"r"(v >> 32) : );
|
|
||||||
}
|
|
||||||
|
|
||||||
static access_t read()
|
|
||||||
{
|
|
||||||
uint32_t v0, v1;
|
|
||||||
asm volatile ("mrrc p15, 0, %[v0], %[v1], c2"
|
|
||||||
: [v0]"=r"(v0), [v1]"=r"(v1) :: );
|
|
||||||
return (access_t) v0 | ((access_t)v1 << 32);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return initialized value
|
* Return initialized value
|
||||||
*
|
*
|
||||||
@ -84,8 +39,8 @@ class Genode::Cpu : public Arm_v7
|
|||||||
*/
|
*/
|
||||||
static access_t init(addr_t const table, unsigned const id)
|
static access_t init(addr_t const table, unsigned const id)
|
||||||
{
|
{
|
||||||
access_t v = Ba::masked((access_t)table);
|
access_t v = Ttbr_64bit::Ba::masked((access_t)table);
|
||||||
Asid::set(v, id);
|
Ttbr_64bit::Asid::set(v, id);
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -176,19 +131,19 @@ class Genode::Cpu : public Arm_v7
|
|||||||
* Return base of assigned translation table
|
* Return base of assigned translation table
|
||||||
*/
|
*/
|
||||||
addr_t translation_table() const {
|
addr_t translation_table() const {
|
||||||
return Ttbr0::Ba::masked(ttbr0); }
|
return Ttbr_64bit::Ba::masked(ttbr0); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Assign translation-table base 'table'
|
* Assign translation-table base 'table'
|
||||||
*/
|
*/
|
||||||
void translation_table(addr_t const table) {
|
void translation_table(addr_t const table) {
|
||||||
Ttbr0::Ba::set(ttbr0, (Ttbr0::access_t)(table >> 5)); }
|
Ttbr_64bit::Ba::set(ttbr0, (Ttbr_64bit::access_t)(table >> 5)); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Assign protection domain
|
* Assign protection domain
|
||||||
*/
|
*/
|
||||||
void protection_domain(Genode::uint8_t const id) {
|
void protection_domain(Genode::uint8_t const id) {
|
||||||
Ttbr0::Asid::set(ttbr0, id); }
|
Ttbr_64bit::Asid::set(ttbr0, id); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -199,10 +154,14 @@ class Genode::Cpu : public Arm_v7
|
|||||||
*/
|
*/
|
||||||
struct User_context : Context
|
struct User_context : Context
|
||||||
{
|
{
|
||||||
/**
|
User_context()
|
||||||
* Constructor
|
{
|
||||||
*/
|
Psr::access_t v = 0;
|
||||||
User_context() { cpsr = Psr::init_user(); }
|
Psr::M::set(v, Psr::M::USR);
|
||||||
|
Psr::F::set(v, 1);
|
||||||
|
Psr::A::set(v, 1);
|
||||||
|
cpsr = v;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Support for kernel calls
|
* Support for kernel calls
|
||||||
@ -249,7 +208,7 @@ class Genode::Cpu : public Arm_v7
|
|||||||
case PREFETCH_ABORT:
|
case PREFETCH_ABORT:
|
||||||
{
|
{
|
||||||
/* check if fault was caused by a translation miss */
|
/* check if fault was caused by a translation miss */
|
||||||
Ifsr::access_t const fs = Ifsr::Fs::get(Ifsr::read());
|
Fsr::access_t const fs = Fsr::Fs::get(Ifsr::read());
|
||||||
if ((fs & 0b11100) != 0b100) return false;
|
if ((fs & 0b11100) != 0b100) return false;
|
||||||
|
|
||||||
/* fetch fault data */
|
/* fetch fault data */
|
||||||
@ -261,7 +220,7 @@ class Genode::Cpu : public Arm_v7
|
|||||||
case DATA_ABORT:
|
case DATA_ABORT:
|
||||||
{
|
{
|
||||||
/* check if fault was caused by translation miss */
|
/* check if fault was caused by translation miss */
|
||||||
Dfsr::access_t const fs = Dfsr::Fs::get(Dfsr::read());
|
Fsr::access_t const fs = Fsr::Fs::get(Dfsr::read());
|
||||||
if ((fs & 0b11100) != 0b100) return false;
|
if ((fs & 0b11100) != 0b100) return false;
|
||||||
|
|
||||||
/* fetch fault data */
|
/* fetch fault data */
|
||||||
|
@ -18,32 +18,30 @@
|
|||||||
/* core includes */
|
/* core includes */
|
||||||
#include <spec/arm_v7/cpu_support.h>
|
#include <spec/arm_v7/cpu_support.h>
|
||||||
|
|
||||||
namespace Genode { class Cpu; }
|
namespace Genode { struct Cpu; }
|
||||||
|
|
||||||
|
|
||||||
class Genode::Cpu : public Arm_v7
|
struct Genode::Cpu : Arm_v7_cpu
|
||||||
{
|
{
|
||||||
public:
|
/**
|
||||||
|
* Write back dirty cache lines and invalidate the whole cache
|
||||||
|
*/
|
||||||
|
static void clean_invalidate_data_cache() {
|
||||||
|
clean_invalidate_inner_data_cache(); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write back dirty cache lines and invalidate the whole cache
|
* Invalidate all cache lines
|
||||||
*/
|
*/
|
||||||
static void clean_invalidate_data_cache() {
|
static void invalidate_data_cache() {
|
||||||
clean_invalidate_inner_data_cache(); }
|
invalidate_inner_data_cache(); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invalidate all cache lines
|
* Post processing after a translation was added to a translation table
|
||||||
*/
|
*
|
||||||
static void invalidate_data_cache() {
|
* \param addr virtual address of the translation
|
||||||
invalidate_inner_data_cache(); }
|
* \param size size of the translation
|
||||||
|
*/
|
||||||
/**
|
static void translation_added(addr_t const addr, size_t const size);
|
||||||
* Post processing after a translation was added to a translation table
|
|
||||||
*
|
|
||||||
* \param addr virtual address of the translation
|
|
||||||
* \param size size of the translation
|
|
||||||
*/
|
|
||||||
static void translation_added(addr_t const addr, size_t const size);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* _CORE__SPEC__CORTEX_A8__CPU_H_ */
|
#endif /* _CORE__SPEC__CORTEX_A8__CPU_H_ */
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
namespace Genode { class Cpu; }
|
namespace Genode { class Cpu; }
|
||||||
|
|
||||||
class Genode::Cpu : public Arm_v7
|
class Genode::Cpu : public Arm_v7_cpu
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
@ -57,7 +57,7 @@ class Genode::Cpu : public Arm_v7
|
|||||||
asm volatile ("mcr p15, 0, %[v], c1, c0, 2" :: [v]"r"(v) :); }
|
asm volatile ("mcr p15, 0, %[v], c1, c0, 2" :: [v]"r"(v) :); }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct User_context : Arm::User_context, Fpu::Context { };
|
struct User_context : Arm_cpu::User_context, Fpu::Context { };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Next cpu context to switch to
|
* Next cpu context to switch to
|
||||||
@ -99,7 +99,7 @@ class Genode::Cpu : public Arm_v7
|
|||||||
void clean_invalidate_data_cache_by_virt_region(addr_t base,
|
void clean_invalidate_data_cache_by_virt_region(addr_t base,
|
||||||
size_t const size)
|
size_t const size)
|
||||||
{
|
{
|
||||||
Arm::clean_invalidate_data_cache_by_virt_region(base, size);
|
Arm_cpu::clean_invalidate_data_cache_by_virt_region(base, size);
|
||||||
Kernel::board().l2_cache().clean_invalidate();
|
Kernel::board().l2_cache().clean_invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,17 +0,0 @@
|
|||||||
/*
|
|
||||||
* \brief Specific core implementations
|
|
||||||
* \author Stefan Kalkowski
|
|
||||||
* \date 2012-10-24
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (C) 2012-2017 Genode Labs GmbH
|
|
||||||
*
|
|
||||||
* This file is part of the Genode OS framework, which is distributed
|
|
||||||
* under the terms of the GNU Affero General Public License version 3.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* core includes */
|
|
||||||
#include <cpu.h>
|
|
||||||
|
|
||||||
Genode::Cpu::User_context::User_context() { cpsr = Psr::init_user(); }
|
|
@ -1,19 +0,0 @@
|
|||||||
/*
|
|
||||||
* \brief Specific core implementations
|
|
||||||
* \author Stefan Kalkowski
|
|
||||||
* \date 2012-10-24
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (C) 2012-2017 Genode Labs GmbH
|
|
||||||
*
|
|
||||||
* This file is part of the Genode OS framework, which is distributed
|
|
||||||
* under the terms of the GNU Affero General Public License version 3.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* core includes */
|
|
||||||
#include <cpu.h>
|
|
||||||
|
|
||||||
using namespace Genode;
|
|
||||||
|
|
||||||
Cpu::User_context::User_context() { cpsr = Psr::init_user_with_trustzone(); }
|
|
@ -1,30 +0,0 @@
|
|||||||
/*
|
|
||||||
* \brief Configuration of the Driver for the Central Security Unit
|
|
||||||
* \author Martin Stein
|
|
||||||
* \date 2015-10-30
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (C) 2015-2017 Genode Labs GmbH
|
|
||||||
*
|
|
||||||
* This file is part of the Genode OS framework, which is distributed
|
|
||||||
* under the terms of the GNU Affero General Public License version 3.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _CORE__SPEC__IMX53_QSB__TRUSTZONE__CSU_CONFIG_H_
|
|
||||||
#define _CORE__SPEC__IMX53_QSB__TRUSTZONE__CSU_CONFIG_H_
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Configuration of the Driver for the Central Security Unit
|
|
||||||
*/
|
|
||||||
namespace Csu_config
|
|
||||||
{
|
|
||||||
enum {
|
|
||||||
SECURE_GPIO = 1,
|
|
||||||
SECURE_ESDHC = 0,
|
|
||||||
SECURE_UART = 0,
|
|
||||||
SECURE_I2C = 1,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* _CORE__SPEC__IMX53_QSB__TRUSTZONE__CSU_CONFIG_H_ */
|
|
@ -1,19 +0,0 @@
|
|||||||
/*
|
|
||||||
* \brief Specific core implementations
|
|
||||||
* \author Stefan Kalkowski
|
|
||||||
* \author Josef Soentgen
|
|
||||||
* \author Martin Stein
|
|
||||||
* \date 2014-02-25
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (C) 2014-2017 Genode Labs GmbH
|
|
||||||
*
|
|
||||||
* This file is part of the Genode OS framework, which is distributed
|
|
||||||
* under the terms of the GNU Affero General Public License version 3.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* core includes */
|
|
||||||
#include <cpu.h>
|
|
||||||
|
|
||||||
Genode::Arm::User_context::User_context() { cpsr = Psr::init_user(); }
|
|
@ -1,17 +0,0 @@
|
|||||||
/*
|
|
||||||
* \brief Platform implementations specific for base-hw and Panda A2
|
|
||||||
* \author Martin Stein
|
|
||||||
* \date 2012-04-27
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (C) 2012-2017 Genode Labs GmbH
|
|
||||||
*
|
|
||||||
* This file is part of the Genode OS framework, which is distributed
|
|
||||||
* under the terms of the GNU Affero General Public License version 3.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* core includes */
|
|
||||||
#include <cpu.h>
|
|
||||||
|
|
||||||
Genode::Arm::User_context::User_context() { cpsr = Psr::init_user(); }
|
|
@ -1,26 +0,0 @@
|
|||||||
/*
|
|
||||||
* \brief Parts of platform that are specific to PBXA9
|
|
||||||
* \author Martin Stein
|
|
||||||
* \date 2012-04-27
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (C) 2012-2017 Genode Labs GmbH
|
|
||||||
*
|
|
||||||
* This file is part of the Genode OS framework, which is distributed
|
|
||||||
* under the terms of the GNU Affero General Public License version 3.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* core includes */
|
|
||||||
#include <platform.h>
|
|
||||||
#include <board.h>
|
|
||||||
#include <cpu.h>
|
|
||||||
#include <pic.h>
|
|
||||||
|
|
||||||
/* base-internal includes */
|
|
||||||
#include <base/internal/unmanaged_singleton.h>
|
|
||||||
|
|
||||||
using namespace Genode;
|
|
||||||
|
|
||||||
|
|
||||||
Genode::Arm::User_context::User_context() { cpsr = Psr::init_user(); }
|
|
@ -1,19 +0,0 @@
|
|||||||
/*
|
|
||||||
* \brief Platform implementations specific for base-hw and Raspberry Pi
|
|
||||||
* \author Norman Feske
|
|
||||||
* \date 2013-04-05
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (C) 2013-2017 Genode Labs GmbH
|
|
||||||
*
|
|
||||||
* This file is part of the Genode OS framework, which is distributed
|
|
||||||
* under the terms of the GNU Affero General Public License version 3.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* core includes */
|
|
||||||
#include <cpu.h>
|
|
||||||
|
|
||||||
using namespace Genode;
|
|
||||||
|
|
||||||
Cpu::User_context::User_context() { cpsr = Psr::init_user(); }
|
|
@ -1,30 +0,0 @@
|
|||||||
/*
|
|
||||||
* \brief Configuration of the Driver for the Central Security Unit
|
|
||||||
* \author Martin Stein
|
|
||||||
* \date 2015-10-30
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (C) 2015-2017 Genode Labs GmbH
|
|
||||||
*
|
|
||||||
* This file is part of the Genode OS framework, which is distributed
|
|
||||||
* under the terms of the GNU Affero General Public License version 3.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _CORE__SPEC__USB_ARMORY__CSU_CONFIG_H_
|
|
||||||
#define _CORE__SPEC__USB_ARMORY__CSU_CONFIG_H_
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Configuration of the Driver for the Central Security Unit
|
|
||||||
*/
|
|
||||||
namespace Csu_config
|
|
||||||
{
|
|
||||||
enum {
|
|
||||||
SECURE_GPIO = 0,
|
|
||||||
SECURE_ESDHC = 1,
|
|
||||||
SECURE_UART = 1,
|
|
||||||
SECURE_I2C = 0,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* _CORE__SPEC__USB_ARMORY__CSU_CONFIG_H_ */
|
|
@ -1,18 +0,0 @@
|
|||||||
/*
|
|
||||||
* \brief Platform implementations specific for base-hw and Zynq
|
|
||||||
* \author Johannes Schlatow
|
|
||||||
* \author Stefan Kalkowski
|
|
||||||
* \date 2014-12-15
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (C) 2014-2017 Genode Labs GmbH
|
|
||||||
*
|
|
||||||
* This file is part of the Genode OS framework, which is distributed
|
|
||||||
* under the terms of the GNU Affero General Public License version 3.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* core includes */
|
|
||||||
#include <cpu.h>
|
|
||||||
|
|
||||||
Genode::Arm::User_context::User_context() { cpsr = Psr::init_user(); }
|
|
@ -31,7 +31,9 @@ struct Hw::Arm_cpu
|
|||||||
ARM_CP15_REGISTER_32BIT(Ctr, c0, c0, 0, 1);
|
ARM_CP15_REGISTER_32BIT(Ctr, c0, c0, 0, 1);
|
||||||
|
|
||||||
/* Multiprocessor Affinity Register */
|
/* Multiprocessor Affinity Register */
|
||||||
ARM_CP15_REGISTER_32BIT(Mpidr, c0, c0, 0, 5);
|
ARM_CP15_REGISTER_32BIT(Mpidr, c0, c0, 0, 5,
|
||||||
|
struct Aff_0 : Bitfield<0, 8> { }; /* affinity value 0 */
|
||||||
|
);
|
||||||
|
|
||||||
/* System Control Register */
|
/* System Control Register */
|
||||||
ARM_CP15_REGISTER_32BIT(Sctlr, c1, c0, 0, 0,
|
ARM_CP15_REGISTER_32BIT(Sctlr, c1, c0, 0, 0,
|
||||||
@ -183,6 +185,9 @@ struct Hw::Arm_cpu
|
|||||||
/* Invalidate entire unified TLB */
|
/* Invalidate entire unified TLB */
|
||||||
ARM_CP15_REGISTER_32BIT(Tlbiall, c8, c7, 0, 0);
|
ARM_CP15_REGISTER_32BIT(Tlbiall, c8, c7, 0, 0);
|
||||||
|
|
||||||
|
/* Invalidate unified TLB by ASID */
|
||||||
|
ARM_CP15_REGISTER_32BIT(Tlbiasid, c8, c7, 0, 2);
|
||||||
|
|
||||||
/* Memory Attribute Indirection Register 0 */
|
/* Memory Attribute Indirection Register 0 */
|
||||||
ARM_CP15_REGISTER_32BIT(Mair0, c10, c2, 0, 0,
|
ARM_CP15_REGISTER_32BIT(Mair0, c10, c2, 0, 0,
|
||||||
struct Attr0 : Bitfield<0, 8> { };
|
struct Attr0 : Bitfield<0, 8> { };
|
||||||
|
Loading…
x
Reference in New Issue
Block a user