Move away drivers from generic base-repository

Driver definitions which are used by kernel/core in base-hw, and also by other
drivers (e.g. from the os repository) have to reside in the generic
base-repository, for instance some uart drivers. All drivers which are
interesting for one of the sites only (sp804 for timer driver, or
cortex_a9 cpu driver for base-hw) should reside in the respective repos.

Factorize cpu context out of Cortex A9 specific definitions. Moreover, there
is already a Cpu_state object containing all common ARM registers. We use
this as a base for the cpu context switching done by the base-hw kernel.
The Cpu_state class get extended by a cpu-exception field, that stores the kind
of exception raised when the corresponding context got interrupted. This
information is used not only by the base-hw kernel, but also by the TrustZone
VMM that is build currently.
This commit is contained in:
Stefan Kalkowski 2012-10-01 12:59:52 +02:00
parent f2d81a8d62
commit 94ea3a0acb
14 changed files with 121 additions and 107 deletions

View File

@ -41,7 +41,7 @@
/* load kernel contextidr */
adr sp, _mt_kernel_context_begin
ldr sp, [sp, #17*4]
ldr sp, [sp, #18*4]
mcr p15, 0, sp, c13, c0, 1
_flush_branch_predictor
@ -81,7 +81,7 @@
/* save type of exception that interrupted the user */
mov r0, #\exception_type
str r0, [sp, #18*4]
str r0, [sp, #17*4]
/*
* Switch to supervisor mode
@ -165,7 +165,7 @@
ldmia sp, {sp,lr}^
/* get user contextidr and section table */
ldr sp, [lr, #17*4]
ldr sp, [lr, #18*4]
ldr lr, [lr, #19*4]
/********************************************************

View File

@ -11,14 +11,15 @@
* under the terms of the GNU General Public License version 2.
*/
#ifndef _INCLUDE__DRIVERS__CPU__CORTEX_A9__CORE_H_
#define _INCLUDE__DRIVERS__CPU__CORTEX_A9__CORE_H_
#ifndef _INCLUDE__CORTEX_A9__CPU__CORE_H_
#define _INCLUDE__CORTEX_A9__CPU__CORE_H_
/* Genode includes */
#include <util/register.h>
#include <util/mmio.h>
#include <drivers/board.h>
#include <drivers/cpu/cortex_a9/timer.h>
#include <cpu/cpu_state.h>
#include <cortex_a9/cpu/timer.h>
namespace Genode
{
@ -409,66 +410,13 @@ namespace Genode
}
};
/**
* An execution state
*/
struct Context
struct Context : Cpu_state
{
enum {
MAX_GPR = 15,
MAX_CPU_EXCEPTION = 7,
};
/**
* Native exception types
*/
enum Cpu_exception {
RESET = 1,
UNDEFINED_INSTRUCTION = 2,
SUPERVISOR_CALL = 3,
PREFETCH_ABORT = 4,
DATA_ABORT = 5,
INTERRUPT_REQUEST = 6,
FAST_INTERRUPT_REQUEST = 7,
};
/* general purpose register backups, offsets 0*4 .. 15*4 */
uint32_t r0, r1, r2, r3, r4, r5, r6, r7,
r8, r9, r10, r11, r12, r13, r14, r15;
uint32_t psr; /* program status register backup, offset 16*4 */
uint32_t contextidr; /* contextidr register backup, offset 17*4 */
uint32_t cpu_exception; /* native type of last exception,
* offset 18*4 */
uint32_t contextidr; /* contextidr register backup, offset 18*4 */
uint32_t section_table; /* base address of applied section table,
* offset 19*4 */
/**
* Read a general purpose register
*
* \param id ID of the targeted register
* \param r Holds register value if this returns 1
*/
bool get_gpr(unsigned id, unsigned & r) const
{
if (id > MAX_GPR) return 0;
r = *(&r0 + id);
return 1;
}
/**
* Override a general purpose register
*
* \param id ID of the targeted register
* \param r Has been written to register if this returns 1
*/
bool set_gpr(unsigned id, unsigned const r)
{
if (id > MAX_GPR) return 0;
*(&r0 + id) = r;
return 1;
}
/***************
** Accessors **
***************/
@ -479,15 +427,41 @@ namespace Genode
Section_table * software_tlb() const {
return (Section_table *)section_table; }
void instruction_ptr(addr_t const p) { r15 = p; }
void instruction_ptr(addr_t const p) { ip = p; }
addr_t instruction_ptr() const { return r15; }
addr_t instruction_ptr() const { return ip; }
void return_ptr(addr_t const p) { r14 = p; }
void return_ptr(addr_t const p) { lr = p; }
void stack_ptr(addr_t const p) { r13 = p; }
void stack_ptr(addr_t const p) { sp = p; }
void protection_domain(unsigned const id) { contextidr = id; }
/**
* Read a general purpose register
*
* \param id ID of the targeted register
* \param v Holds register value if this returns 1
*/
bool get_gpr(unsigned id, unsigned & v) const
{
if (id >= MAX_GPR) return 0;
v = r[id];
return 1;
}
/**
* Override a general purpose register
*
* \param id ID of the targeted register
* \param v Has been written to register if this returns 1
*/
bool set_gpr(unsigned id, unsigned const v)
{
if (id >= MAX_GPR) return 0;
r[id] = v;
return 1;
}
};
/**
@ -495,6 +469,7 @@ namespace Genode
*/
struct User_context : Context
{
/**
* Constructor
*/
@ -502,30 +477,30 @@ namespace Genode
{
/* Execute in usermode with IRQ's enabled and FIQ's and
* asynchronous aborts disabled */
psr = Cpsr::M::bits(Cpsr::M::USER) | Cpsr::F::bits(1) |
Cpsr::I::bits(0) | Cpsr::A::bits(1);
cpsr = Cpsr::M::bits(Cpsr::M::USER) | Cpsr::F::bits(1) |
Cpsr::I::bits(0) | Cpsr::A::bits(1);
}
/***************************************************
** Communication between user and context holder **
***************************************************/
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; }
void user_arg_0(unsigned const arg) { r[0] = arg; }
void user_arg_1(unsigned const arg) { r[1] = arg; }
void user_arg_2(unsigned const arg) { r[2] = arg; }
void user_arg_3(unsigned const arg) { r[3] = arg; }
void user_arg_4(unsigned const arg) { r[4] = arg; }
void user_arg_5(unsigned const arg) { r[5] = arg; }
void user_arg_6(unsigned const arg) { r[6] = arg; }
void user_arg_7(unsigned const arg) { r[7] = arg; }
unsigned user_arg_0() const { return r[0]; }
unsigned user_arg_1() const { return r[1]; }
unsigned user_arg_2() const { return r[2]; }
unsigned user_arg_3() const { return r[3]; }
unsigned user_arg_4() const { return r[4]; }
unsigned user_arg_5() const { return r[5]; }
unsigned user_arg_6() const { return r[6]; }
unsigned user_arg_7() const { return r[7]; }
/**
* Determine wich type of exception occured on this context lastly
@ -638,11 +613,7 @@ namespace Genode
static bool secure_mode_active()
{
if (!Board::CORTEX_A9_SECURITY_EXTENSION) return 0;
if (Cpsr::M::get(Cpsr::read()) != Cpsr::M::MONITOR)
{
return !Scr::Ns::get(Scr::read());
}
return 1;
return !Scr::Ns::get(Scr::read());
}
/**

View File

@ -17,7 +17,7 @@
/* Genode includes */
#include <util/register.h>
#include <base/printf.h>
#include <drivers/cpu/cortex_a9/core.h>
#include <cortex_a9/cpu/core.h>
namespace Genode
{

View File

@ -14,9 +14,9 @@
#ifndef _CORE__INCLUDE__CORTEX_A9__KERNEL_SUPPORT_H_
#define _CORE__INCLUDE__CORTEX_A9__KERNEL_SUPPORT_H_
/* Genode includes */
#include <drivers/cpu/cortex_a9/core.h>
#include <drivers/pic/pl390_base.h>
/* Core includes */
#include <cortex_a9/cpu/core.h>
#include <pic/pl390_base.h>
/**
* CPU driver

View File

@ -13,11 +13,11 @@
/* Genode includes */
#include <drivers/board.h>
#include <drivers/cpu/cortex_a9/core.h>
#include <drivers/pic/pl390_base.h>
/* core includes */
#include <platform.h>
#include <cortex_a9/cpu/core.h>
#include <pic/pl390_base.h>
using namespace Genode;

View File

@ -15,7 +15,7 @@
#define _SRC__CORE__PANDA_A2__SOFTWARE_TLB_H_
/* Genode includes */
#include <drivers/cpu/cortex_a9/section_table.h>
#include <cortex_a9/cpu/section_table.h>
/**
* Software TLB controls

View File

@ -13,11 +13,11 @@
/* Genode includes */
#include <drivers/board.h>
#include <drivers/cpu/cortex_a9/core.h>
#include <drivers/pic/pl390_base.h>
/* core includes */
#include <platform.h>
#include <cortex_a9/cpu/core.h>
#include <pic/pl390_base.h>
using namespace Genode;

View File

@ -15,7 +15,7 @@
#define _SRC__CORE__PBXA9__SOFTWARE_TLB_H_
/* Genode includes */
#include <drivers/cpu/cortex_a9/section_table.h>
#include <cortex_a9/cpu/section_table.h>
/**
* Software TLB controls

View File

@ -13,11 +13,11 @@
/* Genode includes */
#include <drivers/board.h>
#include <drivers/cpu/cortex_a9/core.h>
#include <drivers/pic/pl390_base.h>
/* Core includes */
#include <platform.h>
#include <cortex_a9/cpu/core.h>
#include <pic/pl390_base.h>
using namespace Genode;

View File

@ -15,7 +15,7 @@
#define _SRC__CORE__VEA9X4__SOFTWARE_TLB_H_
/* Genode includes */
#include <drivers/cpu/cortex_a9/section_table.h>
#include <cortex_a9/cpu/section_table.h>
/**
* Software TLB controls

View File

@ -21,11 +21,54 @@ namespace Genode {
struct Cpu_state
{
addr_t ip;
addr_t sp;
addr_t r[13];
addr_t lr;
addr_t cpsr;
/**
* Native exception types
*/
enum Cpu_exception {
RESET = 1,
UNDEFINED_INSTRUCTION = 2,
SUPERVISOR_CALL = 3,
PREFETCH_ABORT = 4,
DATA_ABORT = 5,
INTERRUPT_REQUEST = 6,
FAST_INTERRUPT_REQUEST = 7,
MAX_CPU_EXCEPTION = FAST_INTERRUPT_REQUEST,
};
enum { MAX_GPR = 13 };
addr_t r[MAX_GPR]; /* r0-r12 - general purpose */
addr_t sp; /* r13 - stack pointer */
addr_t lr; /* r14 - link register */
addr_t ip; /* r15 - instruction pointer */
addr_t cpsr; /* current program status register */
Cpu_exception cpu_exception; /* last exception */
};
struct Cpu_state_modes : Cpu_state
{
/**
* Common banked registers for exception modes
*/
struct Mode_state {
enum Mode {
UND, /* Undefined */
SVC, /* Supervisor */
ABORT, /* Abort */
IRQ, /* Interrupt */
FIQ, /* Fast Interrupt */
MAX
};
uint32_t sp; /* banked stack pointer */
uint32_t lr; /* banked link register */
uint32_t spsr; /* saved program status register */
};
Mode_state mode[Mode_state::MAX]; /* exception mode registers */
uint32_t fiq_r[5]; /* fast-interrupt mode r8-r12 */
};
}