From d549921bc896910395aa47262c4805dbb0bb7122 Mon Sep 17 00:00:00 2001 From: Stefan Kalkowski Date: Thu, 6 Oct 2016 20:07:16 +0200 Subject: [PATCH] hw: introduce memory regions and array * replace Native_regions and inline code for iteration Ref #2092 --- repos/base-hw/src/core/include/array.h | 63 +++++++++++++ .../base-hw/src/core/include/memory_region.h | 47 ++++++++++ repos/base-hw/src/core/include/platform.h | 64 +++---------- repos/base-hw/src/core/include/platform_pd.h | 4 +- repos/base-hw/src/core/include/util.h | 6 -- repos/base-hw/src/core/platform.cc | 94 ++++++------------- repos/base-hw/src/core/platform_pd.cc | 25 ++--- .../src/core/spec/arm/platform_support.cc | 15 --- .../src/core/spec/exynos5/platform_support.cc | 37 ++------ .../src/core/spec/imx53/platform_support.cc | 47 +++------- .../spec/imx53/trustzone/platform_support.cc | 51 ++++------ .../src/core/spec/imx6/platform_support.cc | 42 +++------ .../src/core/spec/panda/platform_support.cc | 45 +++------ .../src/core/spec/pbxa9/platform_support.cc | 40 +++----- .../src/core/spec/riscv/platform_support.cc | 11 ++- .../src/core/spec/rpi/platform_support.cc | 49 ++++------ .../core/spec/x86_64/muen/platform_support.cc | 40 ++++---- .../src/core/spec/x86_64/platform_support.cc | 55 +++++------ .../spec/x86_64/platform_support_common.cc | 25 ----- .../src/core/spec/zynq/platform_support.cc | 46 +++------ 20 files changed, 317 insertions(+), 489 deletions(-) create mode 100644 repos/base-hw/src/core/include/array.h create mode 100644 repos/base-hw/src/core/include/memory_region.h diff --git a/repos/base-hw/src/core/include/array.h b/repos/base-hw/src/core/include/array.h new file mode 100644 index 000000000..82ab0d884 --- /dev/null +++ b/repos/base-hw/src/core/include/array.h @@ -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 + +namespace Genode { template class Array; } + + +template +class Genode::Array +{ + private: + + unsigned _count = 0; + T _objs[MAX]; + + void _init(unsigned i, T obj) { _objs[i] = obj; } + + template + void _init(unsigned i, T obj, TAIL ... tail) + { + _objs[i] = obj; + _init(i+1, tail...); + } + + public: + + Array() {} + + template + 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 + void for_each(FUNC f) const { + for (unsigned i = 0; i < _count; i++) f(_objs[i]); } + + unsigned count() const { return _count; } +}; + +#endif /* _ARRAY_H_ */ diff --git a/repos/base-hw/src/core/include/memory_region.h b/repos/base-hw/src/core/include/memory_region.h new file mode 100644 index 000000000..6accf1fd2 --- /dev/null +++ b/repos/base-hw/src/core/include/memory_region.h @@ -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 +#include +#include + +namespace Genode { + struct Memory_region; + + using Memory_region_array = Array; +} + +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_ */ diff --git a/repos/base-hw/src/core/include/platform.h b/repos/base-hw/src/core/include/platform.h index 615bcde6e..907242358 100644 --- a/repos/base-hw/src/core/include/platform.h +++ b/repos/base-hw/src/core/include/platform.h @@ -29,15 +29,10 @@ #include #include #include +#include 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(); } }; diff --git a/repos/base-hw/src/core/include/platform_pd.h b/repos/base-hw/src/core/include/platform_pd.h index 3b5695f38..9ad85500d 100644 --- a/repos/base-hw/src/core/include/platform_pd.h +++ b/repos/base-hw/src/core/include/platform_pd.h @@ -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: diff --git a/repos/base-hw/src/core/include/util.h b/repos/base-hw/src/core/include/util.h index 0d66bd683..0caf6d607 100644 --- a/repos/base-hw/src/core/include/util.h +++ b/repos/base-hw/src/core/include/util.h @@ -25,12 +25,6 @@ namespace Genode { - struct Native_region - { - addr_t base; - size_t size; - }; - enum { ACTIVITY_TABLE_ON_FAULTS = 0, }; diff --git a/repos/base-hw/src/core/platform.cc b/repos/base-hw/src/core/platform.cc index 02ccb354c..c53791b6c 100644 --- a/repos/base-hw/src/core/platform.cc +++ b/repos/base-hw/src/core/platform.cc @@ -17,6 +17,7 @@ /* core includes */ #include +#include #include #include #include @@ -29,44 +30,13 @@ #include /* base-internal includes */ +#include #include 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 { (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 */ diff --git a/repos/base-hw/src/core/platform_pd.cc b/repos/base-hw/src/core/platform_pd.cc index 90755d94e..9b0258604 100644 --- a/repos/base-hw/src/core/platform_pd.cc +++ b/repos/base-hw/src/core/platform_pd.cc @@ -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); }); } diff --git a/repos/base-hw/src/core/spec/arm/platform_support.cc b/repos/base-hw/src/core/spec/arm/platform_support.cc index a47924152..a33dd7eba 100644 --- a/repos/base-hw/src/core/spec/arm/platform_support.cc +++ b/repos/base-hw/src/core/spec/arm/platform_support.cc @@ -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; } diff --git a/repos/base-hw/src/core/spec/exynos5/platform_support.cc b/repos/base-hw/src/core/spec/exynos5/platform_support.cc index f910494be..a93395efd 100644 --- a/repos/base-hw/src/core/spec/exynos5/platform_support.cc +++ b/repos/base-hw/src/core/spec/exynos5/platform_support.cc @@ -14,40 +14,23 @@ /* core includes */ #include #include -#include -#include -#include + +#include 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 { 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 { 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 }); } diff --git a/repos/base-hw/src/core/spec/imx53/platform_support.cc b/repos/base-hw/src/core/spec/imx53/platform_support.cc index fff8738a3..1ae18f138 100644 --- a/repos/base-hw/src/core/spec/imx53/platform_support.cc +++ b/repos/base-hw/src/core/spec/imx53/platform_support.cc @@ -14,48 +14,29 @@ /* core includes */ #include #include -#include #include +#include + 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 { 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 { 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 }); } diff --git a/repos/base-hw/src/core/spec/imx53/trustzone/platform_support.cc b/repos/base-hw/src/core/spec/imx53/trustzone/platform_support.cc index b77b58fc2..edfda3e0c 100644 --- a/repos/base-hw/src/core/spec/imx53/trustzone/platform_support.cc +++ b/repos/base-hw/src/core/spec/imx53/trustzone/platform_support.cc @@ -21,6 +21,8 @@ #include #include +#include + 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 { 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 { 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 }); } diff --git a/repos/base-hw/src/core/spec/imx6/platform_support.cc b/repos/base-hw/src/core/spec/imx6/platform_support.cc index 5ce1f46fb..93e01cdda 100644 --- a/repos/base-hw/src/core/spec/imx6/platform_support.cc +++ b/repos/base-hw/src/core/spec/imx6/platform_support.cc @@ -17,42 +17,26 @@ #include #include +#include + 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 { 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 { 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 }); } diff --git a/repos/base-hw/src/core/spec/panda/platform_support.cc b/repos/base-hw/src/core/spec/panda/platform_support.cc index 82aa51d2d..2affe4ba7 100644 --- a/repos/base-hw/src/core/spec/panda/platform_support.cc +++ b/repos/base-hw/src/core/spec/panda/platform_support.cc @@ -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 { 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 { 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 }); } diff --git a/repos/base-hw/src/core/spec/pbxa9/platform_support.cc b/repos/base-hw/src/core/spec/pbxa9/platform_support.cc index 982062197..eef62913d 100644 --- a/repos/base-hw/src/core/spec/pbxa9/platform_support.cc +++ b/repos/base-hw/src/core/spec/pbxa9/platform_support.cc @@ -17,45 +17,33 @@ #include #include +/* base-internal includes */ +#include + 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 { 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( /* 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 } + ); } diff --git a/repos/base-hw/src/core/spec/riscv/platform_support.cc b/repos/base-hw/src/core/spec/riscv/platform_support.cc index dde45000e..9006e4093 100644 --- a/repos/base-hw/src/core/spec/riscv/platform_support.cc +++ b/repos/base-hw/src/core/spec/riscv/platform_support.cc @@ -16,19 +16,22 @@ #include #include +#include + 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 { 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(); } void Platform::_init_io_port_alloc() { } diff --git a/repos/base-hw/src/core/spec/rpi/platform_support.cc b/repos/base-hw/src/core/spec/rpi/platform_support.cc index cc8947b3c..50d56a3bc 100644 --- a/repos/base-hw/src/core/spec/rpi/platform_support.cc +++ b/repos/base-hw/src/core/spec/rpi/platform_support.cc @@ -16,46 +16,29 @@ #include #include +#include + 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 { 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 { 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 */ + ); } diff --git a/repos/base-hw/src/core/spec/x86_64/muen/platform_support.cc b/repos/base-hw/src/core/spec/x86_64/muen/platform_support.cc index 22796bdde..0a9f9ee2b 100644 --- a/repos/base-hw/src/core/spec/x86_64/muen/platform_support.cc +++ b/repos/base-hw/src/core/spec/x86_64/muen/platform_support.cc @@ -20,6 +20,8 @@ #include #include +#include + 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 { 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", ®ion)) { + if (!sinfo()->get_memregion_info("ram", ®ion)) 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; } diff --git a/repos/base-hw/src/core/spec/x86_64/platform_support.cc b/repos/base-hw/src/core/spec/x86_64/platform_support.cc index 1815ccce0..87def75b6 100644 --- a/repos/base-hw/src/core/spec/x86_64/platform_support.cc +++ b/repos/base-hw/src/core/spec/x86_64/platform_support.cc @@ -18,6 +18,8 @@ #include #include +#include + 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 { 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::Length::access_t size = v.read(); + 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::Length::access_t size = v.read(); - 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; } diff --git a/repos/base-hw/src/core/spec/x86_64/platform_support_common.cc b/repos/base-hw/src/core/spec/x86_64/platform_support_common.cc index 973d04d3a..117220d26 100644 --- a/repos/base-hw/src/core/spec/x86_64/platform_support_common.cc +++ b/repos/base-hw/src/core/spec/x86_64/platform_support_common.cc @@ -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 */ diff --git a/repos/base-hw/src/core/spec/zynq/platform_support.cc b/repos/base-hw/src/core/spec/zynq/platform_support.cc index a8016478e..2134b8657 100644 --- a/repos/base-hw/src/core/spec/zynq/platform_support.cc +++ b/repos/base-hw/src/core/spec/zynq/platform_support.cc @@ -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 { 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 { 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 }); }