From c1bb82fb6b6f4d7f4aad91c31a5fe9e94caba8b8 Mon Sep 17 00:00:00 2001 From: Adrian-Ken Rueegsegger Date: Thu, 2 Jul 2015 16:25:51 +0200 Subject: [PATCH] base-hw: make Muen sinfo API publicly available The sinfo function declared in sinfo_instance.h creates a static sinfo object instance and returns a pointer to the caller. - kernel timer and platform support to use sinfo() function to instantiate sinfo object - address and size of the base-hw RAM region via the sinfo API - log_status() function in sinfo API --- .../include/spec/x86_64/muen/sinfo.h | 56 +++++-- repos/base-hw/lib/mk/spec/muen/base-common.mk | 5 + .../lib/mk/spec/x86_64/core-muen_on.mk | 1 - .../{core/spec/x86_64 => base}/muen/musinfo.h | 10 +- .../{core/spec/x86_64 => base}/muen/sinfo.cc | 145 +++++++++--------- repos/base-hw/src/core/include/platform.h | 5 + .../base-hw/src/core/include/spec/x86/board.h | 2 +- .../src/core/include/spec/x86_64/muen/board.h | 34 ++++ .../include/spec/x86_64/muen/sinfo_instance.h | 35 +++++ .../src/core/include/spec/x86_64/muen/timer.h | 13 +- repos/base-hw/src/core/platform.cc | 2 + .../src/core/spec/arm/platform_support.cc | 2 + .../src/core/spec/riscv/platform_support.cc | 2 + .../core/spec/x86_64/muen/platform_support.cc | 39 +++-- .../src/core/spec/x86_64/platform_support.cc | 1 + 15 files changed, 247 insertions(+), 105 deletions(-) rename repos/base-hw/{src/core => }/include/spec/x86_64/muen/sinfo.h (72%) create mode 100644 repos/base-hw/lib/mk/spec/muen/base-common.mk rename repos/base-hw/src/{core/spec/x86_64 => base}/muen/musinfo.h (90%) rename repos/base-hw/src/{core/spec/x86_64 => base}/muen/sinfo.cc (89%) create mode 100644 repos/base-hw/src/core/include/spec/x86_64/muen/board.h create mode 100644 repos/base-hw/src/core/include/spec/x86_64/muen/sinfo_instance.h diff --git a/repos/base-hw/src/core/include/spec/x86_64/muen/sinfo.h b/repos/base-hw/include/spec/x86_64/muen/sinfo.h similarity index 72% rename from repos/base-hw/src/core/include/spec/x86_64/muen/sinfo.h rename to repos/base-hw/include/spec/x86_64/muen/sinfo.h index b922f50fb..a3572a1be 100644 --- a/repos/base-hw/src/core/include/spec/x86_64/muen/sinfo.h +++ b/repos/base-hw/include/spec/x86_64/muen/sinfo.h @@ -14,11 +14,13 @@ * under the terms of the GNU General Public License version 2. */ -#ifndef _CORE__INCLUDE__SPEC__X86_64__MUEN__SINFO_H_ -#define _CORE__INCLUDE__SPEC__X86_64__MUEN__SINFO_H_ +#ifndef _INCLUDE__SPEC__X86_64__MUEN__SINFO_H_ +#define _INCLUDE__SPEC__X86_64__MUEN__SINFO_H_ #include +struct subject_info_type; + namespace Genode { /** @@ -32,10 +34,12 @@ class Genode::Sinfo public: enum Config { - MAX_NAME_LENGTH = 63, + PHYSICAL_BASE_ADDR = 0xe00000000, + SIZE = 0x7000, + MAX_NAME_LENGTH = 63, }; - Sinfo(); + Sinfo(const addr_t base_addr); /* Structure holding information about a memory region */ struct Memregion_info { @@ -70,7 +74,7 @@ class Genode::Sinfo /* * Check Muen sinfo Magic. */ - static bool check_magic(void); + bool check_magic(void); /* * Return information for a channel given by name. @@ -79,7 +83,7 @@ class Genode::Sinfo * event_number and vector parameters are only valid if indicated by * the has_[event|vector] struct members. */ - static bool get_channel_info(const char * const name, + bool get_channel_info(const char * const name, struct Channel_info *channel); /* @@ -87,7 +91,7 @@ class Genode::Sinfo * * If no memory region with given name exists, False is returned. */ - static bool get_memregion_info(const char * const name, + bool get_memregion_info(const char * const name, struct Memregion_info *memregion); /* @@ -96,7 +100,7 @@ class Genode::Sinfo * The function returns false if no device information for the * specified device exists. */ - static bool get_dev_info(const uint16_t sid, struct Dev_info *dev); + bool get_dev_info(const uint16_t sid, struct Dev_info *dev); /* * Channel callback. @@ -114,7 +118,7 @@ class Genode::Sinfo * invocation of the callback. If a callback invocation returns false, * processing is aborted and false is returned to the caller. */ - static bool for_each_channel(Channel_cb func, void *data); + bool for_each_channel(Channel_cb func, void *data); /* * Memory region callback. @@ -132,24 +136,48 @@ class Genode::Sinfo * invocation of the callback. If a callback invocation returns false, * processing is aborted and false is returned to the caller. */ - static bool for_each_memregion(Memregion_cb func, void *data); + bool for_each_memregion(Memregion_cb func, void *data); /* * Return TSC tick rate in kHz. * * The function returns 0 if the TSC tick rate cannot be retrieved. */ - static uint64_t get_tsc_khz(void); + uint64_t get_tsc_khz(void); /* * Return start time of current minor frame in TSC ticks. */ - static uint64_t get_sched_start(void); + uint64_t get_sched_start(void); /* * Return end time of current minor frame in TSC ticks. */ - static uint64_t get_sched_end(void); + uint64_t get_sched_end(void); + + /* + * Log sinfo status. + */ + void log_status(); + + private: + + subject_info_type * sinfo; + + /* + * Fill memregion struct with memory region info from resource given by + * index. + */ + void fill_memregion_data(uint8_t idx, struct Memregion_info *region); + + /* + * Fill channel struct with channel information from resource given by + * index. + */ + void fill_channel_data(uint8_t idx, struct Channel_info *channel); + + /* Fill dev struct with data from PCI device info given by index. */ + void fill_dev_data(uint8_t idx, struct Dev_info *dev); }; -#endif /* _CORE__INCLUDE__SPEC__X86_64__MUEN__SINFO_H_ */ +#endif /* _INCLUDE__SPEC__X86_64__MUEN__SINFO_H_ */ diff --git a/repos/base-hw/lib/mk/spec/muen/base-common.mk b/repos/base-hw/lib/mk/spec/muen/base-common.mk new file mode 100644 index 000000000..7185f8e66 --- /dev/null +++ b/repos/base-hw/lib/mk/spec/muen/base-common.mk @@ -0,0 +1,5 @@ +SRC_CC += sinfo.cc + +vpath %.cc $(REP_DIR)/src/base/muen + +include $(REP_DIR)/lib/mk/spec/x86_64/base-common.mk diff --git a/repos/base-hw/lib/mk/spec/x86_64/core-muen_on.mk b/repos/base-hw/lib/mk/spec/x86_64/core-muen_on.mk index 1c44f78fd..1c80456f9 100644 --- a/repos/base-hw/lib/mk/spec/x86_64/core-muen_on.mk +++ b/repos/base-hw/lib/mk/spec/x86_64/core-muen_on.mk @@ -16,7 +16,6 @@ SRC_S += spec/x86_64/muen/kernel/crt0_translation_table.s SRC_CC += spec/x86_64/muen/kernel/cpu_exception.cc SRC_CC += spec/x86_64/muen/kernel/thread_exception.cc SRC_CC += spec/x86_64/muen/platform_support.cc -SRC_CC += spec/x86_64/muen/sinfo.cc # include less specific configuration include $(REP_DIR)/lib/mk/spec/x86_64/core.inc diff --git a/repos/base-hw/src/core/spec/x86_64/muen/musinfo.h b/repos/base-hw/src/base/muen/musinfo.h similarity index 90% rename from repos/base-hw/src/core/spec/x86_64/muen/musinfo.h rename to repos/base-hw/src/base/muen/musinfo.h index 78490c7cb..560576f03 100644 --- a/repos/base-hw/src/core/spec/x86_64/muen/musinfo.h +++ b/repos/base-hw/src/base/muen/musinfo.h @@ -1,7 +1,7 @@ /* * \brief Muen subject info - * \author Stefan Kalkowski - * \date 2015-06-02 + * \author Reto Buerki + * \date 2015-04-21 */ /* @@ -11,8 +11,8 @@ * under the terms of the GNU General Public License version 2. */ -#ifndef _CORE__SPEC__X86_64__MUEN__MUSINFO_H_ -#define _CORE__SPEC__X86_64__MUEN__MUSINFO_H_ +#ifndef _BASE__MUEN__MUSINFO_H_ +#define _BASE__MUEN__MUSINFO_H_ #include @@ -82,4 +82,4 @@ struct subject_info_type { struct dev_info_type dev_info[MAX_RESOURCE_COUNT]; } __attribute__((packed, aligned (8))); -#endif /* _CORE__SPEC__X86_64__MUEN__MUSINFO_H_ */ +#endif /* _BASE__MUEN__MUSINFO_H_ */ diff --git a/repos/base-hw/src/core/spec/x86_64/muen/sinfo.cc b/repos/base-hw/src/base/muen/sinfo.cc similarity index 89% rename from repos/base-hw/src/core/spec/x86_64/muen/sinfo.cc rename to repos/base-hw/src/base/muen/sinfo.cc index 27b3c3dcb..1d989b097 100644 --- a/repos/base-hw/src/core/spec/x86_64/muen/sinfo.cc +++ b/repos/base-hw/src/base/muen/sinfo.cc @@ -13,18 +13,11 @@ #include #include -#include + +#include #include "musinfo.h" -enum { - SINFO_BASE_ADDR = 0xe00000000, -}; - -static const subject_info_type * -const sinfo = ((subject_info_type *)SINFO_BASE_ADDR); - - /* Log channel information */ static bool log_channel( const struct Genode::Sinfo::Channel_info * const channel, @@ -60,48 +53,6 @@ static bool log_memregion( } -/* Fill channel struct with channel information from resource given by index */ -static void fill_channel_data(uint8_t idx, - struct Genode::Sinfo::Channel_info *channel) -{ - const struct resource_type resource = sinfo->resources[idx]; - const struct memregion_type memregion = - sinfo->memregions[resource.memregion_idx - 1]; - const struct channel_info_type channel_info = - sinfo->channels_info[resource.channel_info_idx - 1]; - - memset(&channel->name, 0, MAX_NAME_LENGTH + 1); - memcpy(&channel->name, resource.name.data, resource.name.length); - - channel->address = memregion.address; - channel->size = memregion.size; - channel->writable = memregion.flags & MEM_WRITABLE_FLAG; - - channel->has_event = channel_info.flags & CHAN_EVENT_FLAG; - channel->event_number = channel_info.event; - channel->has_vector = channel_info.flags & CHAN_VECTOR_FLAG; - channel->vector = channel_info.vector; -} - - -/* Fill memregion struct with memory region info from resource given by index */ -static void fill_memregion_data(uint8_t idx, - struct Genode::Sinfo::Memregion_info *region) -{ - const struct resource_type resource = sinfo->resources[idx]; - const struct memregion_type memregion = - sinfo->memregions[resource.memregion_idx - 1]; - - memset(®ion->name, 0, MAX_NAME_LENGTH + 1); - memcpy(®ion->name, resource.name.data, resource.name.length); - - region->address = memregion.address; - region->size = memregion.size; - region->writable = memregion.flags & MEM_WRITABLE_FLAG; - region->executable = memregion.flags & MEM_EXECUTABLE_FLAG; -} - - /* Returns true if the given resource is a memory region */ static bool is_memregion(const struct resource_type * const resource) { @@ -116,32 +67,14 @@ static bool is_channel(const struct resource_type * const resource) } -/* Fill dev struct with data from PCI device info given by index */ -static void fill_dev_data(uint8_t idx, struct Genode::Sinfo::Dev_info *dev) +Sinfo::Sinfo(const addr_t base_addr) { - const struct dev_info_type dev_info = sinfo->dev_info[idx]; + sinfo = ((subject_info_type *)base_addr); - dev->sid = dev_info.sid; - dev->irte_start = dev_info.irte_start; - dev->irq_start = dev_info.irq_start; - dev->ir_count = dev_info.ir_count; - dev->msi_capable = dev_info.flags & DEV_MSI_FLAG; -} - - -Sinfo::Sinfo() -{ if (!check_magic()) { PERR("muen-sinfo: Subject information MAGIC mismatch\n"); return; } - - PINF("muen-sinfo: Subject information exports %d memory region(s)\n", - sinfo->memregion_count); - for_each_memregion(log_memregion, 0); - PINF("muen-sinfo: Subject information exports %d channel(s)\n", - sinfo->channel_info_count); - for_each_channel(log_channel, 0); } @@ -269,3 +202,73 @@ uint64_t Sinfo::get_sched_end(void) return sinfo->tsc_schedule_end; } + + +void Sinfo::log_status() +{ + if (!sinfo) { + PINF("Sinfo API not initialized"); + return; + } + if (!check_magic()) { + PINF("Sinfo MAGIC not found"); + return; + } + + PINF("muen-sinfo: Subject information exports %d memory region(s)\n", + sinfo->memregion_count); + for_each_memregion(log_memregion, 0); + PINF("muen-sinfo: Subject information exports %d channel(s)\n", + sinfo->channel_info_count); + for_each_channel(log_channel, 0); +} + + +void Sinfo::fill_memregion_data(uint8_t idx, struct Memregion_info *region) +{ + const struct resource_type resource = sinfo->resources[idx]; + const struct memregion_type memregion = + sinfo->memregions[resource.memregion_idx - 1]; + + memset(®ion->name, 0, MAX_NAME_LENGTH + 1); + memcpy(®ion->name, resource.name.data, resource.name.length); + + region->address = memregion.address; + region->size = memregion.size; + region->writable = memregion.flags & MEM_WRITABLE_FLAG; + region->executable = memregion.flags & MEM_EXECUTABLE_FLAG; +} + + +void Sinfo::fill_channel_data(uint8_t idx, struct Channel_info *channel) +{ + const struct resource_type resource = sinfo->resources[idx]; + const struct memregion_type memregion = + sinfo->memregions[resource.memregion_idx - 1]; + const struct channel_info_type channel_info = + sinfo->channels_info[resource.channel_info_idx - 1]; + + memset(&channel->name, 0, MAX_NAME_LENGTH + 1); + memcpy(&channel->name, resource.name.data, resource.name.length); + + channel->address = memregion.address; + channel->size = memregion.size; + channel->writable = memregion.flags & MEM_WRITABLE_FLAG; + + channel->has_event = channel_info.flags & CHAN_EVENT_FLAG; + channel->event_number = channel_info.event; + channel->has_vector = channel_info.flags & CHAN_VECTOR_FLAG; + channel->vector = channel_info.vector; +} + + +void Sinfo::fill_dev_data(uint8_t idx, struct Dev_info *dev) +{ + const struct dev_info_type dev_info = sinfo->dev_info[idx]; + + dev->sid = dev_info.sid; + dev->irte_start = dev_info.irte_start; + dev->irq_start = dev_info.irq_start; + dev->ir_count = dev_info.ir_count; + dev->msi_capable = dev_info.flags & DEV_MSI_FLAG; +} diff --git a/repos/base-hw/src/core/include/platform.h b/repos/base-hw/src/core/include/platform.h index 25b267caf..8225306b8 100644 --- a/repos/base-hw/src/core/include/platform.h +++ b/repos/base-hw/src/core/include/platform.h @@ -75,6 +75,11 @@ namespace Genode { */ void _init_io_mem_alloc(); + /** + * Perform additional platform-specific initialization. + */ + void _init_additional(); + public: /** diff --git a/repos/base-hw/src/core/include/spec/x86/board.h b/repos/base-hw/src/core/include/spec/x86/board.h index 4d72305b5..579090c59 100644 --- a/repos/base-hw/src/core/include/spec/x86/board.h +++ b/repos/base-hw/src/core/include/spec/x86/board.h @@ -1,5 +1,5 @@ /* - * \brief x86 mmio constants + * \brief x86 constants * \author Reto Buerki * \date 2015-03-18 */ diff --git a/repos/base-hw/src/core/include/spec/x86_64/muen/board.h b/repos/base-hw/src/core/include/spec/x86_64/muen/board.h new file mode 100644 index 000000000..b859af6fa --- /dev/null +++ b/repos/base-hw/src/core/include/spec/x86_64/muen/board.h @@ -0,0 +1,34 @@ +/* + * \brief x86_64_muen constants + * \author Adrian-Ken Rueegsegger + * \date 2015-07-02 + */ + +/* + * Copyright (C) 2015 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#ifndef _CORE__INCLUDE__SPEC__X86_64__MUEN__BOARD_H_ +#define _CORE__INCLUDE__SPEC__X86_64__MUEN__BOARD_H_ + +namespace Genode +{ + struct Board + { + enum { + TIMER_BASE_ADDR = 0xe00010000, + TIMER_SIZE = 0x1000, + + VECTOR_REMAP_BASE = 48, + TIMER_VECTOR_KERNEL = 32, + TIMER_VECTOR_USER = 50, + }; + + void init() { } + }; +} + +#endif /* _CORE__INCLUDE__SPEC__X86_64__MUEN__BOARD_H_ */ diff --git a/repos/base-hw/src/core/include/spec/x86_64/muen/sinfo_instance.h b/repos/base-hw/src/core/include/spec/x86_64/muen/sinfo_instance.h new file mode 100644 index 000000000..446d2e147 --- /dev/null +++ b/repos/base-hw/src/core/include/spec/x86_64/muen/sinfo_instance.h @@ -0,0 +1,35 @@ +/* + * \brief Sinfo kernel singleton + * \author Reto Buerki + * \date 2016-05-09 + */ + +/* + * 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 _CORE__INCLUDE__SPEC__X86_64__MUEN__SINFO_INSTANCE_H_ +#define _CORE__INCLUDE__SPEC__X86_64__MUEN__SINFO_INSTANCE_H_ + +/* base includes */ +#include +#include + +/* core includes */ +#include + +namespace Genode +{ + /** + * Return sinfo singleton + */ + static Sinfo * sinfo() { + static Sinfo singleton(Sinfo::PHYSICAL_BASE_ADDR); + return &singleton; + } +} + +#endif /* _CORE__INCLUDE__SPEC__X86_64__MUEN__SINFO_INSTANCE_H_ */ diff --git a/repos/base-hw/src/core/include/spec/x86_64/muen/timer.h b/repos/base-hw/src/core/include/spec/x86_64/muen/timer.h index fe7e76b93..f15be3af2 100644 --- a/repos/base-hw/src/core/include/spec/x86_64/muen/timer.h +++ b/repos/base-hw/src/core/include/spec/x86_64/muen/timer.h @@ -14,12 +14,13 @@ #ifndef _CORE__INCLUDE__SPEC__X86_64__MUEN__TIMER_H_ #define _CORE__INCLUDE__SPEC__X86_64__MUEN__TIMER_H_ +/* base includes */ #include #include /* core includes */ #include -#include +#include namespace Genode { @@ -47,6 +48,7 @@ class Genode::Timer struct Subject_timer * _timer_page; + inline uint64_t rdtsc() { uint32_t lo, hi; @@ -58,10 +60,15 @@ class Genode::Timer public: - Timer() : _tics_per_ms(Sinfo::get_tsc_khz()) + Timer() : + _tics_per_ms(sinfo()->get_tsc_khz()) { + + /* first sinfo instance, output status */ + sinfo()->log_status(); + struct Sinfo::Memregion_info region; - if (!Sinfo::get_memregion_info("timer", ®ion)) { + if (!sinfo()->get_memregion_info("timer", ®ion)) { PERR("muen-timer: Unable to retrieve time memory region"); throw Invalid_region(); } diff --git a/repos/base-hw/src/core/platform.cc b/repos/base-hw/src/core/platform.cc index ba3692990..b1567f6c9 100644 --- a/repos/base-hw/src/core/platform.cc +++ b/repos/base-hw/src/core/platform.cc @@ -162,6 +162,8 @@ Platform::Platform() _rom_fs.insert(rom_module); } + _init_additional(); + /* print ressource summary */ if (VERBOSE) { printf("Core virtual memory allocator\n"); 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 2a2a39ea2..a47924152 100644 --- a/repos/base-hw/src/core/spec/arm/platform_support.cc +++ b/repos/base-hw/src/core/spec/arm/platform_support.cc @@ -18,6 +18,8 @@ using namespace Genode; void Platform::_init_io_port_alloc() { }; +void Platform::_init_additional() { }; + void Platform::setup_irq_mode(unsigned, unsigned, unsigned) { } Native_region * mmio_regions(unsigned); 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 6cdfc0030..dde45000e 100644 --- a/repos/base-hw/src/core/spec/riscv/platform_support.cc +++ b/repos/base-hw/src/core/spec/riscv/platform_support.cc @@ -34,6 +34,8 @@ void Platform::_init_io_port_alloc() { } void Platform::_init_io_mem_alloc() { } +void Platform::_init_additional() { } + void Platform::setup_irq_mode(unsigned, unsigned, unsigned) { } long Platform::irq(long const user_irq) { return 0; } 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 e7bbb04d0..601c208e2 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 @@ -16,8 +16,9 @@ #include /* core includes */ +#include #include -#include +#include using namespace Genode; @@ -61,10 +62,9 @@ Native_region * Platform::_core_only_mmio_regions(unsigned const i) static Native_region _regions[] = { /* Sinfo pages */ - { 0x000e00000000, 0x7000 }, - + { Sinfo::PHYSICAL_BASE_ADDR, Sinfo::SIZE }, /* Timer page */ - { 0x000e00010000, 0x1000 }, + { Board::TIMER_BASE_ADDR, Board::TIMER_SIZE }, }; return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0; } @@ -79,7 +79,7 @@ bool Platform::get_msi_params(const addr_t mmconf, addr_t &address, const unsigned sid = Mmconf_address::to_sid(mmconf); struct Sinfo::Dev_info dev_info; - if (!Sinfo::get_dev_info(sid, &dev_info)) { + if (!sinfo()->get_dev_info(sid, &dev_info)) { PERR("error retrieving Muen info for device with SID 0x%x", sid); return false; } @@ -100,9 +100,28 @@ bool Platform::get_msi_params(const addr_t mmconf, addr_t &address, Native_region * Platform::_ram_regions(unsigned const i) { - static Native_region _regions[] = - { - { 25*1024*1024, 256*1024*1024 } - }; - return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0; + if (i) + return 0; + + static Native_region result = { .base = 0, .size = 0 }; + + if (!result.size) { + struct Sinfo::Memregion_info region; + if (!sinfo()->get_memregion_info("ram", ®ion)) { + PERR("Unable to retrieve base-hw ram region"); + return 0; + } + + result = { .base = region.address, .size = region.size }; + } + return &result; +} + + +void Platform::_init_additional() +{ + /* export subject info page as ROM module */ + _rom_fs.insert(new (core_mem_alloc()) + Rom_module((addr_t)Sinfo::PHYSICAL_BASE_ADDR, + Sinfo::SIZE, "subject_info_page")); } 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 6529278e6..b6fa5f421 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 @@ -23,6 +23,7 @@ using namespace Genode; /* contains physical pointer to multiboot */ extern "C" Genode::addr_t __initial_bx; +void Platform::_init_additional() { }; Native_region * Platform::_core_only_mmio_regions(unsigned const i) {