mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-08 11:55:24 +00:00
hw: LPAE for Cortex a15 (fix #1387)
This commit is contained in:
parent
21fd2fc582
commit
322be1b4fb
@ -8,7 +8,7 @@
|
||||
INC_DIR += $(REP_DIR)/src/core/include/spec/arm_v6
|
||||
|
||||
# add C++ sources
|
||||
SRC_CC += cpu.cc
|
||||
SRC_CC += spec/arm/cpu.cc
|
||||
|
||||
# add assembly sources
|
||||
SRC_S += spec/arm_v6/mode_transition.s
|
||||
|
11
repos/base-hw/lib/mk/cortex_a15/core.inc
Normal file
11
repos/base-hw/lib/mk/cortex_a15/core.inc
Normal file
@ -0,0 +1,11 @@
|
||||
#
|
||||
# \brief Build config for Genodes core process
|
||||
# \author Stefan Kalkowski
|
||||
# \date 2014-09-02
|
||||
#
|
||||
|
||||
# add include paths
|
||||
INC_DIR += $(REP_DIR)/src/core/include/spec/cortex_a15
|
||||
|
||||
# include less specific configuration
|
||||
include $(REP_DIR)/lib/mk/arm_v7/core.inc
|
14
repos/base-hw/lib/mk/cortex_a8/core.inc
Normal file
14
repos/base-hw/lib/mk/cortex_a8/core.inc
Normal file
@ -0,0 +1,14 @@
|
||||
#
|
||||
# \brief Build config for Genodes core process
|
||||
# \author Stefan Kalkowski
|
||||
# \date 2014-09-02
|
||||
#
|
||||
|
||||
# add include paths
|
||||
INC_DIR += $(REP_DIR)/src/core/include/spec/cortex_a8
|
||||
|
||||
# add C++ sources
|
||||
SRC_CC += spec/arm/cpu.cc
|
||||
|
||||
# include less specific configuration
|
||||
include $(REP_DIR)/lib/mk/arm_v7/core.inc
|
14
repos/base-hw/lib/mk/cortex_a9/core.inc
Normal file
14
repos/base-hw/lib/mk/cortex_a9/core.inc
Normal file
@ -0,0 +1,14 @@
|
||||
#
|
||||
# \brief Build config for Genodes core process
|
||||
# \author Stefan Kalkowski
|
||||
# \date 2014-09-02
|
||||
#
|
||||
|
||||
# add include paths
|
||||
INC_DIR += $(REP_DIR)/src/core/include/spec/cortex_a9
|
||||
|
||||
# add C++ sources
|
||||
SRC_CC += spec/arm/cpu.cc
|
||||
|
||||
# include less specific configuration
|
||||
include $(REP_DIR)/lib/mk/arm_v7/core.inc
|
@ -16,4 +16,4 @@ SRC_CC += platform_services.cc
|
||||
SRC_CC += spec/arm_gic/pic.cc
|
||||
|
||||
# include less specific configuration
|
||||
include $(REP_DIR)/lib/mk/arm_v7/core.inc
|
||||
include $(REP_DIR)/lib/mk/cortex_a15/core.inc
|
||||
|
@ -13,8 +13,5 @@ INC_DIR += $(REP_DIR)/src/core/include/spec/imx53
|
||||
INC_DIR += $(REP_DIR)/src/core/include/spec/imx
|
||||
INC_DIR += $(REP_DIR)/src/core/include/spec/cortex_a8
|
||||
|
||||
# add C++ sources
|
||||
SRC_CC += cpu.cc
|
||||
|
||||
# include less specific configuration
|
||||
include $(REP_DIR)/lib/mk/arm_v7/core.inc
|
||||
include $(REP_DIR)/lib/mk/cortex_a8/core.inc
|
||||
|
@ -15,7 +15,6 @@ SRC_CC += platform_services.cc
|
||||
SRC_CC += spec/panda/platform_support.cc
|
||||
SRC_CC += spec/cortex_a9/pic.cc
|
||||
SRC_CC += spec/arm_gic/pic.cc
|
||||
SRC_CC += cpu.cc
|
||||
|
||||
# include less specific configuration
|
||||
include $(REP_DIR)/lib/mk/arm_v7/core.inc
|
||||
include $(REP_DIR)/lib/mk/cortex_a9/core.inc
|
||||
|
@ -15,7 +15,6 @@ SRC_CC += platform_services.cc
|
||||
SRC_CC += spec/pbxa9/platform_support.cc
|
||||
SRC_CC += spec/cortex_a9/pic.cc
|
||||
SRC_CC += spec/arm_gic/pic.cc
|
||||
SRC_CC += cpu.cc
|
||||
|
||||
# include less specific configuration
|
||||
include $(REP_DIR)/lib/mk/arm_v7/core.inc
|
||||
include $(REP_DIR)/lib/mk/cortex_a9/core.inc
|
||||
|
@ -11,11 +11,10 @@ INC_DIR += $(REP_DIR)/src/core/include/spec/cortex_a9
|
||||
INC_DIR += $(REP_DIR)/src/core/include/spec/pl011
|
||||
|
||||
# add C++ sources
|
||||
SRC_CC += cpu.cc
|
||||
SRC_CC += platform_services.cc
|
||||
SRC_CC += spec/vea9x4/platform_support.cc
|
||||
SRC_CC += spec/cortex_a9/pic.cc
|
||||
SRC_CC += spec/arm_gic/pic.cc
|
||||
|
||||
# include less specific configuration
|
||||
include $(REP_DIR)/lib/mk/arm_v7/core.inc
|
||||
include $(REP_DIR)/lib/mk/cortex_a9/core.inc
|
||||
|
@ -1,21 +0,0 @@
|
||||
/*
|
||||
* \brief CPU driver for core
|
||||
* \author Martin stein
|
||||
* \date 2014-07-14
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2011-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.
|
||||
*/
|
||||
|
||||
/* core includes */
|
||||
#include <cpu.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
unsigned Cpu::primary_id() { return 0; }
|
||||
|
||||
unsigned Cpu::executing_id() { return primary_id(); }
|
@ -16,6 +16,7 @@
|
||||
#define _KERNEL__EARLY_TRANSLATIONS_H_
|
||||
|
||||
/* core includes */
|
||||
#include <assert.h>
|
||||
#include <page_slab.h>
|
||||
#include <translation_table.h>
|
||||
|
||||
|
@ -18,6 +18,7 @@
|
||||
/* Genode includes */
|
||||
#include <base/printf.h>
|
||||
#include <root/root.h>
|
||||
#include <util/construct_at.h>
|
||||
|
||||
/* Core includes */
|
||||
#include <translation_table.h>
|
||||
@ -80,7 +81,7 @@ namespace Genode
|
||||
throw Root::Quota_exceeded();
|
||||
}
|
||||
|
||||
_tt = new (tt) Translation_table();
|
||||
_tt = construct_at<Translation_table>(tt);
|
||||
_tt_phys = (Translation_table*) cma->phys_addr(_tt);
|
||||
_pslab = new (cma) Page_slab(cma);
|
||||
Kernel::mtc()->map(_tt, _pslab);
|
||||
|
@ -336,20 +336,27 @@ class Genode::Arm
|
||||
*/
|
||||
struct Context : Cpu_state
|
||||
{
|
||||
Cidr::access_t cidr;
|
||||
Ttbr0::access_t ttbr0;
|
||||
/**
|
||||
* TODO: currently all non-Cortex A15 platforms use the
|
||||
* short translation table format and thereby the Context ID
|
||||
* register to store the ASID, and the TTBR0 for the table
|
||||
* address. Cortex A15 uses the long translation format and
|
||||
* a 64-bit wide TTBR0 that holds all information.
|
||||
* The current Cortex A15 implementation stores TTBR0 in both
|
||||
* members stated below.
|
||||
*/
|
||||
uint32_t cidr;
|
||||
uint32_t ttbr0;
|
||||
|
||||
/**
|
||||
* Return base of assigned translation table
|
||||
*/
|
||||
addr_t translation_table() const {
|
||||
return Ttbr0::Ba::masked(ttbr0); }
|
||||
addr_t translation_table() const;
|
||||
|
||||
/**
|
||||
* Assign translation-table base 'table'
|
||||
*/
|
||||
void translation_table(addr_t const table) {
|
||||
ttbr0 = Arm::Ttbr0::init(table); }
|
||||
void translation_table(addr_t const table);
|
||||
|
||||
/**
|
||||
* Assign protection domain
|
||||
@ -405,35 +412,7 @@ class Genode::Arm
|
||||
* \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 0; }
|
||||
|
||||
/* fetch fault data */
|
||||
w = 0;
|
||||
va = ip;
|
||||
return 1; }
|
||||
|
||||
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 0; }
|
||||
|
||||
/* fetch fault data */
|
||||
Dfsr::access_t const dfsr = Dfsr::read();
|
||||
w = Dfsr::Wnr::get(dfsr);
|
||||
va = Dfar::read();
|
||||
return 1; }
|
||||
|
||||
default: return 0; }
|
||||
}
|
||||
bool in_fault(addr_t & va, addr_t & w) const;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -53,3 +53,72 @@
|
||||
/* alignment constraints */
|
||||
.set MIN_PAGE_SIZE_LOG2, 12
|
||||
.set DATA_ACCESS_ALIGNM_LOG2, 2
|
||||
|
||||
|
||||
/***************************************************
|
||||
** Constant values that the mode transition uses **
|
||||
***************************************************/
|
||||
|
||||
/* kernel names of exceptions that can interrupt a user */
|
||||
.set RST_TYPE, 1
|
||||
.set UND_TYPE, 2
|
||||
.set SVC_TYPE, 3
|
||||
.set PAB_TYPE, 4
|
||||
.set DAB_TYPE, 5
|
||||
.set IRQ_TYPE, 6
|
||||
.set FIQ_TYPE, 7
|
||||
|
||||
.set RST_PC_ADJUST, 0
|
||||
.set UND_PC_ADJUST, 4
|
||||
.set SVC_PC_ADJUST, 0
|
||||
.set PAB_PC_ADJUST, 4
|
||||
.set DAB_PC_ADJUST, 8
|
||||
.set IRQ_PC_ADJUST, 4
|
||||
.set FIQ_PC_ADJUST, 4
|
||||
|
||||
/* offsets of the member variables in a CPU context */
|
||||
.set R12_OFFSET, 12 * 4
|
||||
.set SP_OFFSET, 13 * 4
|
||||
.set LR_OFFSET, 14 * 4
|
||||
.set PC_OFFSET, 15 * 4
|
||||
.set PSR_OFFSET, 16 * 4
|
||||
.set EXCEPTION_TYPE_OFFSET, 17 * 4
|
||||
.set TRANSIT_TTBR0_OFFSET, 17 * 4
|
||||
.set CIDR_OFFSET, 18 * 4
|
||||
.set TTBR0_OFFSET, 19 * 4
|
||||
|
||||
/* size of local variables */
|
||||
.set CONTEXT_PTR_SIZE, 1 * 4
|
||||
|
||||
|
||||
/*********************************************************
|
||||
** Local data structures that the mode transition uses **
|
||||
*********************************************************/
|
||||
|
||||
.macro _mt_local_variables
|
||||
|
||||
/* space for a copy of the kernel context */
|
||||
.p2align 2
|
||||
.global _mt_master_context_begin
|
||||
_mt_master_context_begin:
|
||||
.space 32 * 4
|
||||
.global _mt_master_context_end
|
||||
_mt_master_context_end:
|
||||
|
||||
/* space for a client context-pointer per CPU */
|
||||
.p2align 2
|
||||
.global _mt_client_context_ptr
|
||||
_mt_client_context_ptr:
|
||||
.rept NR_OF_CPUS
|
||||
.space CONTEXT_PTR_SIZE
|
||||
.endr
|
||||
|
||||
/* a globally mapped buffer per CPU */
|
||||
.p2align 2
|
||||
.global _mt_buffer
|
||||
_mt_buffer:
|
||||
.rept NR_OF_CPUS
|
||||
.space BUFFER_SIZE
|
||||
.endr
|
||||
|
||||
.endm /* _mt_local_variables */
|
||||
|
@ -1,80 +0,0 @@
|
||||
/*
|
||||
* \brief Mode transition definitions used by all ARM architectures
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2014-06-12
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/***************************************************
|
||||
** Constant values that the mode transition uses **
|
||||
***************************************************/
|
||||
|
||||
/* kernel names of exceptions that can interrupt a user */
|
||||
.set RST_TYPE, 1
|
||||
.set UND_TYPE, 2
|
||||
.set SVC_TYPE, 3
|
||||
.set PAB_TYPE, 4
|
||||
.set DAB_TYPE, 5
|
||||
.set IRQ_TYPE, 6
|
||||
.set FIQ_TYPE, 7
|
||||
|
||||
.set RST_PC_ADJUST, 0
|
||||
.set UND_PC_ADJUST, 4
|
||||
.set SVC_PC_ADJUST, 0
|
||||
.set PAB_PC_ADJUST, 4
|
||||
.set DAB_PC_ADJUST, 8
|
||||
.set IRQ_PC_ADJUST, 4
|
||||
.set FIQ_PC_ADJUST, 4
|
||||
|
||||
/* offsets of the member variables in a CPU context */
|
||||
.set R12_OFFSET, 12 * 4
|
||||
.set SP_OFFSET, 13 * 4
|
||||
.set LR_OFFSET, 14 * 4
|
||||
.set PC_OFFSET, 15 * 4
|
||||
.set PSR_OFFSET, 16 * 4
|
||||
.set EXCEPTION_TYPE_OFFSET, 17 * 4
|
||||
.set TRANSIT_TTBR0_OFFSET, 17 * 4
|
||||
.set CIDR_OFFSET, 18 * 4
|
||||
.set TTBR0_OFFSET, 19 * 4
|
||||
|
||||
/* size of local variables */
|
||||
.set CONTEXT_PTR_SIZE, 1 * 4
|
||||
|
||||
|
||||
/*********************************************************
|
||||
** Local data structures that the mode transition uses **
|
||||
*********************************************************/
|
||||
|
||||
.macro _mt_local_variables
|
||||
|
||||
/* space for a copy of the kernel context */
|
||||
.p2align 2
|
||||
.global _mt_master_context_begin
|
||||
_mt_master_context_begin:
|
||||
.space 32 * 4
|
||||
.global _mt_master_context_end
|
||||
_mt_master_context_end:
|
||||
|
||||
/* space for a client context-pointer per CPU */
|
||||
.p2align 2
|
||||
.global _mt_client_context_ptr
|
||||
_mt_client_context_ptr:
|
||||
.rept NR_OF_CPUS
|
||||
.space CONTEXT_PTR_SIZE
|
||||
.endr
|
||||
|
||||
/* a globally mapped buffer per CPU */
|
||||
.p2align 2
|
||||
.global _mt_buffer
|
||||
_mt_buffer:
|
||||
.rept NR_OF_CPUS
|
||||
.space BUFFER_SIZE
|
||||
.endr
|
||||
|
||||
.endm /* _mt_local_variables */
|
@ -34,8 +34,82 @@ namespace Kernel { using Genode::Cpu_lazy_state; }
|
||||
|
||||
class Genode::Cpu : public Arm_v7
|
||||
{
|
||||
protected:
|
||||
|
||||
/**
|
||||
* Translation table base control register
|
||||
*/
|
||||
struct Ttbcr : Arm::Ttbcr
|
||||
{
|
||||
struct Irgn0 : Bitfield<8, 2> { };
|
||||
struct Orgn0 : Bitfield<10, 2> { };
|
||||
struct Sh0 : Bitfield<12, 2> { };
|
||||
struct Eae : Bitfield<31, 1> { }; /* extended address enable */
|
||||
|
||||
static access_t init_virt_kernel()
|
||||
{
|
||||
access_t v = 0;
|
||||
Irgn0::set(v, 1);
|
||||
Orgn0::set(v, 1);
|
||||
Sh0::set(v, 0b10);
|
||||
Eae::set(v, 1);
|
||||
return v;
|
||||
}
|
||||
};
|
||||
|
||||
struct Mair0 : Register<32>
|
||||
{
|
||||
static void init()
|
||||
{
|
||||
access_t v = 0xff0044;
|
||||
asm volatile ("mcr p15, 0, %[v], c10, c2, 0" :: [v]"r"(v) : );
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Translation table base register 0 (64-bit format)
|
||||
*/
|
||||
struct Ttbr0 : Register<64>
|
||||
{
|
||||
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
|
||||
*
|
||||
* \param table base of targeted translation table
|
||||
*/
|
||||
static access_t init(addr_t const table, unsigned const id)
|
||||
{
|
||||
access_t v = Ba::masked((access_t)table);
|
||||
Asid::set(v, id);
|
||||
return v;
|
||||
}
|
||||
|
||||
static Genode::uint32_t init(addr_t const table) {
|
||||
return table; }
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Return wether to retry an undefined user instruction after this call
|
||||
*/
|
||||
@ -51,6 +125,24 @@ class Genode::Cpu : public Arm_v7
|
||||
*/
|
||||
static unsigned primary_id();
|
||||
|
||||
/**
|
||||
* Switch to the virtual mode in kernel
|
||||
*
|
||||
* \param table base of targeted translation table
|
||||
* \param process_id process ID of the kernel address-space
|
||||
*/
|
||||
static void
|
||||
init_virt_kernel(addr_t const table, unsigned const process_id)
|
||||
{
|
||||
Mair0::init();
|
||||
Cidr::write(process_id);
|
||||
Dacr::write(Dacr::init_virt_kernel());
|
||||
Ttbr0::write(Ttbr0::init(table, 1));
|
||||
Ttbcr::write(Ttbcr::init_virt_kernel());
|
||||
Sctlr::write(Sctlr::init_virt_kernel());
|
||||
inval_branch_predicts();
|
||||
}
|
||||
|
||||
/*************
|
||||
** Dummies **
|
||||
*************/
|
||||
|
38
repos/base-hw/src/core/include/spec/cortex_a15/macros.s
Normal file
38
repos/base-hw/src/core/include/spec/cortex_a15/macros.s
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* \brief Macros that are used by multiple assembly files
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2015-01-30
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2015 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.
|
||||
*/
|
||||
|
||||
/* core includes */
|
||||
.include "spec/arm_v7/macros_support.s"
|
||||
|
||||
|
||||
/**
|
||||
* Switch to a given protection domain
|
||||
*
|
||||
* There is no atomicity problem when setting the ASID and translation table
|
||||
* base address in the one 64-bit TTBR0 register, like in Armv7 cpus without
|
||||
* LPAE extensions. Therefore, we don't have to use a transition table.
|
||||
*
|
||||
* \param transit_ttbr0 ignored parameter
|
||||
* \param new_cidr new CIDR value, read reg
|
||||
* \param new_ttbr0 new TTBR0 value, read/write reg
|
||||
*/
|
||||
.macro _switch_protection_domain transit_ttbr0, new_cidr, new_ttbr0
|
||||
|
||||
/* write translation-table-base register 0 */
|
||||
lsl \new_cidr, \new_cidr, #16
|
||||
mcrr p15, 0, \new_ttbr0, \new_cidr, c2
|
||||
|
||||
/* instruction and data synchronization barrier */
|
||||
isb
|
||||
dsb
|
||||
.endm
|
@ -0,0 +1,18 @@
|
||||
/*
|
||||
* \brief Translation table definitions for core
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2015-01-30
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2015 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 _TRANSLATION_TABLE_H_
|
||||
#define _TRANSLATION_TABLE_H_
|
||||
|
||||
/* core includes */
|
||||
#include <long_translation_table.h>
|
||||
|
||||
#endif /* _TRANSLATION_TABLE_H_ */
|
31
repos/base-hw/src/core/include/spec/cortex_a8/macros.s
Normal file
31
repos/base-hw/src/core/include/spec/cortex_a8/macros.s
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* \brief Macros that are used by multiple assembly files
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2015-01-30
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2015 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.
|
||||
*/
|
||||
|
||||
/* core includes */
|
||||
.include "spec/arm_v7/macros_support.s"
|
||||
|
||||
/**
|
||||
* Switch to a given protection domain
|
||||
*
|
||||
* \param transit_ttbr0 transitional TTBR0 value, read/write reg
|
||||
* \param new_cidr new CIDR value, read reg
|
||||
* \param new_ttbr0 new TTBR0 value, read/write reg
|
||||
*/
|
||||
.macro _switch_protection_domain transit_ttbr0, new_cidr, new_ttbr0
|
||||
mcr p15, 0, \transit_ttbr0, c2, c0, 0
|
||||
isb
|
||||
mcr p15, 0, \new_cidr, c13, c0, 1
|
||||
isb
|
||||
mcr p15, 0, \new_ttbr0, c2, c0, 0
|
||||
isb
|
||||
.endm
|
@ -1,22 +1,20 @@
|
||||
/*
|
||||
* \brief Armv7 translation table definitions for core
|
||||
* \author Martin Stein
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2012-02-22
|
||||
* \brief Translation table definitions for core
|
||||
* \author Martin Stein
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2012-02-22
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012-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 _TRANSLATION_TABLE_H_
|
||||
#define _TRANSLATION_TABLE_H_
|
||||
|
||||
/* core includes */
|
||||
#include <spec/arm/short_translation_table.h>
|
||||
#include <short_translation_table.h>
|
||||
|
||||
constexpr unsigned Genode::Translation::_device_tex() { return 2; }
|
||||
|
40
repos/base-hw/src/core/include/spec/cortex_a9/macros.s
Normal file
40
repos/base-hw/src/core/include/spec/cortex_a9/macros.s
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* \brief Macros that are used by multiple assembly files
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2015-01-30
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2015 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.
|
||||
*/
|
||||
|
||||
/* core includes */
|
||||
.include "spec/arm_v7/macros_support.s"
|
||||
|
||||
/**
|
||||
* Switch to a given protection domain
|
||||
*
|
||||
* \param transit_ttbr0 transitional TTBR0 value, read/write reg
|
||||
* \param new_cidr new CIDR value, read reg
|
||||
* \param new_ttbr0 new TTBR0 value, read/write reg
|
||||
*/
|
||||
.macro _switch_protection_domain transit_ttbr0, new_cidr, new_ttbr0
|
||||
|
||||
/*
|
||||
* FIXME: Fixes instability problems that were observed on the
|
||||
* PandaBoard only. We neither know why invalidating predictions
|
||||
* at PD switches is a fix nor wether not doing so is the real
|
||||
* cause of this instability.
|
||||
*/
|
||||
mcr p15, 0, r0, c7, c5, 6
|
||||
|
||||
mcr p15, 0, \transit_ttbr0, c2, c0, 0
|
||||
isb
|
||||
mcr p15, 0, \new_cidr, c13, c0, 1
|
||||
isb
|
||||
mcr p15, 0, \new_ttbr0, c2, c0, 0
|
||||
isb
|
||||
.endm
|
@ -0,0 +1,21 @@
|
||||
/*
|
||||
* \brief Translation table definitions for core
|
||||
* \author Martin Stein
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2012-02-22
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2012-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 _TRANSLATION_TABLE_H_
|
||||
#define _TRANSLATION_TABLE_H_
|
||||
|
||||
/* core includes */
|
||||
#include <short_translation_table.h>
|
||||
|
||||
constexpr unsigned Genode::Translation::_device_tex() { return 2; }
|
||||
|
||||
#endif /* _TRANSLATION_TABLE_H_ */
|
66
repos/base-hw/src/core/spec/arm/cpu.cc
Normal file
66
repos/base-hw/src/core/spec/arm/cpu.cc
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* \brief CPU driver for core
|
||||
* \author Martin stein
|
||||
* \date 2014-07-14
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2011-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.
|
||||
*/
|
||||
|
||||
/* core includes */
|
||||
#include <cpu.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
unsigned Cpu::primary_id() { return 0; }
|
||||
|
||||
|
||||
unsigned Cpu::executing_id() { return primary_id(); }
|
||||
|
||||
|
||||
addr_t Cpu::Context::translation_table() const {
|
||||
return Ttbr0::Ba::masked(ttbr0); }
|
||||
|
||||
|
||||
void Cpu::Context::translation_table(addr_t const t) {
|
||||
ttbr0 = Arm::Ttbr0::init(t); }
|
||||
|
||||
|
||||
bool Cpu::User_context::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;
|
||||
};
|
||||
}
|
@ -12,7 +12,6 @@
|
||||
*/
|
||||
|
||||
/* core includes */
|
||||
.include "mode_transition.s"
|
||||
.include "macros.s"
|
||||
|
||||
|
||||
|
@ -13,7 +13,6 @@
|
||||
*/
|
||||
|
||||
/* core includes */
|
||||
.include "mode_transition.s"
|
||||
.include "macros.s"
|
||||
|
||||
|
||||
@ -84,60 +83,6 @@
|
||||
.endm
|
||||
|
||||
|
||||
/**
|
||||
* Override the TTBR0 register
|
||||
*
|
||||
* \param val new value, read reg
|
||||
*/
|
||||
.macro _write_ttbr0 val
|
||||
mcr p15, 0, \val, c2, c0, 0
|
||||
.endm
|
||||
|
||||
|
||||
/**
|
||||
* Override the CIDR register
|
||||
*
|
||||
* \param val new value, read reg
|
||||
*/
|
||||
.macro _write_cidr val
|
||||
mcr p15, 0, \val, c13, c0, 1
|
||||
.endm
|
||||
|
||||
|
||||
/*
|
||||
* Invalidate all branch predictors
|
||||
*/
|
||||
.macro _bpiall
|
||||
mcr p15, 0, r0, c7, c5, 6
|
||||
.endm
|
||||
|
||||
|
||||
/**
|
||||
* Switch to a given protection domain
|
||||
*
|
||||
* \param transit_ttbr0 transitional TTBR0 value, read/write reg
|
||||
* \param new_cidr new CIDR value, read reg
|
||||
* \param new_ttbr0 new TTBR0 value, read/write reg
|
||||
*/
|
||||
.macro _switch_protection_domain transit_ttbr0, new_cidr, new_ttbr0
|
||||
|
||||
/*
|
||||
* FIXME: Fixes instability problems that were observed on the
|
||||
* PandaBoard only. We neither know why invalidating predictions
|
||||
* at PD switches is a fix nor wether not doing so is the real
|
||||
* cause of this instability.
|
||||
*/
|
||||
_bpiall
|
||||
|
||||
_write_ttbr0 \transit_ttbr0
|
||||
isb
|
||||
_write_cidr \new_cidr
|
||||
isb
|
||||
_write_ttbr0 \new_ttbr0
|
||||
isb
|
||||
.endm
|
||||
|
||||
|
||||
/**
|
||||
* Save an interrupted user context and switch to the kernel context
|
||||
*
|
||||
|
@ -1,6 +1,7 @@
|
||||
/*
|
||||
* \brief CPU driver for core
|
||||
* \author Martin stein
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2011-11-03
|
||||
*/
|
||||
|
||||
@ -19,4 +20,48 @@ using namespace Genode;
|
||||
|
||||
unsigned Cpu::executing_id() { return Mpidr::Aff_0::get(Mpidr::read()); }
|
||||
|
||||
|
||||
unsigned Cpu::primary_id() { return Board::PRIMARY_MPIDR_AFF_0; }
|
||||
|
||||
|
||||
addr_t Cpu::Context::translation_table() const { return ttbr0; }
|
||||
|
||||
|
||||
void Cpu::Context::translation_table(addr_t const t) { ttbr0 = t; }
|
||||
|
||||
|
||||
bool Cpu::User_context::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 & 0b11100) != 0b100)
|
||||
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 & 0b11100) != 0b100)
|
||||
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;
|
||||
};
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user