mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-08 20:05:54 +00:00
Minor coding-style fixes
This commit is contained in:
parent
2b0c613336
commit
cba25cc1d6
@ -1,4 +1,4 @@
|
||||
/**
|
||||
/*
|
||||
* \brief Driver for the OMAP4 PandaBoard revision A2
|
||||
* \author Martin stein
|
||||
* \date 2011-11-03
|
||||
@ -11,8 +11,8 @@
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _BASE__INCLUDE__DRIVERS__BOARD__PANDA_A2_H_
|
||||
#define _BASE__INCLUDE__DRIVERS__BOARD__PANDA_A2_H_
|
||||
#ifndef _INCLUDE__DRIVERS__BOARD__PANDA_A2_H_
|
||||
#define _INCLUDE__DRIVERS__BOARD__PANDA_A2_H_
|
||||
|
||||
namespace Genode
|
||||
{
|
||||
@ -23,11 +23,11 @@ namespace Genode
|
||||
{
|
||||
enum
|
||||
{
|
||||
/* Buses */
|
||||
/* buses */
|
||||
L4_PER_BASE = 0x48000000,
|
||||
L4_PER_SIZE = 0x01000000,
|
||||
|
||||
/* Clocks */
|
||||
/* clocks */
|
||||
MPU_DPLL_CLOCK = 200*1000*1000,
|
||||
|
||||
/* UART */
|
||||
@ -49,5 +49,5 @@ namespace Genode
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _BASE__INCLUDE__DRIVERS__BOARD__PANDA_A2_H_ */
|
||||
#endif /* _INCLUDE__DRIVERS__BOARD__PANDA_A2_H_ */
|
||||
|
||||
|
@ -11,8 +11,8 @@
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _BASE__INCLUDE__DRIVERS__BOARD__PBXA9_H_
|
||||
#define _BASE__INCLUDE__DRIVERS__BOARD__PBXA9_H_
|
||||
#ifndef _INCLUDE__DRIVERS__BOARD__PBXA9_H_
|
||||
#define _INCLUDE__DRIVERS__BOARD__PBXA9_H_
|
||||
|
||||
namespace Genode
|
||||
{
|
||||
@ -23,18 +23,18 @@ namespace Genode
|
||||
{
|
||||
enum
|
||||
{
|
||||
/* Northbridge */
|
||||
/* northbridge */
|
||||
NORTHBRIDGE_DDR_0_BASE = 0x00000000, /* DMC mirror */
|
||||
NORTHBRIDGE_DDR_0_SIZE = 256*1024*1024,
|
||||
|
||||
NORTHBRIDGE_AHB_BASE = 0x10020000,
|
||||
NORTHBRIDGE_AHB_SIZE = 768*1024,
|
||||
|
||||
/* Southbridge */
|
||||
/* southbridge */
|
||||
SOUTHBRIDGE_APB_BASE = 0x10000000,
|
||||
SOUTHBRIDGE_APB_SIZE = 128*1024,
|
||||
|
||||
/* Clocks */
|
||||
/* clocks */
|
||||
OSC_6_CLOCK = 24*1000*1000,
|
||||
OSC_7_CLOCK = 14*1000*1000,
|
||||
|
||||
@ -50,7 +50,7 @@ namespace Genode
|
||||
PL011_0_CLOCK = OSC_6_CLOCK,
|
||||
PL011_0_IRQ = 44,
|
||||
|
||||
/* Timer */
|
||||
/* timer */
|
||||
SP804_0_MMIO_BASE = SOUTHBRIDGE_APB_BASE + 0x11000,
|
||||
SP804_0_MMIO_SIZE = 4*1024,
|
||||
SP804_0_IRQ = 36,
|
||||
@ -74,5 +74,5 @@ namespace Genode
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _BASE__INCLUDE__DRIVERS__BOARD__PBXA9_H_ */
|
||||
#endif /* _INCLUDE__DRIVERS__BOARD__PBXA9_H_ */
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/**
|
||||
/*
|
||||
* \brief Driver for the Versatile Express A9X4 board
|
||||
* \author Martin stein
|
||||
* \date 2011-11-03
|
||||
@ -11,22 +11,21 @@
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _BASE__INCLUDE__DRIVERS__BOARD__VEA9X4_H_
|
||||
#define _BASE__INCLUDE__DRIVERS__BOARD__VEA9X4_H_
|
||||
#ifndef _INCLUDE__DRIVERS__BOARD__VEA9X4_H_
|
||||
#define _INCLUDE__DRIVERS__BOARD__VEA9X4_H_
|
||||
|
||||
namespace Genode
|
||||
{
|
||||
/**
|
||||
* Driver for the Versatile Express A9X4 board
|
||||
*
|
||||
* \detail Implies the uATX motherboard and the
|
||||
* CoreTile Express A9X4 daughterboard
|
||||
* Implies the uATX motherboard and the CoreTile Express A9X4 daughterboard
|
||||
*/
|
||||
struct Vea9x4
|
||||
{
|
||||
enum
|
||||
{
|
||||
/* Static memory bus */
|
||||
/* static memory bus */
|
||||
SMB_CS7_BASE = 0x10000000,
|
||||
SMB_CS7_SIZE = 0x20000,
|
||||
SMB_CS0_TO_CS6_BASE = 0x40000000,
|
||||
@ -38,13 +37,13 @@ namespace Genode
|
||||
PL011_0_CLOCK = 24*1000*1000,
|
||||
PL011_0_IRQ = 5,
|
||||
|
||||
/* Timer/counter */
|
||||
/* timer/counter */
|
||||
SP804_0_1_MMIO_BASE = SMB_CS7_BASE + 0x11000,
|
||||
SP804_0_1_MMIO_SIZE = 0x1000,
|
||||
SP804_0_1_CLOCK = 1000*1000,
|
||||
SP804_0_1_IRQ = 34,
|
||||
|
||||
/* Clocks */
|
||||
/* clocks */
|
||||
TCREF_CLOCK = 66670*1000,
|
||||
|
||||
/* CPU */
|
||||
@ -60,5 +59,5 @@ namespace Genode
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _BASE__INCLUDE__DRIVERS__BOARD__VEA9X4_H_ */
|
||||
#endif /* _INCLUDE__DRIVERS__BOARD__VEA9X4_H_ */
|
||||
|
||||
|
@ -11,8 +11,8 @@
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _BASE__INCLUDE__DRIVERS__CPU__CORTEX_A9__CORE_H_
|
||||
#define _BASE__INCLUDE__DRIVERS__CPU__CORTEX_A9__CORE_H_
|
||||
#ifndef _INCLUDE__DRIVERS__CPU__CORTEX_A9__CORE_H_
|
||||
#define _INCLUDE__DRIVERS__CPU__CORTEX_A9__CORE_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <util/register.h>
|
||||
@ -31,21 +31,21 @@ namespace Genode
|
||||
{
|
||||
enum
|
||||
{
|
||||
/* Common */
|
||||
/* common */
|
||||
DATA_ACCESS_ALIGNM = 4,
|
||||
CLK = Board::CORTEX_A9_CLOCK, /* CPU interface clock */
|
||||
PERIPH_CLK = CLK, /* Clock for CPU internal components */
|
||||
PERIPH_CLK = CLK, /* clock for CPU internal components */
|
||||
MIN_PAGE_SIZE_LOG2 = 12,
|
||||
MAX_PAGE_SIZE_LOG2 = 20,
|
||||
HIGHEST_EXCEPTION_ENTRY = 0xffff0000,
|
||||
|
||||
/* Interrupt controller */
|
||||
/* interrupt controller */
|
||||
PL390_DISTRIBUTOR_MMIO_BASE = Board::CORTEX_A9_PRIVATE_MEM_BASE + 0x1000,
|
||||
PL390_DISTRIBUTOR_MMIO_SIZE = 0x1000,
|
||||
PL390_CPU_MMIO_BASE = Board::CORTEX_A9_PRIVATE_MEM_BASE + 0x100,
|
||||
PL390_CPU_MMIO_SIZE = 0x100,
|
||||
|
||||
/* Timer */
|
||||
/* timer */
|
||||
PRIVATE_TIMER_MMIO_BASE = Board::CORTEX_A9_PRIVATE_MEM_BASE + 0x600,
|
||||
PRIVATE_TIMER_MMIO_SIZE = 0x10,
|
||||
PRIVATE_TIMER_IRQ = 29,
|
||||
@ -53,15 +53,17 @@ namespace Genode
|
||||
TIMER_IRQ = PRIVATE_TIMER_IRQ,
|
||||
};
|
||||
|
||||
/* Exceotion type IDs */
|
||||
/**
|
||||
* Exceotion type IDs
|
||||
*/
|
||||
enum Exception_type
|
||||
{
|
||||
RESET = 1,
|
||||
UNDEFINED_INSTRUCTION = 2,
|
||||
SUPERVISOR_CALL = 3,
|
||||
PREFETCH_ABORT = 4,
|
||||
DATA_ABORT = 5,
|
||||
INTERRUPT_REQUEST = 6,
|
||||
RESET = 1,
|
||||
UNDEFINED_INSTRUCTION = 2,
|
||||
SUPERVISOR_CALL = 3,
|
||||
PREFETCH_ABORT = 4,
|
||||
DATA_ABORT = 5,
|
||||
INTERRUPT_REQUEST = 6,
|
||||
FAST_INTERRUPT_REQUEST = 7,
|
||||
};
|
||||
|
||||
@ -72,14 +74,16 @@ namespace Genode
|
||||
*/
|
||||
struct Fsr : Register<32>
|
||||
{
|
||||
/* Fault status encoding */
|
||||
/**
|
||||
* Fault status encoding
|
||||
*/
|
||||
enum Fault_status {
|
||||
SECTION_TRANSLATION_FAULT = 5,
|
||||
PAGE_TRANSLATION_FAULT = 7,
|
||||
PAGE_TRANSLATION_FAULT = 7,
|
||||
};
|
||||
|
||||
struct Fs_3_0 : Bitfield<0, 4> { }; /* Fault status bits [3:0] */
|
||||
struct Fs_4 : Bitfield<10, 1> { }; /* Fault status bits [4] */
|
||||
struct Fs_3_0 : Bitfield<0, 4> { }; /* fault status bits [3:0] */
|
||||
struct Fs_4 : Bitfield<10, 1> { }; /* fault status bits [4] */
|
||||
};
|
||||
|
||||
/**
|
||||
@ -126,7 +130,7 @@ namespace Genode
|
||||
*/
|
||||
struct Dfsr : Fsr
|
||||
{
|
||||
struct Wnr : Bitfield<11, 1> { }; /* Write not read bit */
|
||||
struct Wnr : Bitfield<11, 1> { }; /* write not read bit */
|
||||
|
||||
/**
|
||||
* Read register
|
||||
@ -187,9 +191,9 @@ namespace Genode
|
||||
struct Sctlr : Register<32>
|
||||
{
|
||||
struct M : Bitfield<0,1> { }; /* MMU enable bit */
|
||||
struct C : Bitfield<2,1> { }; /* Cache enable bit */
|
||||
struct I : Bitfield<12,1> { }; /* Instruction cache enable bit */
|
||||
struct V : Bitfield<13,1> { }; /* Exception vectors bit */
|
||||
struct C : Bitfield<2,1> { }; /* cache enable bit */
|
||||
struct I : Bitfield<12,1> { }; /* instruction cache enable bit */
|
||||
struct V : Bitfield<13,1> { }; /* exception vectors bit */
|
||||
|
||||
/**
|
||||
* Read whole register
|
||||
@ -215,19 +219,19 @@ namespace Genode
|
||||
*/
|
||||
struct Ttbcr : Register<32>
|
||||
{
|
||||
/********************
|
||||
* Always available *
|
||||
********************/
|
||||
/**********************
|
||||
** Always available **
|
||||
**********************/
|
||||
|
||||
struct N : Bitfield<0,3> /* Base address width */
|
||||
struct N : Bitfield<0,3> /* base address width */
|
||||
{ };
|
||||
|
||||
/******************************************
|
||||
* Only available with security extension *
|
||||
******************************************/
|
||||
/********************************************
|
||||
** Only available with security extension **
|
||||
********************************************/
|
||||
|
||||
struct Pd0 : Bitfield<4,1> { }; /* Translation table walk disable bit for TTBR0 */
|
||||
struct Pd1 : Bitfield<5,1> { }; /* Translation table walk disable bit for TTBR1 */
|
||||
struct Pd0 : Bitfield<4,1> { }; /* translation table walk disable bit for TTBR0 */
|
||||
struct Pd1 : Bitfield<5,1> { }; /* translation table walk disable bit for TTBR1 */
|
||||
|
||||
/**
|
||||
* Read whole register, only in privileged CPU mode
|
||||
@ -253,16 +257,16 @@ namespace Genode
|
||||
/**
|
||||
* Access values for the 16 available domains
|
||||
*/
|
||||
struct D0 : Bitfield<0,2> { };
|
||||
struct D1 : Bitfield<2,2> { };
|
||||
struct D2 : Bitfield<4,2> { };
|
||||
struct D3 : Bitfield<6,2> { };
|
||||
struct D4 : Bitfield<8,2> { };
|
||||
struct D5 : Bitfield<10,2> { };
|
||||
struct D6 : Bitfield<12,2> { };
|
||||
struct D7 : Bitfield<14,2> { };
|
||||
struct D8 : Bitfield<16,2> { };
|
||||
struct D9 : Bitfield<18,2> { };
|
||||
struct D0 : Bitfield<0,2> { };
|
||||
struct D1 : Bitfield<2,2> { };
|
||||
struct D2 : Bitfield<4,2> { };
|
||||
struct D3 : Bitfield<6,2> { };
|
||||
struct D4 : Bitfield<8,2> { };
|
||||
struct D5 : Bitfield<10,2> { };
|
||||
struct D6 : Bitfield<12,2> { };
|
||||
struct D7 : Bitfield<14,2> { };
|
||||
struct D8 : Bitfield<16,2> { };
|
||||
struct D9 : Bitfield<18,2> { };
|
||||
struct D10 : Bitfield<20,2> { };
|
||||
struct D11 : Bitfield<22,2> { };
|
||||
struct D12 : Bitfield<24,2> { };
|
||||
@ -282,53 +286,54 @@ namespace Genode
|
||||
/**
|
||||
* Translation table base register 0
|
||||
*
|
||||
* \detail Typically for process specific spaces, references first level
|
||||
* table with a size between 128B and 16KB according to TTBCR.N,
|
||||
* Typically for process specific spaces, references first level table
|
||||
* with a size between 128B and 16KB according to TTBCR.N
|
||||
*/
|
||||
struct Ttbr0 : Register<32>
|
||||
{
|
||||
/********************
|
||||
* Always available *
|
||||
********************/
|
||||
/**********************
|
||||
** Always available **
|
||||
**********************/
|
||||
|
||||
struct S : Bitfield<1,1> { }; /* Shareable bit */
|
||||
struct Rgn : Bitfield<3,2> /* Region bits */
|
||||
struct S : Bitfield<1,1> { }; /* shareable bit */
|
||||
struct Rgn : Bitfield<3,2> /* region bits */
|
||||
{
|
||||
enum { OUTER_NON_CACHEABLE = 0b00,
|
||||
OUTER_WBACK_WALLOCATE_CACHEABLE = 0b01,
|
||||
OUTER_WTHROUGH_CACHEABLE = 0b10,
|
||||
OUTER_WBACK_NO_WALLCOATE_CACHEABLE = 0b11,
|
||||
OUTER_WBACK_WALLOCATE_CACHEABLE = 0b01,
|
||||
OUTER_WTHROUGH_CACHEABLE = 0b10,
|
||||
OUTER_WBACK_NO_WALLCOATE_CACHEABLE = 0b11,
|
||||
};
|
||||
};
|
||||
|
||||
struct Nos : Bitfield<5,1> { }; /* Not outer shareable bit */
|
||||
struct Base_address : Bitfield<14,18> { }; /* Translation table base address (Driver supports only 16KB alignment) */
|
||||
struct Nos : Bitfield<5,1> { }; /* not outer shareable bit */
|
||||
struct Base_address : Bitfield<14,18> { }; /* translation table base address
|
||||
(Driver supports only 16KB alignment) */
|
||||
|
||||
/*********************************************
|
||||
* Only available without security extension *
|
||||
*********************************************/
|
||||
/***********************************************
|
||||
** Only available without security extension **
|
||||
***********************************************/
|
||||
|
||||
struct C : Bitfield<0,1> { }; /* Cacheable bit */
|
||||
struct C : Bitfield<0,1> { }; /* cacheable bit */
|
||||
|
||||
/******************************************
|
||||
* Only available with security extension *
|
||||
******************************************/
|
||||
/********************************************
|
||||
** Only available with security extension **
|
||||
********************************************/
|
||||
|
||||
struct Irgn_1 : Bitfield<0,1> /* Inner region bit 0 */
|
||||
struct Irgn_1 : Bitfield<0,1> /* inner region bit 0 */
|
||||
{
|
||||
enum { INNER_NON_CACHEABLE = 0b0,
|
||||
INNER_WBACK_WALLOCATE_CACHEABLE = 0b0,
|
||||
INNER_WTHROUGH_CACHEABLE = 0b1,
|
||||
INNER_WBACK_NO_WALLCOATE_CACHEABLE = 0b1,
|
||||
INNER_WBACK_WALLOCATE_CACHEABLE = 0b0,
|
||||
INNER_WTHROUGH_CACHEABLE = 0b1,
|
||||
INNER_WBACK_NO_WALLCOATE_CACHEABLE = 0b1,
|
||||
};
|
||||
};
|
||||
|
||||
struct Irgn_0 : Bitfield<6,1> /* Inner region bit 1 */
|
||||
struct Irgn_0 : Bitfield<6,1> /* inner region bit 1 */
|
||||
{
|
||||
enum { INNER_NON_CACHEABLE = 0b0,
|
||||
INNER_WBACK_WALLOCATE_CACHEABLE = 0b1,
|
||||
INNER_WTHROUGH_CACHEABLE = 0b0,
|
||||
INNER_WBACK_NO_WALLCOATE_CACHEABLE = 0b1,
|
||||
INNER_WBACK_WALLOCATE_CACHEABLE = 0b1,
|
||||
INNER_WTHROUGH_CACHEABLE = 0b0,
|
||||
INNER_WBACK_NO_WALLCOATE_CACHEABLE = 0b1,
|
||||
};
|
||||
};
|
||||
|
||||
@ -351,22 +356,22 @@ namespace Genode
|
||||
*/
|
||||
struct Cpsr : Register<32>
|
||||
{
|
||||
struct M : Bitfield<0,5> /* Processor mode */
|
||||
struct M : Bitfield<0,5> /* processor mode */
|
||||
{
|
||||
enum { /* <Privileged>, <Description> */
|
||||
USER = 0b10000, /* 0, Application code */
|
||||
FIQ = 0b10001, /* 1, Entered at fast interrupt */
|
||||
IRQ = 0b10010, /* 1, Entered at normal interrupt */
|
||||
SUPERVISOR = 0b10011, /* 1, Most kernel code */
|
||||
MONITOR = 0b10110, /* 1, A secure mode, switch sec./non-sec. */
|
||||
ABORT = 0b10111, /* 1, Entered at aborts */
|
||||
UNDEFINED = 0b11011, /* 1, Entered at instruction-related error */
|
||||
SYSTEM = 0b11111, /* 1, Applications that require privileged */
|
||||
USER = 0b10000, /* 0, application code */
|
||||
FIQ = 0b10001, /* 1, entered at fast interrupt */
|
||||
IRQ = 0b10010, /* 1, entered at normal interrupt */
|
||||
SUPERVISOR = 0b10011, /* 1, most kernel code */
|
||||
MONITOR = 0b10110, /* 1, a secure mode, switch sec./non-sec. */
|
||||
ABORT = 0b10111, /* 1, entered at aborts */
|
||||
UNDEFINED = 0b11011, /* 1, entered at instruction-related error */
|
||||
SYSTEM = 0b11111, /* 1, applications that require privileged */
|
||||
};
|
||||
};
|
||||
struct F : Bitfield<6,1> { }; /* Fast interrupt request disable */
|
||||
struct I : Bitfield<7,1> { }; /* Interrupt request disable */
|
||||
struct A : Bitfield<8,1> { }; /* Asynchronous abort disable */
|
||||
struct F : Bitfield<6,1> { }; /* fast interrupt request disable */
|
||||
struct I : Bitfield<7,1> { }; /* interrupt request disable */
|
||||
struct A : Bitfield<8,1> { }; /* asynchronous abort disable */
|
||||
|
||||
/**
|
||||
* Read whole register
|
||||
@ -392,7 +397,7 @@ namespace Genode
|
||||
*/
|
||||
struct Scr : Register<32>
|
||||
{
|
||||
struct Ns : Bitfield<0, 1> { }; /* Non secure bit */
|
||||
struct Ns : Bitfield<0, 1> { }; /* non secure bit */
|
||||
|
||||
/**
|
||||
* Read whole register
|
||||
@ -410,15 +415,15 @@ namespace Genode
|
||||
*/
|
||||
struct Context
|
||||
{
|
||||
/* General purpose registers, offset 0*4 .. 15*4 */
|
||||
/* general purpose registers, offset 0*4 .. 15*4 */
|
||||
uint32_t
|
||||
r0, r1, r2, r3, r4, r5, r6, r7,
|
||||
r8, r9, r10, r11, r12, sp, lr, pc;
|
||||
|
||||
/* Special registers, offset 16*4 .. 17*4 */
|
||||
/* special registers, offset 16*4 .. 17*4 */
|
||||
uint32_t psr, contextidr;
|
||||
|
||||
/* Additional state info, offset 18*4 .. 19*4 */
|
||||
/* additional state info, offset 18*4 .. 19*4 */
|
||||
uint32_t exception_type, section_table;
|
||||
|
||||
/***************
|
||||
@ -454,8 +459,8 @@ namespace Genode
|
||||
/**
|
||||
* Set CPU exception entry to a given address
|
||||
*
|
||||
* \return 0 Exception entry set to the given address
|
||||
* <0 Otherwise
|
||||
* \return 0 exception entry set to the given address
|
||||
* <0 otherwise
|
||||
*/
|
||||
static int exception_entry_at(addr_t a)
|
||||
{
|
||||
@ -490,14 +495,14 @@ namespace Genode
|
||||
/**
|
||||
* Enable the MMU
|
||||
*
|
||||
* \param section_table Section translation table of the initial
|
||||
* \param section_table section translation table of the initial
|
||||
* address space this function switches to
|
||||
* \param process_id Process ID of the initial address space
|
||||
* \param process_id process ID of the initial address space
|
||||
*/
|
||||
static void enable_mmu (Section_table * const section_table,
|
||||
unsigned long const process_id)
|
||||
{
|
||||
/* Initialize domains */
|
||||
/* initialize domains */
|
||||
Dacr::write (Dacr::D0::bits (Dacr::CLIENT)
|
||||
| Dacr::D1::bits (Dacr::NO_ACCESS)
|
||||
| Dacr::D2::bits (Dacr::NO_ACCESS)
|
||||
@ -515,16 +520,16 @@ namespace Genode
|
||||
| Dacr::D14::bits (Dacr::NO_ACCESS)
|
||||
| Dacr::D15::bits (Dacr::NO_ACCESS));
|
||||
|
||||
/* Switch process ID */
|
||||
/* switch process ID */
|
||||
Contextidr::write(process_id);
|
||||
|
||||
/* Install section table */
|
||||
/* install section table */
|
||||
Ttbr0::write (Ttbr0::Base_address::masked ((addr_t)section_table));
|
||||
Ttbcr::write (Ttbcr::N::bits(0)
|
||||
| Ttbcr::Pd0::bits(0)
|
||||
| Ttbcr::Pd1::bits(0) );
|
||||
|
||||
/* Enable MMU without instruction-, data-, or unified caches */
|
||||
/* enable MMU without instruction-, data-, or unified caches */
|
||||
Sctlr::access_t sctlr = Sctlr::read();
|
||||
Sctlr::M::set(sctlr);
|
||||
Sctlr::I::clear(sctlr);
|
||||
@ -536,7 +541,7 @@ namespace Genode
|
||||
/**
|
||||
* Invalidate all entries of the branch predictor array
|
||||
*
|
||||
* \detail Must be inline to avoid dependence on the branch predictor
|
||||
* Must be inline to avoid dependence on the branch predictor
|
||||
*/
|
||||
__attribute__((always_inline)) inline static void flush_branch_prediction()
|
||||
{
|
||||
@ -559,25 +564,25 @@ namespace Genode
|
||||
/**
|
||||
* Does a pagefault exist and originate from a lack of translation?
|
||||
*
|
||||
* \param c CPU Context that triggered the pagefault
|
||||
* \param va Holds the virtual fault-address if this
|
||||
* \param c CPU Context that triggered the page fault
|
||||
* \param va holds the virtual fault-address if this
|
||||
* function returns 1
|
||||
* \param w Indicates wether the fault was caused by a write access
|
||||
* \param w indicates whether the fault was caused by a write access
|
||||
* if this function returns 1
|
||||
*/
|
||||
static bool translation_miss(Context * c, addr_t & va, bool & w)
|
||||
{
|
||||
/* Determine fault type */
|
||||
/* determine fault type */
|
||||
switch (c->exception_type)
|
||||
{
|
||||
case PREFETCH_ABORT: {
|
||||
|
||||
/* Is fault caused by translation miss? */
|
||||
/* is fault caused by translation miss? */
|
||||
Ifsr::Fault_status const fs = Ifsr::fault_status();
|
||||
if(fs == Ifsr::SECTION_TRANSLATION_FAULT ||
|
||||
fs == Ifsr::PAGE_TRANSLATION_FAULT)
|
||||
{
|
||||
/* Fetch fault data */
|
||||
/* fetch fault data */
|
||||
w = 0;
|
||||
va = Ifar::read();
|
||||
return 1;
|
||||
@ -585,12 +590,12 @@ namespace Genode
|
||||
return 0; }
|
||||
case DATA_ABORT: {
|
||||
|
||||
/* Is fault caused by translation miss? */
|
||||
/* is fault caused by translation miss? */
|
||||
Dfsr::Fault_status const fs = Dfsr::fault_status();
|
||||
if(fs == Dfsr::SECTION_TRANSLATION_FAULT ||
|
||||
fs == Dfsr::PAGE_TRANSLATION_FAULT)
|
||||
{
|
||||
/* Fetch fault data */
|
||||
/* fetch fault data */
|
||||
Dfsr::access_t const dfsr = Dfsr::read();
|
||||
w = Dfsr::Wnr::get(dfsr);
|
||||
va = Dfar::read();
|
||||
@ -603,5 +608,5 @@ namespace Genode
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _BASE__INCLUDE__DRIVERS__CPU__CORTEX_A9__CORE_H_ */
|
||||
#endif /* _INCLUDE__DRIVERS__CPU__CORTEX_A9__CORE_H_ */
|
||||
|
||||
|
@ -11,8 +11,8 @@
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _BASE__INCLUDE__DRIVERS__CPU__CORTEX_A9__SECTION_TABLE_H_
|
||||
#define _BASE__INCLUDE__DRIVERS__CPU__CORTEX_A9__SECTION_TABLE_H_
|
||||
#ifndef _INCLUDE__DRIVERS__CPU__CORTEX_A9__SECTION_TABLE_H_
|
||||
#define _INCLUDE__DRIVERS__CPU__CORTEX_A9__SECTION_TABLE_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <util/register.h>
|
||||
@ -50,10 +50,9 @@ namespace Genode
|
||||
/**
|
||||
* Cortex A9 second level translation table
|
||||
*
|
||||
* \detail A table is dedicated to either secure or non-secure
|
||||
* mode. All translations done by this table apply
|
||||
* domain 0. They are not shareable and have zero-filled
|
||||
* memory region attributes.
|
||||
* A table is dedicated to either secure or non-secure mode. All
|
||||
* translations done by this table apply domain 0. They are not shareable
|
||||
* and have zero-filled memory region attributes.
|
||||
*/
|
||||
class Page_table
|
||||
{
|
||||
@ -83,7 +82,9 @@ namespace Genode
|
||||
*/
|
||||
struct Descriptor : Register<32>
|
||||
{
|
||||
/* Descriptor types */
|
||||
/**
|
||||
* Descriptor types
|
||||
*/
|
||||
enum Type { FAULT, SMALL_PAGE, LARGE_PAGE };
|
||||
|
||||
struct Type_1 : Bitfield<1, 1> { };
|
||||
@ -150,9 +151,9 @@ namespace Genode
|
||||
/**
|
||||
* Large page descriptor structure
|
||||
*
|
||||
* \detail Must always occur as group of 16 consecutive copies, this
|
||||
* groups must be aligned on a 16 word boundary (Represents
|
||||
* 64KB = 16 * Small page size)
|
||||
* Must always occur as group of 16 consecutive copies, this groups
|
||||
* must be aligned on a 16 word boundary (Represents 64KB = 16 *
|
||||
* Small page size)
|
||||
*/
|
||||
struct Large_page : Descriptor
|
||||
{
|
||||
@ -160,17 +161,17 @@ namespace Genode
|
||||
VIRT_SIZE = 1 << VIRT_SIZE_LOG2,
|
||||
VIRT_BASE_MASK = ~((1 << VIRT_SIZE_LOG2) - 1) };
|
||||
|
||||
struct B : Bitfield<2, 1> { }; /* Part of the memory region attributes */
|
||||
struct C : Bitfield<3, 1> { }; /* Part of the memory region attributes */
|
||||
struct Ap_1_0 : Bitfield<4, 2>, /* Access permission bits [1:0] */
|
||||
struct B : Bitfield<2, 1> { }; /* part of the memory region attributes */
|
||||
struct C : Bitfield<3, 1> { }; /* part of the memory region attributes */
|
||||
struct Ap_1_0 : Bitfield<4, 2>, /* access permission bits [1:0] */
|
||||
Ap_1_0_bitfield { };
|
||||
struct Ap_2 : Bitfield<9, 1>, /* Access permission bits [2] */
|
||||
struct Ap_2 : Bitfield<9, 1>, /* access permission bits [2] */
|
||||
Ap_2_bitfield { };
|
||||
struct S : Bitfield<10, 1> { }; /* Shareable bit */
|
||||
struct Ng : Bitfield<11, 1> { }; /* Not global bit */
|
||||
struct Tex : Bitfield<12, 3> { }; /* Part of the memory region attributes */
|
||||
struct Xn : Bitfield<15, 1> { }; /* Execute never bit */
|
||||
struct Pa_31_16 : Bitfield<16, 16> { }; /* Physical address bits [31:16] */
|
||||
struct S : Bitfield<10, 1> { }; /* shareable bit */
|
||||
struct Ng : Bitfield<11, 1> { }; /* not global bit */
|
||||
struct Tex : Bitfield<12, 3> { }; /* part of the memory region attributes */
|
||||
struct Xn : Bitfield<15, 1> { }; /* execute never bit */
|
||||
struct Pa_31_16 : Bitfield<16, 16> { }; /* physical address bits [31:16] */
|
||||
};
|
||||
|
||||
/**
|
||||
@ -184,25 +185,25 @@ namespace Genode
|
||||
VIRT_BASE_MASK = ~((1 << VIRT_SIZE_LOG2) - 1)
|
||||
};
|
||||
|
||||
struct Xn : Bitfield<0, 1> { }; /* Execute never bit */
|
||||
struct B : Bitfield<2, 1> { }; /* Part of the memory region attributes */
|
||||
struct C : Bitfield<3, 1> { }; /* Part of the memory region attributes */
|
||||
struct Ap_1_0 : Bitfield<4, 2>, /* Access permission bits [1:0] */
|
||||
struct Xn : Bitfield<0, 1> { }; /* execute never bit */
|
||||
struct B : Bitfield<2, 1> { }; /* part of the memory region attributes */
|
||||
struct C : Bitfield<3, 1> { }; /* part of the memory region attributes */
|
||||
struct Ap_1_0 : Bitfield<4, 2>, /* access permission bits [1:0] */
|
||||
Ap_1_0_bitfield { };
|
||||
struct Tex : Bitfield<6, 3> { }; /* Part of the memory region attributes */
|
||||
struct Ap_2 : Bitfield<9, 1>, /* Access permission bits [2] */
|
||||
struct Tex : Bitfield<6, 3> { }; /* part of the memory region attributes */
|
||||
struct Ap_2 : Bitfield<9, 1>, /* access permission bits [2] */
|
||||
Ap_2_bitfield { };
|
||||
struct S : Bitfield<10, 1> { }; /* Shareable bit */
|
||||
struct Ng : Bitfield<11, 1> { }; /* Not global bit */
|
||||
struct Pa_31_12 : Bitfield<12, 20> { }; /* Physical address bits [31:12] */
|
||||
struct S : Bitfield<10, 1> { }; /* shareable bit */
|
||||
struct Ng : Bitfield<11, 1> { }; /* not global bit */
|
||||
struct Pa_31_12 : Bitfield<12, 20> { }; /* physical address bits [31:12] */
|
||||
|
||||
/**
|
||||
* Permission configuration according to given access rights
|
||||
*
|
||||
* \param r Readability
|
||||
* \param w Writeability
|
||||
* \param x Executability
|
||||
* \return Descriptor value configured with appropriate
|
||||
* \param r readability
|
||||
* \param w writeability
|
||||
* \param x executability
|
||||
* \return descriptor value configured with appropriate
|
||||
* access permissions and the rest left zero
|
||||
*/
|
||||
static access_t access_permission_bits(bool const r,
|
||||
@ -227,8 +228,11 @@ namespace Genode
|
||||
}
|
||||
};
|
||||
|
||||
/* Table payload
|
||||
* Attention: Must be the only member of this class */
|
||||
/*
|
||||
* Table payload
|
||||
*
|
||||
* Attention: Must be the only member of this class
|
||||
*/
|
||||
Descriptor::access_t _entries[SIZE/sizeof(Descriptor::access_t)];
|
||||
|
||||
enum { MAX_INDEX = sizeof(_entries) / sizeof(_entries[0]) - 1 };
|
||||
@ -236,9 +240,9 @@ namespace Genode
|
||||
/**
|
||||
* Get entry index by virtual offset
|
||||
*
|
||||
* \param i Is overridden with the resulting index
|
||||
* \param vo Virtual offset relative to the virtual table base
|
||||
* \retval <0 If virtual offset couldn't be resolved,
|
||||
* \param i is overridden with the resulting index
|
||||
* \param vo virtual offset relative to the virtual table base
|
||||
* \retval <0 if virtual offset couldn't be resolved,
|
||||
* in this case 'i' reside invalid
|
||||
*/
|
||||
int _index_by_vo (unsigned long & i, addr_t const vo) const
|
||||
@ -260,15 +264,15 @@ namespace Genode
|
||||
*/
|
||||
Page_table()
|
||||
{
|
||||
/* Check table alignment */
|
||||
/* check table alignment */
|
||||
if (!aligned((addr_t)this, ALIGNM_LOG2)
|
||||
|| (addr_t)this != (addr_t)_entries)
|
||||
{
|
||||
|| (addr_t)this != (addr_t)_entries) {
|
||||
|
||||
PDBG("Insufficient table alignment");
|
||||
while (1) ;
|
||||
}
|
||||
|
||||
/* Start with an empty table */
|
||||
/* start with an empty table */
|
||||
for (unsigned i = 0; i <= MAX_INDEX; i++)
|
||||
Descriptor::invalidate(_entries[i]);
|
||||
}
|
||||
@ -285,43 +289,47 @@ namespace Genode
|
||||
/**
|
||||
* Insert one atomic translation into this table
|
||||
*
|
||||
* \param vo Offset of the virtual region represented
|
||||
* \param vo offset of the virtual region represented
|
||||
* by the translation within the virtual
|
||||
* region represented by this table
|
||||
* \param pa Base of the physical backing store
|
||||
* \param size_log2 Log2(Size of the translated region),
|
||||
* \param pa base of the physical backing store
|
||||
* \param size_log2 log2(Size of the translated region),
|
||||
* must be supported by this table
|
||||
* \param r Shall one can read trough this translation
|
||||
* \param w Shall one can write trough this translation
|
||||
* \param x Shall one can execute trough this
|
||||
* \param r shall one can read trough this translation
|
||||
* \param w shall one can write trough this translation
|
||||
* \param x shall one can execute trough this
|
||||
* translation
|
||||
*
|
||||
* \detail This method overrides an existing translation in case
|
||||
* that it spans the the same virtual range and is not
|
||||
* a link to another table level
|
||||
* This method overrides an existing translation in case that it
|
||||
* spans the the same virtual range and is not a link to another
|
||||
* table level.
|
||||
*/
|
||||
void insert_translation (addr_t const vo, addr_t const pa,
|
||||
unsigned long const size_log2,
|
||||
bool const r, bool const w, bool const x,
|
||||
bool const global)
|
||||
{
|
||||
/* Validate virtual address */
|
||||
/* validate virtual address */
|
||||
unsigned long i;
|
||||
if (_index_by_vo (i, vo)) {
|
||||
PDBG("Invalid virtual offset");
|
||||
while (1) ;
|
||||
}
|
||||
/* Select descriptor type by the translation size */
|
||||
if (size_log2 == Small_page::VIRT_SIZE_LOG2)
|
||||
{
|
||||
/* Can we write to the targeted entry? */
|
||||
|
||||
/* select descriptor type by the translation size */
|
||||
if (size_log2 == Small_page::VIRT_SIZE_LOG2) {
|
||||
|
||||
/*
|
||||
* Can we write to the targeted entry?
|
||||
*/
|
||||
if (Descriptor::valid(_entries[i]) &&
|
||||
Descriptor::type(_entries[i]) != Descriptor::SMALL_PAGE)
|
||||
{
|
||||
PDBG("Couldn't override entry");
|
||||
while (1) ;
|
||||
}
|
||||
/* Compose descriptor */
|
||||
|
||||
/* compose descriptor */
|
||||
_entries[i] = Small_page::access_permission_bits(r, w, x)
|
||||
| Small_page::Ng::bits(!global)
|
||||
| Small_page::Pa_31_12::masked(pa);
|
||||
@ -335,25 +343,32 @@ namespace Genode
|
||||
/**
|
||||
* Remove translations, wich overlap with a given virtual region
|
||||
*
|
||||
* \param vo Offset of the virtual region within the region
|
||||
* \param vo offset of the virtual region within the region
|
||||
* represented by this table
|
||||
* \param size Region size
|
||||
* \param size region size
|
||||
*/
|
||||
void remove_region (addr_t const vo, size_t const size)
|
||||
{
|
||||
/* Traverse all possibly affected entries */
|
||||
/* traverse all possibly affected entries */
|
||||
addr_t residual_vo = vo;
|
||||
unsigned long i;
|
||||
while (1)
|
||||
{
|
||||
/* Is anything left over to remove? */
|
||||
/*
|
||||
* Is anything left over to remove?
|
||||
*/
|
||||
if (residual_vo >= vo + size) return;
|
||||
|
||||
/* Does the residual region overlap with the region
|
||||
* represented by this table? */
|
||||
/*
|
||||
* Does the residual region overlap with the region
|
||||
* represented by this table?
|
||||
*/
|
||||
if (_index_by_vo(i, residual_vo)) return;
|
||||
|
||||
/* Update current entry and recalculate the residual region */
|
||||
/*
|
||||
* Update current entry and recalculate the residual
|
||||
* region.
|
||||
*/
|
||||
switch (Descriptor::type(_entries[i]))
|
||||
{
|
||||
case Descriptor::FAULT:
|
||||
@ -396,12 +411,11 @@ namespace Genode
|
||||
/**
|
||||
* Cortex A9 first level translation table
|
||||
*
|
||||
* \detail A table is dedicated to either secure or non-secure
|
||||
* mode. All translations done by this table apply
|
||||
* domain 0. They are not shareable and have zero-filled
|
||||
* memory region attributes. The size of this table is fixed
|
||||
* to such a value that this table translates a space wich is
|
||||
* addressable by 32 bit.
|
||||
* A table is dedicated to either secure or non-secure mode. All
|
||||
* translations done by this table apply domain 0. They are not shareable
|
||||
* and have zero-filled memory region attributes. The size of this table is
|
||||
* fixed to such a value that this table translates a space wich is
|
||||
* addressable by 32 bit.
|
||||
*/
|
||||
class Section_table
|
||||
{
|
||||
@ -435,11 +449,13 @@ namespace Genode
|
||||
*/
|
||||
struct Descriptor : Register<32>
|
||||
{
|
||||
/* Descriptor types */
|
||||
/**
|
||||
* Descriptor types
|
||||
*/
|
||||
enum Type { FAULT, PAGE_TABLE, SECTION, SUPERSECTION };
|
||||
|
||||
struct Type_1 : Bitfield<0, 2> { }; /* Entry type encoding 1 */
|
||||
struct Type_2 : Bitfield<18, 1> { }; /* Entry type encoding 2 */
|
||||
struct Type_1 : Bitfield<0, 2> { }; /* entry type encoding 1 */
|
||||
struct Type_2 : Bitfield<18, 1> { }; /* entry type encoding 2 */
|
||||
|
||||
/**
|
||||
* Get descriptor type of 'v'
|
||||
@ -503,16 +519,16 @@ namespace Genode
|
||||
*/
|
||||
struct Page_table_descriptor : Descriptor
|
||||
{
|
||||
struct Ns : Bitfield<3, 1> { }; /* Non-secure bit */
|
||||
struct Domain : Bitfield<5, 4> { }; /* Domain field */
|
||||
struct Pa_31_10 : Bitfield<10, 22> { }; /* Physical address bits [31:10] */
|
||||
struct Ns : Bitfield<3, 1> { }; /* non-secure bit */
|
||||
struct Domain : Bitfield<5, 4> { }; /* domain field */
|
||||
struct Pa_31_10 : Bitfield<10, 22> { }; /* physical address bits [31:10] */
|
||||
};
|
||||
|
||||
/**
|
||||
* Supersection-descriptor structure
|
||||
*
|
||||
* \detail Must always occur as group of 16 consecutive copies, this
|
||||
* groups must be aligned on a 16 word boundary.
|
||||
* Must always occur as group of 16 consecutive copies, this groups
|
||||
* must be aligned on a 16 word boundary.
|
||||
*/
|
||||
struct Supersection : Descriptor
|
||||
{
|
||||
@ -522,20 +538,20 @@ namespace Genode
|
||||
VIRT_BASE_MASK = ~((1 << VIRT_SIZE_LOG2) - 1)
|
||||
};
|
||||
|
||||
struct B : Bitfield<2, 1> { }; /* Part of the memory region attributes */
|
||||
struct C : Bitfield<3, 1> { }; /* Part of the memory region attributes */
|
||||
struct Xn : Bitfield<4, 1> { }; /* Execute never bit */
|
||||
struct Pa_39_36 : Bitfield<5, 4> { }; /* Extendend physical address bits [39:36] */
|
||||
struct Ap_1_0 : Bitfield<10, 2>, /* Access permission bits [1:0] */
|
||||
struct B : Bitfield<2, 1> { }; /* part of the memory region attributes */
|
||||
struct C : Bitfield<3, 1> { }; /* part of the memory region attributes */
|
||||
struct Xn : Bitfield<4, 1> { }; /* execute never bit */
|
||||
struct Pa_39_36 : Bitfield<5, 4> { }; /* extendend physical address bits [39:36] */
|
||||
struct Ap_1_0 : Bitfield<10, 2>, /* access permission bits [1:0] */
|
||||
Ap_1_0_bitfield { };
|
||||
struct Tex : Bitfield<12, 3> { }; /* Part of the memory region attributes */
|
||||
struct Ap_2 : Bitfield<15, 1>, /* Access permission bits [2] */
|
||||
struct Tex : Bitfield<12, 3> { }; /* part of the memory region attributes */
|
||||
struct Ap_2 : Bitfield<15, 1>, /* access permission bits [2] */
|
||||
Ap_2_bitfield { };
|
||||
struct S : Bitfield<16, 1> { }; /* Shareable bit */
|
||||
struct Ng : Bitfield<17, 1> { }; /* Not global bit */
|
||||
struct Ns : Bitfield<19, 1> { }; /* Non-secure bit */
|
||||
struct Pa_35_32 : Bitfield<20, 4> { }; /* Extendend physical address bits [35:32] */
|
||||
struct Pa_31_24 : Bitfield<24, 8> { }; /* Physical address bits [31:24] */
|
||||
struct S : Bitfield<16, 1> { }; /* shareable bit */
|
||||
struct Ng : Bitfield<17, 1> { }; /* not global bit */
|
||||
struct Ns : Bitfield<19, 1> { }; /* non-secure bit */
|
||||
struct Pa_35_32 : Bitfield<20, 4> { }; /* extendend physical address bits [35:32] */
|
||||
struct Pa_31_24 : Bitfield<24, 8> { }; /* physical address bits [31:24] */
|
||||
};
|
||||
|
||||
/**
|
||||
@ -549,27 +565,27 @@ namespace Genode
|
||||
VIRT_BASE_MASK = ~((1 << VIRT_SIZE_LOG2) - 1)
|
||||
};
|
||||
|
||||
struct B : Bitfield<2, 1> { }; /* Part of the memory region attributes */
|
||||
struct C : Bitfield<3, 1> { }; /* Part of the memory region attributes */
|
||||
struct Xn : Bitfield<4, 1> { }; /* Execute never bit */
|
||||
struct Domain : Bitfield<5, 4> { }; /* Domain field */
|
||||
struct Ap_1_0 : Bitfield<10, 2>, /* Access permission bits [1:0] */
|
||||
struct B : Bitfield<2, 1> { }; /* part of the memory region attributes */
|
||||
struct C : Bitfield<3, 1> { }; /* part of the memory region attributes */
|
||||
struct Xn : Bitfield<4, 1> { }; /* execute never bit */
|
||||
struct Domain : Bitfield<5, 4> { }; /* domain field */
|
||||
struct Ap_1_0 : Bitfield<10, 2>, /* access permission bits [1:0] */
|
||||
Ap_1_0_bitfield { };
|
||||
struct Tex : Bitfield<12, 3> { }; /* Part of the memory region attributes */
|
||||
struct Ap_2 : Bitfield<15, 1>, /* Access permission bits [2] */
|
||||
struct Tex : Bitfield<12, 3> { }; /* part of the memory region attributes */
|
||||
struct Ap_2 : Bitfield<15, 1>, /* access permission bits [2] */
|
||||
Ap_2_bitfield { };
|
||||
struct S : Bitfield<16, 1> { }; /* Shareable bit */
|
||||
struct Ng : Bitfield<17, 1> { }; /* Not global bit */
|
||||
struct Ns : Bitfield<19, 1> { }; /* Non-secure bit */
|
||||
struct Pa_31_20 : Bitfield<20, 12> { }; /* Physical address bits [31:20] */
|
||||
struct S : Bitfield<16, 1> { }; /* shareable bit */
|
||||
struct Ng : Bitfield<17, 1> { }; /* not global bit */
|
||||
struct Ns : Bitfield<19, 1> { }; /* non-secure bit */
|
||||
struct Pa_31_20 : Bitfield<20, 12> { }; /* physical address bits [31:20] */
|
||||
|
||||
/**
|
||||
* Permission configuration according to given access rights
|
||||
*
|
||||
* \param r Readability
|
||||
* \param w Writeability
|
||||
* \param x Executability
|
||||
* \return Descriptor value configured with appropriate
|
||||
* \param r readability
|
||||
* \param w writeability
|
||||
* \param x executability
|
||||
* \return descriptor value configured with appropriate
|
||||
* access permissions and the rest left zero
|
||||
*/
|
||||
static access_t access_permission_bits(bool const r,
|
||||
@ -594,22 +610,25 @@ namespace Genode
|
||||
}
|
||||
};
|
||||
|
||||
/* Table payload
|
||||
* Attention: Must be the first member of this class */
|
||||
/*
|
||||
* Table payload
|
||||
*
|
||||
* Attention: Must be the first member of this class
|
||||
*/
|
||||
Descriptor::access_t _entries[SIZE/sizeof(Descriptor::access_t)];
|
||||
|
||||
enum { MAX_INDEX = sizeof(_entries) / sizeof(_entries[0]) - 1 };
|
||||
|
||||
/* Is this table dedicated to secure mode or to non-secure mode */
|
||||
/* is this table dedicated to secure mode or to non-secure mode */
|
||||
bool _secure;
|
||||
|
||||
/**
|
||||
* Get entry index by virtual offset
|
||||
*
|
||||
* \param i Is overridden with the resulting index
|
||||
* \param vo Offset within the virtual region represented
|
||||
* \param i is overridden with the resulting index
|
||||
* \param vo offset within the virtual region represented
|
||||
* by this table
|
||||
* \retval <0 If virtual offset couldn't be resolved,
|
||||
* \retval <0 if virtual offset couldn't be resolved,
|
||||
* in this case 'i' reside invalid
|
||||
*/
|
||||
int _index_by_vo(unsigned long & i, addr_t const vo) const
|
||||
@ -626,15 +645,15 @@ namespace Genode
|
||||
*/
|
||||
Section_table() : _secure(Cortex_a9::secure_mode_active())
|
||||
{
|
||||
/* Check table alignment */
|
||||
/* check table alignment */
|
||||
if (!aligned((addr_t)this, ALIGNM_LOG2)
|
||||
|| (addr_t)this != (addr_t)_entries)
|
||||
{
|
||||
|| (addr_t)this != (addr_t)_entries) {
|
||||
|
||||
PDBG("Insufficient table alignment");
|
||||
while (1) ;
|
||||
}
|
||||
|
||||
/* Start with an empty table */
|
||||
/* start with an empty table */
|
||||
for (unsigned i = 0; i <= MAX_INDEX; i++)
|
||||
Descriptor::invalidate(_entries[i]);
|
||||
}
|
||||
@ -651,17 +670,17 @@ namespace Genode
|
||||
/**
|
||||
* Insert one atomic translation into this table
|
||||
*
|
||||
* \param vo Offset of the virtual region represented
|
||||
* \param vo offset of the virtual region represented
|
||||
* by the translation within the virtual
|
||||
* region represented by this table
|
||||
* \param pa Base of the physical backing store
|
||||
* \param size_log2 Size log2 of the translated region
|
||||
* \param r Shall one can read trough this translation
|
||||
* \param w Shall one can write trough this translation
|
||||
* \param x Shall one can execute trough this translation
|
||||
* \param global Shall the translation apply to all
|
||||
* \param pa base of the physical backing store
|
||||
* \param size_log2 size log2 of the translated region
|
||||
* \param r shall one can read trough this translation
|
||||
* \param w shall one can write trough this translation
|
||||
* \param x shall one can execute trough this translation
|
||||
* \param global shall the translation apply to all
|
||||
* address spaces
|
||||
* \param extra_space If > 0 it must point to a portion of
|
||||
* \param extra_space If > 0, it must point to a portion of
|
||||
* size-aligned memory space wich may be used
|
||||
* furthermore by the table for the incurring
|
||||
* administrative costs of the translation.
|
||||
@ -669,16 +688,16 @@ namespace Genode
|
||||
* needed memory one can instrument this
|
||||
* method with 'extra_space' set to 0.
|
||||
* The so donated memory may be regained by
|
||||
* using the method 'regain_memory'
|
||||
* \retval 0 Translation successfully inserted
|
||||
* \retval >0 Translation not inserted, the return value
|
||||
* using the method 'regain_memory'.
|
||||
* \retval 0 translation successfully inserted
|
||||
* \retval >0 translation not inserted, the return value
|
||||
* is the size log2 of additional size-aligned
|
||||
* space that is needed to do the translation.
|
||||
* This occurs solely when 'extra_space' is 0.
|
||||
*
|
||||
* \detail This method overrides an existing translation in case
|
||||
* that it spans the the same virtual range and is not
|
||||
* a link to another table level
|
||||
* This method overrides an existing translation in case that it
|
||||
* spans the the same virtual range and is not a link to another
|
||||
* table level.
|
||||
*/
|
||||
unsigned long insert_translation (addr_t const vo, addr_t const pa,
|
||||
unsigned long const size_log2,
|
||||
@ -686,34 +705,42 @@ namespace Genode
|
||||
bool const x, bool const global,
|
||||
void * const extra_space = 0)
|
||||
{
|
||||
/* Validate virtual address */
|
||||
/* validate virtual address */
|
||||
unsigned long i;
|
||||
if (_index_by_vo (i, vo)) {
|
||||
PDBG("Invalid virtual offset");
|
||||
while (1) ;
|
||||
}
|
||||
|
||||
/* Select descriptor type by translation size */
|
||||
if (size_log2 < Section::VIRT_SIZE_LOG2)
|
||||
{
|
||||
/* select descriptor type by translation size */
|
||||
if (size_log2 < Section::VIRT_SIZE_LOG2) {
|
||||
|
||||
Page_table * pt;
|
||||
|
||||
/* Does an appropriate page table already exist? */
|
||||
if (Descriptor::type(_entries[i]) == Descriptor::PAGE_TABLE)
|
||||
{
|
||||
/*
|
||||
* Does an appropriate page table already exist?
|
||||
*/
|
||||
if (Descriptor::type(_entries[i]) == Descriptor::PAGE_TABLE) {
|
||||
pt = (Page_table *)(addr_t)
|
||||
Page_table_descriptor::Pa_31_10::masked(_entries[i]);
|
||||
}
|
||||
/* Is there some extra space to create a page table? */
|
||||
else if (extra_space)
|
||||
{
|
||||
/* Can we write to the targeted entry? */
|
||||
|
||||
/*
|
||||
* Is there some extra space to create a page table?
|
||||
*/
|
||||
else if (extra_space) {
|
||||
|
||||
/*
|
||||
* Can we write to the targeted entry?
|
||||
*/
|
||||
if (Descriptor::valid(_entries[i])) {
|
||||
PDBG ("Couldn't override entry");
|
||||
while (1) ;
|
||||
}
|
||||
/* Create and link page table,
|
||||
* the page table checks alignment by itself */
|
||||
/*
|
||||
* Create and link page table. The page table checks
|
||||
* alignment by itself.
|
||||
*/
|
||||
pt = new (extra_space) Page_table();
|
||||
_entries[i] = Page_table_descriptor::Ns::bits(!_secure)
|
||||
| Page_table_descriptor::Pa_31_10::masked((addr_t)pt);
|
||||
@ -722,14 +749,16 @@ namespace Genode
|
||||
/* Request additional memory to create a page table */
|
||||
else return Page_table::SIZE_LOG2;
|
||||
|
||||
/* Insert translation */
|
||||
/* insert translation */
|
||||
pt->insert_translation(vo - Section::Pa_31_20::masked(vo),
|
||||
pa, size_log2, r, w, x, global);
|
||||
return 0;
|
||||
}
|
||||
if (size_log2 == Section::VIRT_SIZE_LOG2)
|
||||
{
|
||||
/* Can we write to the targeted entry? */
|
||||
if (size_log2 == Section::VIRT_SIZE_LOG2) {
|
||||
|
||||
/*
|
||||
* Can we write to the targeted entry?
|
||||
*/
|
||||
if (Descriptor::valid(_entries[i]) &&
|
||||
Descriptor::type(_entries[i]) != Descriptor::SECTION)
|
||||
{
|
||||
@ -737,7 +766,7 @@ namespace Genode
|
||||
while (1) ;
|
||||
}
|
||||
|
||||
/* Compose section descriptor */
|
||||
/* compose section descriptor */
|
||||
_entries[i] = Section::access_permission_bits(r, w, x)
|
||||
| Section::Ns::bits(!_secure)
|
||||
| Section::Ng::bits(!global)
|
||||
@ -752,25 +781,32 @@ namespace Genode
|
||||
/**
|
||||
* Remove translations, wich overlap with a given virtual region
|
||||
*
|
||||
* \param vo Offset of the virtual region within the region
|
||||
* \param vo offset of the virtual region within the region
|
||||
* represented by this table
|
||||
* \param size Region size
|
||||
* \param size region size
|
||||
*/
|
||||
void remove_region (addr_t const vo, size_t const size)
|
||||
{
|
||||
/* Traverse all possibly affected entries */
|
||||
/* traverse all possibly affected entries */
|
||||
addr_t residual_vo = vo;
|
||||
unsigned long i;
|
||||
while (1)
|
||||
{
|
||||
/* Is anything left over to remove? */
|
||||
/*
|
||||
* Is anything left over to remove?
|
||||
*/
|
||||
if (residual_vo >= vo + size) return;
|
||||
|
||||
/* Does the residual region overlap with the region
|
||||
* represented by this table? */
|
||||
/*
|
||||
* Does the residual region overlap with the region
|
||||
* represented by this table?
|
||||
*/
|
||||
if (_index_by_vo(i, residual_vo)) return;
|
||||
|
||||
/* Update current entry and recalculate the residual region */
|
||||
/*
|
||||
* Update current entry and recalculate the residual
|
||||
* region.
|
||||
*/
|
||||
switch (Descriptor::type(_entries[i]))
|
||||
{
|
||||
case Descriptor::FAULT:
|
||||
@ -781,7 +817,7 @@ namespace Genode
|
||||
}
|
||||
case Descriptor::PAGE_TABLE:
|
||||
{
|
||||
/* Instruct page table to remove residual region */
|
||||
/* instruct page table to remove residual region */
|
||||
Page_table * const pt = (Page_table *)
|
||||
(addr_t)Page_table_descriptor::Pa_31_10::masked(_entries[i]);
|
||||
size_t const residual_size = vo + size - residual_vo;
|
||||
@ -814,21 +850,22 @@ namespace Genode
|
||||
/**
|
||||
* Get a portion of memory that is no longer used by this table
|
||||
*
|
||||
* \param base Base of regained memory portion if method returns 1
|
||||
* \param s Size of regained memory portion if method returns 1
|
||||
* \param base base of regained memory portion if method returns 1
|
||||
* \param s size of regained memory portion if method returns 1
|
||||
*/
|
||||
bool regain_memory (void * & base, size_t & s)
|
||||
{
|
||||
/* Walk through all entries */
|
||||
/* walk through all entries */
|
||||
for (unsigned i = 0; i <= MAX_INDEX; i++)
|
||||
{
|
||||
if (Descriptor::type(_entries[i]) == Descriptor::PAGE_TABLE)
|
||||
{
|
||||
if (Descriptor::type(_entries[i]) == Descriptor::PAGE_TABLE) {
|
||||
|
||||
Page_table * const pt = (Page_table *)
|
||||
(addr_t)Page_table_descriptor::Pa_31_10::masked(_entries[i]);
|
||||
if (pt->empty())
|
||||
{
|
||||
/* We've found an useless page table */
|
||||
|
||||
if (pt->empty()) {
|
||||
|
||||
/* we've found an useless page table */
|
||||
Descriptor::invalidate(_entries[i]);
|
||||
base = (void *)pt;
|
||||
s = sizeof(Page_table);
|
||||
@ -841,5 +878,5 @@ namespace Genode
|
||||
} __attribute__((aligned(1<<Section_table::ALIGNM_LOG2)));
|
||||
}
|
||||
|
||||
#endif /* _BASE__INCLUDE__DRIVERS__CPU__CORTEX_A9__SECTION_TABLE_H_ */
|
||||
#endif /* _INCLUDE__DRIVERS__CPU__CORTEX_A9__SECTION_TABLE_H_ */
|
||||
|
||||
|
@ -11,8 +11,8 @@
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _BASE__INCLUDE__DRIVERS__CPU__CORTEX_A9__TIMER_H_
|
||||
#define _BASE__INCLUDE__DRIVERS__CPU__CORTEX_A9__TIMER_H_
|
||||
#ifndef _INCLUDE__DRIVERS__CPU__CORTEX_A9__TIMER_H_
|
||||
#define _INCLUDE__DRIVERS__CPU__CORTEX_A9__TIMER_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <util/mmio.h>
|
||||
@ -28,7 +28,7 @@ namespace Genode
|
||||
enum { TICS_PER_MS = CLK / 1000, };
|
||||
|
||||
/**
|
||||
* Load value rgeister
|
||||
* Load value register
|
||||
*/
|
||||
struct Load : Register<0x0, 32> { };
|
||||
|
||||
@ -96,17 +96,17 @@ namespace Genode
|
||||
template <unsigned long CLOCK>
|
||||
void Genode::Cortex_a9_timer<CLOCK>::start_one_shot(uint32_t const tics)
|
||||
{
|
||||
/* Reset timer */
|
||||
/* reset timer */
|
||||
clear_interrupt();
|
||||
write<Control>(Control::Timer_enable::bits(0) |
|
||||
Control::Auto_reload::bits(0) |
|
||||
Control::Irq_enable::bits(1) |
|
||||
Control::Prescaler::bits(0));
|
||||
|
||||
/* Load timer and start decrementing */
|
||||
/* load timer and start decrementing */
|
||||
write<Load>(tics);
|
||||
write<typename Control::Timer_enable>(1);
|
||||
}
|
||||
|
||||
|
||||
#endif /* _BASE__INCLUDE__DRIVERS__CPU__CORTEX_A9__TIMER_H_ */
|
||||
#endif /* _INCLUDE__DRIVERS__CPU__CORTEX_A9__TIMER_H_ */
|
||||
|
@ -11,8 +11,8 @@
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _BASE__INCLUDE__DRIVERS__PIC__PL390_BASE_H_
|
||||
#define _BASE__INCLUDE__DRIVERS__PIC__PL390_BASE_H_
|
||||
#ifndef _INCLUDE__DRIVERS__PIC__PL390_BASE_H_
|
||||
#define _INCLUDE__DRIVERS__PIC__PL390_BASE_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <util/mmio.h>
|
||||
@ -208,16 +208,16 @@ namespace Genode
|
||||
_max_interrupt(_distr.max_interrupt()),
|
||||
_last_taken_request(SPURIOUS_ID)
|
||||
{
|
||||
/* Disable device */
|
||||
/* disable device */
|
||||
_distr.write<Distr::Icddcr::Enable>(0);
|
||||
_cpu.write<Cpu::Iccicr::Enable>(0);
|
||||
mask();
|
||||
|
||||
/* Supported priority range */
|
||||
/* supported priority range */
|
||||
unsigned const min_prio = _distr.min_priority();
|
||||
unsigned const max_prio = _distr.max_priority();
|
||||
|
||||
/* Configure every shared peripheral interrupt */
|
||||
/* configure every shared peripheral interrupt */
|
||||
for (unsigned i=MIN_SPI; i <= _max_interrupt; i++)
|
||||
{
|
||||
_distr.write<Distr::Icdicr::Edge_triggered>(0, i);
|
||||
@ -225,14 +225,14 @@ namespace Genode
|
||||
_distr.write<Distr::Icdiptr::Cpu_targets>(Distr::Icdiptr::Cpu_targets::ALL, i);
|
||||
}
|
||||
|
||||
/* Disable the priority filter */
|
||||
/* disable the priority filter */
|
||||
_cpu.write<Cpu::Iccpmr::Priority>(min_prio);
|
||||
|
||||
/* Disable preemption of interrupt handling by interrupts */
|
||||
/* disable preemption of interrupt handling by interrupts */
|
||||
_cpu.write<Cpu::Iccbpr::Binary_point>(
|
||||
Cpu::Iccbpr::Binary_point::NO_PREEMPTION);
|
||||
|
||||
/* Enable device */
|
||||
/* enable device */
|
||||
_distr.write<Distr::Icddcr::Enable>(1);
|
||||
_cpu.write<Cpu::Iccicr::Enable>(1);
|
||||
}
|
||||
@ -304,5 +304,5 @@ namespace Genode
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _BASE__INCLUDE__DRIVERS__PIC__PL390_BASE_H_ */
|
||||
#endif /* _INCLUDE__DRIVERS__PIC__PL390_BASE_H_ */
|
||||
|
||||
|
@ -11,8 +11,8 @@
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _BASE__INCLUDE__DRIVERS__TIMER__SP804_H_
|
||||
#define _BASE__INCLUDE__DRIVERS__TIMER__SP804_H_
|
||||
#ifndef _INCLUDE__DRIVERS__TIMER__SP804_H_
|
||||
#define _INCLUDE__DRIVERS__TIMER__SP804_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <util/mmio.h>
|
||||
@ -22,7 +22,7 @@ namespace Genode
|
||||
/**
|
||||
* Basic driver for the ARM SP804 timer
|
||||
*
|
||||
* \detail Uses only timer module 0
|
||||
* Uses only timer module 0.
|
||||
*/
|
||||
template <unsigned long CLK>
|
||||
class Sp804_base : public Mmio
|
||||
@ -84,12 +84,12 @@ namespace Genode
|
||||
* Run the timer in order that it raises IRQ when
|
||||
* it reaches zero, then stop
|
||||
*
|
||||
* \param tics Native timer value used to assess the delay
|
||||
* \param tics native timer value used to assess the delay
|
||||
* of the timer interrupt as of this call
|
||||
*/
|
||||
void run_and_stop(unsigned long const tics)
|
||||
{
|
||||
/* Disable and configure timer for a one-shot */
|
||||
/* disable and configure timer for a one-shot */
|
||||
clear_interrupt();
|
||||
write<typename Control::Timer_en>(0);
|
||||
write<Control>(Control::Timer_en::bits(0) |
|
||||
@ -99,21 +99,21 @@ namespace Genode
|
||||
Control::Size::bits(1) |
|
||||
Control::Oneshot::bits(1));
|
||||
|
||||
/* Load value and enable timer */
|
||||
/* load value and enable timer */
|
||||
write<Load>(tics);
|
||||
write<typename Control::Timer_en>(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the timer in order that it raises IRQ when
|
||||
* it reaches zero, then wrap and continue
|
||||
* Run the timer in order that it raises IRQ when it reaches zero,
|
||||
* then wrap and continue
|
||||
*
|
||||
* \param tics Native timer value used to assess the delay
|
||||
* \param tics native timer value used to assess the delay
|
||||
* of the timer interrupt as of this call
|
||||
*/
|
||||
void run_and_wrap(unsigned long const tics)
|
||||
{
|
||||
/* Configure the timer in order that it reloads on 0 */
|
||||
/* configure the timer in order that it reloads on 0 */
|
||||
clear_interrupt();
|
||||
write<typename Control::Timer_en>(0);
|
||||
write<Control>(Control::Timer_en::bits(0) |
|
||||
@ -123,13 +123,15 @@ namespace Genode
|
||||
Control::Size::bits(1) |
|
||||
Control::Oneshot::bits(0));
|
||||
|
||||
/* Start timer with the inital value */
|
||||
/* start timer with the initial value */
|
||||
write<Load>(tics);
|
||||
write<typename Control::Timer_en>(1);
|
||||
|
||||
/* Ensure that the timer loads its max value instead of
|
||||
* the initial value when it reaches 0 in order that it
|
||||
* looks like it wraps */
|
||||
/*
|
||||
* Ensure that the timer loads its max value instead of the
|
||||
* initial value when it reaches 0 in order that it looks like
|
||||
* it wraps.
|
||||
*/
|
||||
write<Bgload>(max_value());
|
||||
}
|
||||
|
||||
@ -179,5 +181,5 @@ namespace Genode
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _BASE__INCLUDE__DRIVERS__TIMER__SP804_H_ */
|
||||
#endif /* _INCLUDE__DRIVERS__TIMER__SP804_H_ */
|
||||
|
||||
|
@ -11,8 +11,8 @@
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _BASE__INCLUDE__DRIVERS__UART__PL011_BASE_H_
|
||||
#define _BASE__INCLUDE__DRIVERS__UART__PL011_BASE_H_
|
||||
#ifndef _INCLUDE__DRIVERS__UART__PL011_BASE_H_
|
||||
#define _INCLUDE__DRIVERS__UART__PL011_BASE_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <util/mmio.h>
|
||||
@ -119,9 +119,9 @@ namespace Genode
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* \param base Device MMIO base
|
||||
* \param clock Device reference clock frequency
|
||||
* \param baud_rate Targeted UART baud rate
|
||||
* \param base device MMIO base
|
||||
* \param clock device reference clock frequency
|
||||
* \param baud_rate targeted UART baud rate
|
||||
*/
|
||||
inline Pl011_base(addr_t const base, uint32_t const clock,
|
||||
uint32_t const baud_rate);
|
||||
@ -141,16 +141,16 @@ Genode::Pl011_base::Pl011_base(addr_t const base, uint32_t const clock,
|
||||
Uartcr::Txe::bits(1) |
|
||||
Uartcr::Rxe::bits(1));
|
||||
|
||||
/**
|
||||
* We can't print an error or throw C++ exceptions
|
||||
* because we must expect both to be uninitialized yet,
|
||||
* so its better to hold the program counter in here for debugging
|
||||
/*
|
||||
* We can't print an error or throw C++ exceptions because we must expect
|
||||
* both to be uninitialized yet, so its better to hold the program counter
|
||||
* in here for debugging.
|
||||
*/
|
||||
if (baud_rate > MAX_BAUD_RATE) while(1) ;
|
||||
|
||||
/**
|
||||
* Calculate fractional and integer part of baud rate
|
||||
* divisor to initialize IBRD and FBRD
|
||||
/*
|
||||
* Calculate fractional and integer part of baud rate divisor to initialize
|
||||
* IBRD and FBRD.
|
||||
*/
|
||||
uint32_t const adjusted_br = baud_rate << 4;
|
||||
double const divisor = (double)clock / adjusted_br;
|
||||
@ -163,9 +163,7 @@ Genode::Pl011_base::Pl011_base(addr_t const base, uint32_t const clock,
|
||||
|
||||
write<Uartlcrh::Wlen>(Uartlcrh::Wlen::WORD_LENGTH_8BITS);
|
||||
|
||||
/**
|
||||
* Unmask all interrupts
|
||||
*/
|
||||
/* unmask all interrupts */
|
||||
write<Uartimsc::Imsc>(0);
|
||||
|
||||
_wait_until_ready();
|
||||
@ -174,16 +172,16 @@ Genode::Pl011_base::Pl011_base(addr_t const base, uint32_t const clock,
|
||||
|
||||
void Genode::Pl011_base::put_char(char const c)
|
||||
{
|
||||
/* Wait as long as the transmission buffer is full */
|
||||
/* wait as long as the transmission buffer is full */
|
||||
while (read<Uartfr::Txff>()) ;
|
||||
|
||||
/* Auto complete new line commands */
|
||||
/* auto complete new line commands */
|
||||
if (c == ASCII_LINE_FEED) write<Uartdr::Data>(ASCII_CARRIAGE_RETURN);
|
||||
|
||||
/* Transmit character */
|
||||
/* transmit character */
|
||||
write<Uartdr::Data>(c);
|
||||
_wait_until_ready();
|
||||
}
|
||||
|
||||
|
||||
#endif /* _BASE__INCLUDE__DRIVERS__UART__PL011_BASE_H_ */
|
||||
#endif /* _INCLUDE__DRIVERS__UART__PL011_BASE_H_ */
|
||||
|
@ -11,8 +11,8 @@
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _BASE__INCLUDE__DRIVERS__UART__TL16C750_BASE_H_
|
||||
#define _BASE__INCLUDE__DRIVERS__UART__TL16C750_BASE_H_
|
||||
#ifndef _INCLUDE__DRIVERS__UART__TL16C750_BASE_H_
|
||||
#define _INCLUDE__DRIVERS__UART__TL16C750_BASE_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <util/mmio.h>
|
||||
@ -27,8 +27,8 @@ namespace Genode
|
||||
/**
|
||||
* Base driver Texas instruments TL16C750 UART module
|
||||
*
|
||||
* \detail In contrast to the abilities of the TL16C750, this driver
|
||||
* targets only the basic UART functionalities.
|
||||
* In contrast to the abilities of the TL16C750, this driver targets only
|
||||
* the basic UART functionalities.
|
||||
*/
|
||||
class Tl16c750_base : public Mmio
|
||||
{
|
||||
@ -150,25 +150,27 @@ namespace Genode
|
||||
* Constructor
|
||||
*
|
||||
* \param base MMIO base address
|
||||
* \param clock Reference clock
|
||||
* \param baud_rate Targeted baud rate
|
||||
* \param clock reference clock
|
||||
* \param baud_rate targeted baud rate
|
||||
*/
|
||||
Tl16c750_base(addr_t const base, unsigned long const clock,
|
||||
unsigned long const baud_rate) : Mmio(base)
|
||||
{
|
||||
/* Reset and disable UART */
|
||||
/* reset and disable UART */
|
||||
write<Uart_sysc::Softreset>(1);
|
||||
while (!read<Uart_syss::Resetdone>()) ;
|
||||
write<Uart_mdr1::Mode_select>(Uart_mdr1::Mode_select::DISABLED);
|
||||
|
||||
/* Enable access to 'Uart_fcr' and 'Uart_ier' */
|
||||
/* enable access to 'Uart_fcr' and 'Uart_ier' */
|
||||
write<Uart_lcr::Reg_mode>(Uart_lcr::Reg_mode::OPERATIONAL);
|
||||
|
||||
/* Configure FIFOs, we don't use any interrupts or DMA,
|
||||
* thus FIFO trigger and DMA configurations are dispensable */
|
||||
/*
|
||||
* Configure FIFOs, we don't use any interrupts or DMA,
|
||||
* thus FIFO trigger and DMA configurations are dispensable.
|
||||
*/
|
||||
write<Uart_fcr::Fifo_enable>(1);
|
||||
|
||||
/* Disable interrupts and sleep mode */
|
||||
/* disable interrupts and sleep mode */
|
||||
write<Uart_ier>(Uart_ier::Rhr_it::bits(0)
|
||||
| Uart_ier::Thr_it::bits(0)
|
||||
| Uart_ier::Line_sts_it::bits(0)
|
||||
@ -178,11 +180,13 @@ namespace Genode
|
||||
| Uart_ier::Rts_it::bits(0)
|
||||
| Uart_ier::Cts_it::bits(0));
|
||||
|
||||
/* Enable access to 'Uart_dlh' and 'Uart_dll' */
|
||||
/* enable access to 'Uart_dlh' and 'Uart_dll' */
|
||||
write<Uart_lcr::Reg_mode>(Uart_lcr::Reg_mode::CONFIG_B);
|
||||
|
||||
/* Load the new divisor value (this driver solely uses
|
||||
* 'UART_16X' mode )*/
|
||||
/*
|
||||
* Load the new divisor value (this driver solely uses
|
||||
* 'UART_16X' mode)
|
||||
*/
|
||||
enum { UART_16X_DIVIDER_LOG2 = 4 };
|
||||
unsigned long const adjusted_br = baud_rate << UART_16X_DIVIDER_LOG2;
|
||||
double const divisor = (double)clock / adjusted_br;
|
||||
@ -190,16 +194,20 @@ namespace Genode
|
||||
write<Uart_dll::Clock_lsb>(divisor_uint);
|
||||
write<Uart_dlh::Clock_msb>(divisor_uint>>Uart_dll::Clock_lsb::WIDTH);
|
||||
|
||||
/* Configure protocol formatting and thereby return to
|
||||
* operational mode */
|
||||
/*
|
||||
* Configure protocol formatting and thereby return to
|
||||
* operational mode.
|
||||
*/
|
||||
write<Uart_lcr>(Uart_lcr::Char_length::bits(Uart_lcr::Char_length::_8_BIT)
|
||||
| Uart_lcr::Nb_stop::bits(Uart_lcr::Nb_stop::_1_STOP_BIT)
|
||||
| Uart_lcr::Parity_en::bits(0)
|
||||
| Uart_lcr::Break_en::bits(0)
|
||||
| Uart_lcr::Div_en::bits(0));
|
||||
|
||||
/* Switch to UART mode, we don't use hardware or software flow
|
||||
* control, thus according configurations are dispensable*/
|
||||
/*
|
||||
* Switch to UART mode, we don't use hardware or software flow
|
||||
* control, thus according configurations are dispensable
|
||||
*/
|
||||
write<Uart_mdr1::Mode_select>(Uart_mdr1::Mode_select::UART_16X);
|
||||
}
|
||||
|
||||
@ -208,18 +216,18 @@ namespace Genode
|
||||
*/
|
||||
void put_char(char const c)
|
||||
{
|
||||
/* Wait as long as the transmission buffer is full */
|
||||
/* wait as long as the transmission buffer is full */
|
||||
while (!read<Uart_lsr::Tx_fifo_empty>()) ;
|
||||
|
||||
/* Auto complete new line commands */
|
||||
/* auto complete new line commands */
|
||||
if (c == ASCII_LINE_FEED)
|
||||
write<Uart_thr::Thr>(ASCII_CARRIAGE_RETURN);
|
||||
|
||||
/* Transmit character */
|
||||
/* transmit character */
|
||||
write<Uart_thr::Thr>(c);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _BASE__INCLUDE__DRIVERS__UART__TL16C750_BASE_H_ */
|
||||
#endif /* _INCLUDE__DRIVERS__UART__TL16C750_BASE_H_ */
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user