hw: introduce memory regions and array

* replace Native_regions and inline code for iteration

Ref #2092
This commit is contained in:
Stefan Kalkowski 2016-10-06 20:07:16 +02:00 committed by Christian Helmuth
parent a97e92c7ec
commit d549921bc8
20 changed files with 317 additions and 489 deletions

View File

@ -0,0 +1,63 @@
/*
* \brief Array helper class
* \author Stefan Kalkowski
* \date 2016-09-30
*/
/*
* Copyright (C) 2016 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 _ARRAY_H_
#define _ARRAY_H_
#include <base/log.h>
namespace Genode { template <typename, unsigned> class Array; }
template <typename T, unsigned MAX>
class Genode::Array
{
private:
unsigned _count = 0;
T _objs[MAX];
void _init(unsigned i, T obj) { _objs[i] = obj; }
template <typename ... TAIL>
void _init(unsigned i, T obj, TAIL ... tail)
{
_objs[i] = obj;
_init(i+1, tail...);
}
public:
Array() {}
template<typename ... ARGS>
Array(ARGS ... args) : _count(sizeof...(ARGS))
{
static_assert(sizeof...(ARGS) <= MAX, "Array too small!");
_init(0, args...);
}
void add(T const & obj)
{
if (_count == MAX) error("Array too small!");
else _objs[_count++] = obj;
}
template <typename FUNC>
void for_each(FUNC f) const {
for (unsigned i = 0; i < _count; i++) f(_objs[i]); }
unsigned count() const { return _count; }
};
#endif /* _ARRAY_H_ */

View File

@ -0,0 +1,47 @@
/*
* \brief Memory information
* \author Stefan Kalkowski
* \date 2016-09-30
*/
/*
* Copyright (C) 2016 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 _MEMORY_REGION_H_
#define _MEMORY_REGION_H_
#include <base/output.h>
#include <array.h>
#include <util.h>
namespace Genode {
struct Memory_region;
using Memory_region_array = Array<Memory_region, 16>;
}
struct Genode::Memory_region
{
addr_t base = 0;
size_t size = 0;
Memory_region(addr_t base, size_t size)
: base(trunc(base, get_page_size_log2())),
size(round(size, get_page_size_log2())) {}
Memory_region() {}
addr_t end() const { return base + size; }
void print(Output & out) const
{
Genode::print(out, "base=", (void*)base,
" size=", Hex(size, Hex::PREFIX));
}
};
#endif /* _MEMORY_REGION_H_ */

View File

@ -29,15 +29,10 @@
#include <platform_generic.h>
#include <core_region_map.h>
#include <core_mem_alloc.h>
#include <memory_region.h>
namespace Genode {
/**
* Function pointer that provides accessor to a pool of address regions.
*/
typedef Native_region * (*Region_pool)(unsigned const);
/**
* Manages all platform ressources
*/
@ -51,14 +46,6 @@ namespace Genode {
Phys_allocator _irq_alloc; /* IRQ allocator */
Rom_fs _rom_fs; /* ROM file system */
/*
* Virtual-memory range for non-core address spaces.
* The virtual memory layout of core is maintained in
* '_core_mem_alloc.virt_alloc()'.
*/
addr_t _vm_start;
size_t _vm_size;
/**
* Initialize I/O port allocator
*/
@ -81,33 +68,7 @@ namespace Genode {
public:
/**
* Get one of the consecutively numbered available resource regions
*
* \return >0 region pointer if region with index 'i' exists
* 0 if region with index 'i' doesn't exist
*
* These functions should provide all ressources that are available
* on the current platform.
*/
static Native_region * _ram_regions(unsigned i);
/**
* Get one of the consecutively numbered core regions
*
* \return >0 Region pointer if region with index 'i' exists
* 0 If region with index 'i' doesn't exist
*
* Core regions are address regions that must be permitted to
* core only, such as the core image ROM. These regions are
* normally a subset of the ressource regions provided above.
*/
static Native_region * _core_only_ram_regions(unsigned i);
static Native_region * _core_only_mmio_regions(unsigned i);
/**
* Constructor
*/
Platform();
/**
@ -152,30 +113,35 @@ namespace Genode {
Translation_table::CORE_TRANS_TABLE_COUNT>));
}
static Genode::Memory_region_array & ram_regions();
static Memory_region_array & core_ram_regions();
static Genode::Memory_region_array & core_mmio_regions();
/********************************
** Platform_generic interface **
********************************/
inline Range_allocator * core_mem_alloc() {
Range_allocator * core_mem_alloc() {
return &_core_mem_alloc; }
inline Range_allocator * ram_alloc() {
Range_allocator * ram_alloc() {
return _core_mem_alloc.phys_alloc(); }
inline Range_allocator * region_alloc() {
Range_allocator * region_alloc() {
return _core_mem_alloc.virt_alloc(); }
inline Range_allocator * io_mem_alloc() { return &_io_mem_alloc; }
Range_allocator * io_mem_alloc() { return &_io_mem_alloc; }
inline Range_allocator * io_port_alloc() { return &_io_port_alloc; }
Range_allocator * io_port_alloc() { return &_io_port_alloc; }
inline Range_allocator * irq_alloc() { return &_irq_alloc; }
Range_allocator * irq_alloc() { return &_irq_alloc; }
inline addr_t vm_start() const { return _vm_start; }
addr_t vm_start() const { return VIRT_ADDR_SPACE_START; }
inline size_t vm_size() const { return _vm_size; }
size_t vm_size() const { return VIRT_ADDR_SPACE_SIZE; }
inline Rom_fs *rom_fs() { return &_rom_fs; }
Rom_fs *rom_fs() { return &_rom_fs; }
inline void wait_for_exit() {
while (1) { Kernel::stop_thread(); } };

View File

@ -226,10 +226,10 @@ class Genode::Core_platform_pd : public Genode::Platform_pd
* on some ARM SoCs.
*
* \param start physical/virtual start address of area
* \param end physical/virtual end address of area
* \param size size of area
* \param io_mem true if it should be marked as device memory
*/
void _map(addr_t start, addr_t end, bool io_mem);
void _map(addr_t start, size_t size, bool io_mem);
public:

View File

@ -25,12 +25,6 @@
namespace Genode
{
struct Native_region
{
addr_t base;
size_t size;
};
enum {
ACTIVITY_TABLE_ON_FAULTS = 0,
};

View File

@ -17,6 +17,7 @@
/* core includes */
#include <boot_modules.h>
#include <memory_region.h>
#include <core_parent.h>
#include <map_local.h>
#include <platform.h>
@ -29,44 +30,13 @@
#include <trustzone.h>
/* base-internal includes */
#include <base/internal/crt0.h>
#include <base/internal/stack_area.h>
using namespace Genode;
extern int _prog_img_beg;
extern int _prog_img_end;
void __attribute__((weak)) Kernel::init_trustzone(Pic & pic) { }
/**
* Helper to initialise allocators through include/exclude region lists
*/
static void init_alloc(Range_allocator * const alloc,
Region_pool incl_regions, Region_pool excl_regions,
unsigned const granu_log2 = 0)
{
/* make all include regions available */
Native_region * r = incl_regions(0);
for (unsigned i = 0; r; r = incl_regions(++i)) {
if (granu_log2) {
addr_t const b = trunc(r->base, granu_log2);
addr_t const s = round(r->size, granu_log2);
alloc->add_range(b, s);
}
else alloc->add_range(r->base, r->size);
}
/* preserve all exclude regions */
r = excl_regions(0);
for (unsigned i = 0; r; r = excl_regions(++i)) {
if (granu_log2) {
addr_t const b = trunc(r->base, granu_log2);
addr_t const s = round(r->size, granu_log2);
alloc->remove_range(b, s);
}
else alloc->remove_range(r->base, r->size);
}
}
/**************
** Platform **
@ -80,51 +50,47 @@ addr_t Platform::core_translation_tables()
}
Native_region * Platform::_core_only_ram_regions(unsigned const i)
Genode::Memory_region_array & Platform::core_ram_regions()
{
static Native_region _r[] =
{
/* core image */
{ (addr_t)&_prog_img_beg,
(size_t)((addr_t)&_prog_img_end - (addr_t)&_prog_img_beg) },
/* boot modules */
{ (addr_t)&_boot_modules_binaries_begin,
(size_t)((addr_t)&_boot_modules_binaries_end -
(addr_t)&_boot_modules_binaries_begin) },
/* translation table allocator */
{ core_translation_tables(), core_translation_tables_size() }
};
return i < sizeof(_r)/sizeof(_r[0]) ? &_r[i] : 0;
return *unmanaged_singleton<Memory_region_array>(
Memory_region { (addr_t)&_prog_img_beg,
(size_t)((addr_t)&_prog_img_end -
(addr_t)&_prog_img_beg) },
Memory_region { core_translation_tables(),
core_translation_tables_size() });
}
static Native_region * virt_region(unsigned const i) {
static Native_region r = { VIRT_ADDR_SPACE_START, VIRT_ADDR_SPACE_SIZE };
return i ? 0 : &r; }
void Platform::_init_io_mem_alloc()
{
/* add entire adress space minus the RAM memory regions */
_io_mem_alloc.add_range(0, ~0x0UL);
Platform::ram_regions().for_each([this] (Memory_region const &r) {
_io_mem_alloc.remove_range(r.base, r.size); });
/* remove IOMEM of core from its virtual address space allocator */
Platform::core_mmio_regions().for_each([this] (Memory_region const &r) {
_core_mem_alloc.virt_alloc()->remove_range(r.base, r.size);});
};
Platform::Platform()
:
_io_mem_alloc(core_mem_alloc()),
_io_port_alloc(core_mem_alloc()),
_irq_alloc(core_mem_alloc()),
_vm_start(VIRT_ADDR_SPACE_START), _vm_size(VIRT_ADDR_SPACE_SIZE)
_irq_alloc(core_mem_alloc())
{
/*
* Initialise platform resource allocators.
* Core mem alloc must come first because it is
* used by the other allocators.
*/
init_alloc(_core_mem_alloc.phys_alloc(), _ram_regions,
_core_only_ram_regions, get_page_size_log2());
init_alloc(_core_mem_alloc.virt_alloc(), virt_region,
_core_only_ram_regions, get_page_size_log2());
/* preserve stack area in core's virtual address space */
_core_mem_alloc.virt_alloc()->add_range(VIRT_ADDR_SPACE_START,
VIRT_ADDR_SPACE_SIZE);
_core_mem_alloc.virt_alloc()->remove_range(stack_area_virtual_base(),
stack_area_virtual_size());
Platform::ram_regions().for_each([this] (Memory_region const & region) {
_core_mem_alloc.phys_alloc()->add_range(region.base, region.size); });
core_ram_regions().for_each([this] (Memory_region const & region) {
_core_mem_alloc.phys_alloc()->remove_range(region.base, region.size); });
_init_io_port_alloc();
/* make all non-kernel interrupts available to the interrupt allocator */

View File

@ -201,18 +201,13 @@ Translation_table_allocator * const Core_platform_pd::_table_alloc()
}
void Core_platform_pd::_map(addr_t start, addr_t end, bool io_mem)
void Core_platform_pd::_map(addr_t start, size_t size, bool io_mem)
{
const Page_flags flags =
Page_flags::apply_mapping(true, io_mem ? UNCACHED : CACHED, io_mem);
start = trunc_page(start);
if (start < VIRT_ADDR_SPACE_START) error("mapping outside of core's vm");
/* omitt regions before vm_start */
if (start < VIRT_ADDR_SPACE_START)
start = VIRT_ADDR_SPACE_START;
size_t size = round_page(end) - start;
try {
_table()->insert_translation(start, start, size, flags, _table_alloc());
} catch(Allocator::Out_of_memory) {
@ -229,17 +224,11 @@ Core_platform_pd::Core_platform_pd()
/* map exception vector for core */
Kernel::mtc()->map(_table(), _table_alloc());
/* map core's program image */
_map((addr_t)&_prog_img_beg, (addr_t)&_prog_img_end, false);
/* map core's page table allocator */
_map(Platform::core_translation_tables(),
Platform::core_translation_tables() +
Platform::core_translation_tables_size(), false);
/* map core's ram regions */
Platform::core_ram_regions().for_each([this] (Memory_region const &r) {
_map(r.base, r.size, false); });
/* map core's mmio regions */
Native_region * r = Platform::_core_only_mmio_regions(0);
for (unsigned i = 0; r;
r = Platform::_core_only_mmio_regions(++i))
_map(r->base, r->base + r->size, true);
Platform::core_mmio_regions().for_each([this] (Memory_region const &r) {
_map(r.base, r.size, true); });
}

View File

@ -22,21 +22,6 @@ void Platform::_init_additional() { };
void Platform::setup_irq_mode(unsigned, unsigned, unsigned) { }
Native_region * mmio_regions(unsigned);
void Platform::_init_io_mem_alloc()
{
Native_region * r = mmio_regions(0);
for (unsigned i = 0; r; r = mmio_regions(++i))
_io_mem_alloc.add_range(r->base, r->size);
r = mmio_regions(0);
for (unsigned i = 0; r; r = mmio_regions(++i))
_core_mem_alloc.virt_alloc()->remove_range(r->base, r->size);
};
long Platform::irq(long const user_irq) { return user_irq; }

View File

@ -14,40 +14,23 @@
/* core includes */
#include <board.h>
#include <platform.h>
#include <pic.h>
#include <cpu.h>
#include <timer.h>
#include <base/internal/unmanaged_singleton.h>
using namespace Genode;
Native_region * Platform::_ram_regions(unsigned const i)
Memory_region_array & Platform::ram_regions()
{
static Native_region _regions[] =
{
{ Board::RAM_0_BASE, Board::RAM_0_SIZE },
};
return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0;
return *unmanaged_singleton<Memory_region_array>(
Memory_region { Board::RAM_0_BASE, Board::RAM_0_SIZE } );
}
Native_region * mmio_regions(unsigned const i)
Memory_region_array & Platform::core_mmio_regions()
{
static Native_region _regions[] =
{
{ Board::MMIO_0_BASE, Board::MMIO_0_SIZE },
};
return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0;
}
Native_region * Platform::_core_only_mmio_regions(unsigned const i)
{
static Native_region _regions[] =
{
{ Board::IRQ_CONTROLLER_BASE, Board::IRQ_CONTROLLER_SIZE },
{ Board::MCT_MMIO_BASE, Board::MCT_MMIO_SIZE },
{ Board::UART_2_MMIO_BASE, 0x1000 },
};
return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0;
return *unmanaged_singleton<Memory_region_array>(
Memory_region { Board::IRQ_CONTROLLER_BASE, Board::IRQ_CONTROLLER_SIZE },
Memory_region { Board::MCT_MMIO_BASE, Board::MCT_MMIO_SIZE },
Memory_region { Board::UART_2_MMIO_BASE, 0x1000 });
}

View File

@ -14,48 +14,29 @@
/* core includes */
#include <platform.h>
#include <board.h>
#include <pic.h>
#include <cpu.h>
#include <base/internal/unmanaged_singleton.h>
using namespace Genode;
Native_region * Platform::_ram_regions(unsigned const i)
Memory_region_array & Platform::ram_regions()
{
static Native_region _regions[] =
{
{ Board::RAM0_BASE, Board::RAM0_SIZE },
{ Board::RAM1_BASE, Board::RAM1_SIZE }
};
return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0;
return *unmanaged_singleton<Memory_region_array>(
Memory_region { Board::RAM0_BASE, Board::RAM0_SIZE },
Memory_region { Board::RAM1_BASE, Board::RAM1_SIZE });
}
Native_region * mmio_regions(unsigned const i)
Memory_region_array & Platform::core_mmio_regions()
{
static Native_region _regions[] =
{
{ 0x07000000, 0x1000000 }, /* security controller */
{ 0x10000000, 0x30000000 }, /* SATA, IPU, GPU */
{ 0x50000000, 0x20000000 }, /* Misc. */
};
return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0;
}
Native_region * Platform::_core_only_mmio_regions(unsigned const i)
{
static Native_region _regions[] =
{
/* core UART */
{ Board::UART_1_MMIO_BASE, Board::UART_1_MMIO_SIZE },
/* core timer */
{ Board::EPIT_1_MMIO_BASE, Board::EPIT_1_MMIO_SIZE },
/* interrupt controller */
{ Board::IRQ_CONTROLLER_BASE, Board::IRQ_CONTROLLER_SIZE },
};
return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0;
return *unmanaged_singleton<Memory_region_array>(
Memory_region { Board::UART_1_MMIO_BASE, /* UART */
Board::UART_1_MMIO_SIZE },
Memory_region { Board::EPIT_1_MMIO_BASE, /* timer */
Board::EPIT_1_MMIO_SIZE },
Memory_region { Board::IRQ_CONTROLLER_BASE, /* irq controller */
Board::IRQ_CONTROLLER_SIZE });
}

View File

@ -21,6 +21,8 @@
#include <trustzone.h>
#include <csu.h>
#include <base/internal/unmanaged_singleton.h>
using namespace Genode;
/* monitor exception vector address */
@ -62,46 +64,25 @@ void Kernel::init_trustzone(Pic & pic)
}
Native_region * Platform::_ram_regions(unsigned const i)
Memory_region_array & Platform::ram_regions()
{
static Native_region _regions[] =
{
{ Trustzone::SECURE_RAM_BASE, Trustzone::SECURE_RAM_SIZE },
};
return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0;
return *unmanaged_singleton<Memory_region_array>(
Memory_region { Trustzone::SECURE_RAM_BASE,
Trustzone::SECURE_RAM_SIZE });
}
Native_region * mmio_regions(unsigned const i)
Memory_region_array & Platform::core_mmio_regions()
{
static Native_region _regions[] =
{
{ 0x07000000, 0x1000000 }, /* security controller */
{ 0x10000000, 0x30000000 }, /* SATA, IPU, GPU */
{ 0x50000000, 0x20000000 }, /* Misc. */
{ Trustzone::NONSECURE_RAM_BASE, Trustzone::NONSECURE_RAM_SIZE },
};
return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0;
}
Native_region * Platform::_core_only_mmio_regions(unsigned const i)
{
static Native_region _regions[] =
{
/* core UART */
{ Board::UART_1_MMIO_BASE, Board::UART_1_MMIO_SIZE },
/* core timer */
{ Board::EPIT_1_MMIO_BASE, Board::EPIT_1_MMIO_SIZE },
/* interrupt controller */
{ Board::IRQ_CONTROLLER_BASE, Board::IRQ_CONTROLLER_SIZE },
/* central security unit */
{ Board::CSU_BASE, Board::CSU_SIZE },
};
return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0;
return *unmanaged_singleton<Memory_region_array>(
Memory_region { Board::UART_1_MMIO_BASE, /* UART */
Board::UART_1_MMIO_SIZE },
Memory_region { Board::EPIT_1_MMIO_BASE, /* timer */
Board::EPIT_1_MMIO_SIZE },
Memory_region { Board::IRQ_CONTROLLER_BASE, /* irq controller */
Board::IRQ_CONTROLLER_SIZE },
Memory_region { Board::CSU_BASE, /* central security unit */
Board::CSU_SIZE });
}

View File

@ -17,42 +17,26 @@
#include <platform.h>
#include <cpu.h>
#include <base/internal/unmanaged_singleton.h>
using namespace Genode;
Native_region * Platform::_ram_regions(unsigned const i)
Memory_region_array & Platform::ram_regions()
{
static Native_region _regions[] =
{
{ Board::RAM0_BASE, Board::RAM0_SIZE }
};
return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0;
return *unmanaged_singleton<Memory_region_array>(
Memory_region { Board::RAM0_BASE, Board::RAM0_SIZE });
}
Native_region * mmio_regions(unsigned const i)
Memory_region_array & Platform::core_mmio_regions()
{
static Native_region _regions[] =
{
{ Board::MMIO_BASE, Board::MMIO_SIZE }
};
return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0;
}
Native_region * Platform::_core_only_mmio_regions(unsigned const i)
{
static Native_region _regions[] =
{
/* core UART */
{ Board::UART_1_MMIO_BASE, Board::UART_1_MMIO_SIZE },
/* CPU-local core MMIO like interrupt controller and timer */
{ Board::CORTEX_A9_PRIVATE_MEM_BASE, Board::CORTEX_A9_PRIVATE_MEM_SIZE },
/* l2 cache controller */
{ Board::PL310_MMIO_BASE, Board::PL310_MMIO_SIZE }
};
return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0;
return *unmanaged_singleton<Memory_region_array>(
Memory_region { Board::UART_1_MMIO_BASE, /* UART */
Board::UART_1_MMIO_SIZE },
Memory_region { Board::CORTEX_A9_PRIVATE_MEM_BASE, /* irq controller */
Board::CORTEX_A9_PRIVATE_MEM_SIZE }, /* and timer */
Memory_region { Board::PL310_MMIO_BASE, /* l2 cache controller */
Board::PL310_MMIO_SIZE });
}

View File

@ -23,45 +23,22 @@
using namespace Genode;
Native_region * Platform::_ram_regions(unsigned const i)
Memory_region_array & Platform::ram_regions()
{
static Native_region _regions[] =
{
{ Board::RAM_0_BASE, Board::RAM_0_SIZE }
};
return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0;
return *unmanaged_singleton<Memory_region_array>(
Memory_region { Board::RAM_0_BASE, Board::RAM_0_SIZE });
}
Native_region * mmio_regions(unsigned const i)
Memory_region_array & Platform::core_mmio_regions()
{
static Native_region _regions[] =
{
{ Board::MMIO_0_BASE, Board::MMIO_0_SIZE },
{ Board::MMIO_1_BASE, Board::MMIO_1_SIZE },
{ Board::DSS_MMIO_BASE, Board::DSS_MMIO_SIZE },
{ Board::DISPC_MMIO_BASE, Board::DISPC_MMIO_SIZE },
{ Board::HDMI_MMIO_BASE, Board::HDMI_MMIO_SIZE }
};
return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0;
}
Native_region * Platform::_core_only_mmio_regions(unsigned const i)
{
static Native_region _regions[] =
{
/* core timer and PIC */
{ Board::CORTEX_A9_PRIVATE_MEM_BASE,
Board::CORTEX_A9_PRIVATE_MEM_SIZE },
/* core UART */
{ Board::TL16C750_3_MMIO_BASE, Board::TL16C750_MMIO_SIZE },
/* l2 cache controller */
{ Board::PL310_MMIO_BASE, Board::PL310_MMIO_SIZE }
};
return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0;
return *unmanaged_singleton<Memory_region_array>(
Memory_region { Board::CORTEX_A9_PRIVATE_MEM_BASE, /* timer and PIC */
Board::CORTEX_A9_PRIVATE_MEM_SIZE },
Memory_region { Board::TL16C750_3_MMIO_BASE, /* UART */
Board::TL16C750_MMIO_SIZE },
Memory_region { Board::PL310_MMIO_BASE, /* l2 cache controller */
Board::PL310_MMIO_SIZE });
}

View File

@ -17,45 +17,33 @@
#include <cpu.h>
#include <pic.h>
/* base-internal includes */
#include <base/internal/unmanaged_singleton.h>
using namespace Genode;
Native_region * Platform::_ram_regions(unsigned const i)
Memory_region_array & Platform::ram_regions()
{
static Native_region _regions[] =
{
{ Board::RAM_0_BASE, Board::RAM_0_SIZE },
{ Board::RAM_1_BASE, Board::RAM_1_SIZE }
};
return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0;
return *unmanaged_singleton<Memory_region_array>(
Memory_region { Board::RAM_0_BASE, Board::RAM_0_SIZE },
Memory_region { Board::RAM_1_BASE, Board::RAM_1_SIZE });
}
Native_region * mmio_regions(unsigned const i)
Memory_region_array & Platform::core_mmio_regions()
{
static Native_region _regions[] =
{
{ Board::MMIO_0_BASE, Board::MMIO_0_SIZE },
{ Board::MMIO_1_BASE, Board::MMIO_1_SIZE }
};
return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0;
}
Native_region * Platform::_core_only_mmio_regions(unsigned const i)
{
static Native_region _regions[] =
{
return *unmanaged_singleton<Memory_region_array>(
/* core timer and PIC */
{ Board::CORTEX_A9_PRIVATE_MEM_BASE, Board::CORTEX_A9_PRIVATE_MEM_SIZE },
Memory_region { Board::CORTEX_A9_PRIVATE_MEM_BASE,
Board::CORTEX_A9_PRIVATE_MEM_SIZE },
/* core UART */
{ Board::PL011_0_MMIO_BASE, Board::PL011_0_MMIO_SIZE },
Memory_region { Board::PL011_0_MMIO_BASE, Board::PL011_0_MMIO_SIZE },
/* L2 Cache Controller */
{ Board::PL310_MMIO_BASE, Board::PL310_MMIO_SIZE }
};
return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0;
Memory_region { Board::PL310_MMIO_BASE, Board::PL310_MMIO_SIZE }
);
}

View File

@ -16,19 +16,22 @@
#include <board.h>
#include <cpu.h>
#include <base/internal/unmanaged_singleton.h>
using namespace Genode;
Native_region * Platform::_ram_regions(unsigned const i)
Memory_region_array & Platform::ram_regions()
{
static Native_region _regions[] = { { 0, 128 * 1024 * 1024 } };
return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0;
return *unmanaged_singleton<Memory_region_array>(
Memory_region { 0, 128 * 1024 * 1024 } );
}
Cpu::User_context::User_context() { }
Native_region * Platform::_core_only_mmio_regions(unsigned) { return 0; }
Memory_region_array & Platform::core_mmio_regions() {
return *unmanaged_singleton<Memory_region_array>(); }
void Platform::_init_io_port_alloc() { }

View File

@ -16,46 +16,29 @@
#include <board.h>
#include <cpu.h>
#include <base/internal/unmanaged_singleton.h>
using namespace Genode;
Native_region * Platform::_ram_regions(unsigned const i)
Memory_region_array & Platform::ram_regions()
{
static Native_region _regions[] =
{
{ Board::RAM_0_BASE, Board::RAM_0_SIZE }
};
return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0;
return *unmanaged_singleton<Memory_region_array>(
Memory_region { Board::RAM_0_BASE, Board::RAM_0_SIZE });
}
Native_region * mmio_regions(unsigned const i)
Memory_region_array & Platform::core_mmio_regions()
{
static Native_region _regions[] =
{
{ 0x20000000, 0x22000000 },
{ 0x50000000, 0x10000000 },
};
return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0;
}
Native_region * Platform::_core_only_mmio_regions(unsigned const i)
{
static Native_region _regions[] =
{
/* UART */
{ Board::PL011_0_MMIO_BASE, Board::PL011_0_MMIO_SIZE },
/* system timer */
{ Board::SYSTEM_TIMER_MMIO_BASE, Board::SYSTEM_TIMER_MMIO_SIZE },
/* IRQ controller */
{ Board::IRQ_CONTROLLER_BASE, Board::IRQ_CONTROLLER_SIZE },
/* DWC OTG USB controller (used for in-kernel SOF IRQ handling) */
{ Board::USB_DWC_OTG_BASE, Board::USB_DWC_OTG_SIZE },
};
return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0;
return *unmanaged_singleton<Memory_region_array>(
Memory_region { Board::PL011_0_MMIO_BASE, /* UART */
Board::PL011_0_MMIO_SIZE },
Memory_region { Board::SYSTEM_TIMER_MMIO_BASE, /* system timer */
Board::SYSTEM_TIMER_MMIO_SIZE },
Memory_region { Board::IRQ_CONTROLLER_BASE, /* IRQ controller */
Board::IRQ_CONTROLLER_SIZE },
Memory_region { Board::USB_DWC_OTG_BASE, /* DWC OTG USB */
Board::USB_DWC_OTG_SIZE } /* controller */
);
}

View File

@ -20,6 +20,8 @@
#include <platform.h>
#include <sinfo_instance.h>
#include <base/internal/unmanaged_singleton.h>
using namespace Genode;
struct Mmconf_address : Register<64>
@ -57,18 +59,15 @@ struct Msi_address : Register<32>
};
Native_region * Platform::_core_only_mmio_regions(unsigned const i)
Memory_region_array & Platform::core_mmio_regions()
{
static Native_region _regions[] =
{
/* Sinfo pages */
{ Sinfo::PHYSICAL_BASE_ADDR, Sinfo::SIZE },
/* Timer page */
{ Board::TIMER_BASE_ADDR, Board::TIMER_SIZE },
/* Optional guest timed event page for preemption */
{ Board::TIMER_PREEMPT_BASE_ADDR, Board::TIMER_PREEMPT_SIZE },
};
return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0;
return *unmanaged_singleton<Memory_region_array>(
Memory_region { Sinfo::PHYSICAL_BASE_ADDR, /* Sinfo pages */
Sinfo::SIZE },
Memory_region { Board::TIMER_BASE_ADDR, /* Timer page */
Board::TIMER_SIZE },
Memory_region { Board::TIMER_PREEMPT_BASE_ADDR, /* Timed event page */
Board::TIMER_PREEMPT_SIZE }); /* for preemption */
}
@ -100,23 +99,18 @@ bool Platform::get_msi_params(const addr_t mmconf, addr_t &address,
}
Native_region * Platform::_ram_regions(unsigned const i)
Memory_region_array & Platform::ram_regions()
{
if (i)
return 0;
static Memory_region_array ram;
static Native_region result = { .base = 0, .size = 0 };
if (!result.size) {
if (ram.count() == 0) {
struct Sinfo::Memregion_info region;
if (!sinfo()->get_memregion_info("ram", &region)) {
if (!sinfo()->get_memregion_info("ram", &region))
error("Unable to retrieve base-hw ram region");
return 0;
}
result = { .base = region.address, .size = region.size };
else
ram.add(Memory_region { region.address, region.size });
}
return &result;
return ram;
}

View File

@ -18,6 +18,8 @@
#include <kernel/kernel.h>
#include <multiboot.h>
#include <base/internal/unmanaged_singleton.h>
using namespace Genode;
/* contains physical pointer to multiboot */
@ -25,21 +27,12 @@ extern "C" Genode::addr_t __initial_bx;
void Platform::_init_additional() { };
Native_region * Platform::_core_only_mmio_regions(unsigned const i)
Memory_region_array & Platform::core_mmio_regions()
{
static Native_region _regions[] =
{
{ Board::MMIO_LAPIC_BASE, Board::MMIO_LAPIC_SIZE },
{ Board::MMIO_IOAPIC_BASE, Board::MMIO_IOAPIC_SIZE },
{ 0, 0}
};
unsigned const max = sizeof(_regions) / sizeof(_regions[0]);
if (!_regions[max - 1].size)
_regions[max - 1] = { __initial_bx & ~0xFFFUL, get_page_size() };
return i < max ? &_regions[i] : nullptr;
return *unmanaged_singleton<Memory_region_array>(
Memory_region { Board::MMIO_LAPIC_BASE, Board::MMIO_LAPIC_SIZE },
Memory_region { Board::MMIO_IOAPIC_BASE, Board::MMIO_IOAPIC_SIZE },
Memory_region { __initial_bx & ~0xFFFUL, get_page_size() });
}
@ -57,32 +50,32 @@ bool Platform::get_msi_params(const addr_t mmconf, addr_t &address,
}
Native_region * Platform::_ram_regions(unsigned const i)
Memory_region_array & Platform::ram_regions()
{
static Native_region _regions[16];
static Memory_region_array ram;
Multiboot_info::Mmap v = Genode::Multiboot_info(__initial_bx).phys_ram(i);
if (!v.base)
return nullptr;
/* initialize memory pool */
if (ram.count() == 0) {
using Mmap = Multiboot_info::Mmap;
Multiboot_info::Mmap::Addr::access_t base = v.read<Multiboot_info::Mmap::Addr>();
Multiboot_info::Mmap::Length::access_t size = v.read<Multiboot_info::Mmap::Length>();
for (unsigned i = 0; true; i++) {
Mmap v = Multiboot_info(__initial_bx).phys_ram(i);
if (!v.base) break;
unsigned const max = sizeof(_regions) / sizeof(_regions[0]);
Mmap::Addr::access_t base = v.read<Mmap::Addr>();
Mmap::Length::access_t size = v.read<Mmap::Length>();
if (i < max && _regions[i].size == 0) {
if (base == 0 && size >= get_page_size()) {
/*
* Exclude first physical page, so that it will become part of the
* MMIO allocator. The framebuffer requests this page as MMIO.
*/
base = get_page_size();
size -= get_page_size();
if (base == 0 && size >= get_page_size()) {
base = get_page_size();
size -= get_page_size();
}
ram.add(Memory_region { base, size });
}
_regions[i] = { base, size };
} else if (i >= max)
warning("physical ram region ", (void*)base, "+", (size_t)size,
" will be not used");
}
return i < max ? &_regions[i] : nullptr;
return ram;
}

View File

@ -25,31 +25,6 @@ void Platform::_init_io_port_alloc()
}
/**
* Remove given exclude memory regions from specified allocator.
*/
static void alloc_exclude_regions(Range_allocator * const alloc,
Region_pool excl_regions)
{
Native_region * r = excl_regions(0);
for (unsigned i = 0; r; r = excl_regions(++i))
alloc->remove_range(r->base, r->size);
}
void Platform::_init_io_mem_alloc()
{
/* add entire adress space minus the RAM memory regions */
_io_mem_alloc.add_range(0, ~0x0UL);
alloc_exclude_regions(&_io_mem_alloc, _ram_regions);
alloc_exclude_regions(&_io_mem_alloc, _core_only_ram_regions);
alloc_exclude_regions(&_io_mem_alloc, _core_only_mmio_regions);
/* exclude all mmio regions from virt allocator of core */
alloc_exclude_regions(_core_mem_alloc.virt_alloc(), _core_only_mmio_regions);
}
long Platform::irq(long const user_irq)
{
/* remap IRQ requests to fit I/O APIC configuration */

View File

@ -23,46 +23,22 @@
using namespace Genode;
Native_region * Platform::_ram_regions(unsigned const i)
Memory_region_array & Platform::ram_regions()
{
static Native_region _regions[] =
{
{ Board::RAM_0_BASE, Board::RAM_0_SIZE }
};
return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0;
return *unmanaged_singleton<Memory_region_array>(
Memory_region { Board::RAM_0_BASE, Board::RAM_0_SIZE });
}
Native_region * mmio_regions(unsigned const i)
Memory_region_array & Platform::core_mmio_regions()
{
static Native_region _regions[] =
{
{ Board::MMIO_0_BASE, Board::MMIO_0_SIZE },
{ Board::MMIO_1_BASE, Board::MMIO_1_SIZE },
{ Board::QSPI_MMIO_BASE, Board::QSPI_MMIO_SIZE },
{ Board::OCM_MMIO_BASE, Board::OCM_MMIO_SIZE },
{ Board::AXI_0_MMIO_BASE, Board::AXI_0_MMIO_SIZE },
{ Board::AXI_1_MMIO_BASE, Board::AXI_1_MMIO_SIZE }
};
return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0;
}
Native_region * Platform::_core_only_mmio_regions(unsigned const i)
{
static Native_region _regions[] =
{
/* core timer and PIC */
{ Board::CORTEX_A9_PRIVATE_MEM_BASE,
Board::CORTEX_A9_PRIVATE_MEM_SIZE },
/* core UART */
{ Board::KERNEL_UART_BASE, Board::KERNEL_UART_SIZE },
/* L2 cache controller */
{ Board::PL310_MMIO_BASE, Board::PL310_MMIO_SIZE }
};
return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0;
return *unmanaged_singleton<Memory_region_array>(
Memory_region { Board::CORTEX_A9_PRIVATE_MEM_BASE, /* timer and PIC */
Board::CORTEX_A9_PRIVATE_MEM_SIZE },
Memory_region { Board::KERNEL_UART_BASE, /* UART */
Board::KERNEL_UART_SIZE },
Memory_region { Board::PL310_MMIO_BASE, /* L2 cache controller */
Board::PL310_MMIO_SIZE });
}