From 42db1e112bccdc5797100411f7da97d46eca4f86 Mon Sep 17 00:00:00 2001 From: Stefan Kalkowski Date: Tue, 20 Jun 2017 15:25:04 +0200 Subject: [PATCH] hw: introduce kernel/user address space split * introduces central memory map for core/kernel * on 32-bit platforms the kernel/core starts at 0x80000000 * on 64-bit platforms the kernel/core starts at 0xffffffc000000000 * mark kernel/core mappings as global ones (tagged TLB) * move the exception vector to begin of core's binary, thereby bootstrap knows from where to map it appropriately * do not map boot modules into core anymore * constrain core's virtual heap memory area * differentiate in between user's and core's main thread's UTCB, which now resides inside the kernel segment Ref #2091 --- repos/base-hw/lib/mk/base-hw.mk | 1 + repos/base-hw/lib/mk/core-hw.inc | 1 + repos/base-hw/lib/mk/spec/arm/core-hw.inc | 3 ++ .../lib/mk/spec/arndale/bootstrap-hw.mk | 1 + .../lib/mk/spec/imx53_qsb/bootstrap-hw.mk | 1 + .../lib/mk/spec/odroid_xu/bootstrap-hw.mk | 1 + .../base-hw/lib/mk/spec/panda/bootstrap-hw.mk | 1 + .../base-hw/lib/mk/spec/pbxa9/bootstrap-hw.mk | 1 + .../base-hw/lib/mk/spec/riscv/bootstrap-hw.mk | 3 ++ repos/base-hw/lib/mk/spec/riscv/core-hw.mk | 3 ++ repos/base-hw/lib/mk/spec/rpi/bootstrap-hw.mk | 1 + .../lib/mk/spec/usb_armory/bootstrap-hw.mk | 1 + .../lib/mk/spec/wand_quad/bootstrap-hw.mk | 1 + .../lib/mk/spec/x86_pc/bootstrap-hw.mk | 2 + repos/base-hw/lib/mk/spec/x86_pc/core-hw.mk | 4 ++ .../lib/mk/spec/zynq_qemu/bootstrap-hw.mk | 1 + repos/base-hw/src/bootstrap/platform.cc | 38 ++++++++------ repos/base-hw/src/bootstrap/platform.h | 2 +- .../base-hw/src/bootstrap/spec/x86_64/crt0.s | 4 +- repos/base-hw/src/core/kernel/init.cc | 2 +- repos/base-hw/src/core/native_utcb.cc | 21 ++++++++ repos/base-hw/src/core/platform.cc | 27 +++++++--- repos/base-hw/src/core/platform.h | 8 +-- repos/base-hw/src/core/platform_pd.cc | 4 +- repos/base-hw/src/core/platform_thread.cc | 2 +- repos/base-hw/src/core/spec/x86_64/cpu.cc | 10 +--- repos/base-hw/src/core/spec/x86_64/cpu.h | 2 +- .../src/core/spec/x86_64/mode_transition.s | 4 +- repos/base-hw/src/core/stack_area_addr.cc | 5 +- .../src/include/base/internal/native_utcb.h | 13 +++-- repos/base-hw/src/lib/base/native_utcb.cc | 18 +++++++ repos/base-hw/src/lib/hw/boot_info.h | 8 +-- .../src/lib/hw/{mmio_space.h => memory_map.h} | 25 +++++++--- .../base-hw/src/lib/hw/page_table_allocator.h | 9 ++-- .../src/lib/hw/spec/32bit/memory_map.cc | 49 +++++++++++++++++++ .../src/lib/hw/spec/64bit/memory_map.cc | 49 +++++++++++++++++++ repos/base-hw/src/lib/hw/spec/x86_64/gdt.s | 6 +-- repos/base-nova/src/kernel/nova/target.mk | 2 + repos/base/mk/spec/x86_64.mk | 2 +- tool/run/boot_dir/hw | 10 ++-- tool/run/run | 2 +- 41 files changed, 275 insertions(+), 73 deletions(-) create mode 100644 repos/base-hw/src/core/native_utcb.cc create mode 100644 repos/base-hw/src/lib/base/native_utcb.cc rename repos/base-hw/src/lib/hw/{mmio_space.h => memory_map.h} (65%) create mode 100644 repos/base-hw/src/lib/hw/spec/32bit/memory_map.cc create mode 100644 repos/base-hw/src/lib/hw/spec/64bit/memory_map.cc diff --git a/repos/base-hw/lib/mk/base-hw.mk b/repos/base-hw/lib/mk/base-hw.mk index 53ba241b4..c5fd86477 100644 --- a/repos/base-hw/lib/mk/base-hw.mk +++ b/repos/base-hw/lib/mk/base-hw.mk @@ -6,5 +6,6 @@ SRC_CC += cache.cc SRC_CC += raw_write_string.cc SRC_CC += signal_receiver.cc SRC_CC += stack_area_addr.cc +SRC_CC += native_utcb.cc LIBS += startup-hw base-hw-common cxx timeout-hw diff --git a/repos/base-hw/lib/mk/core-hw.inc b/repos/base-hw/lib/mk/core-hw.inc index c21b2cd4a..f1083aa2a 100644 --- a/repos/base-hw/lib/mk/core-hw.inc +++ b/repos/base-hw/lib/mk/core-hw.inc @@ -30,6 +30,7 @@ SRC_CC += io_mem_session_support.cc SRC_CC += irq_session_component.cc SRC_CC += main.cc SRC_CC += native_pd_component.cc +SRC_CC += native_utcb.cc SRC_CC += pd_session_support.cc SRC_CC += platform.cc SRC_CC += platform_rom_modules.cc diff --git a/repos/base-hw/lib/mk/spec/arm/core-hw.inc b/repos/base-hw/lib/mk/spec/arm/core-hw.inc index 7aa298e54..404bf1a77 100644 --- a/repos/base-hw/lib/mk/spec/arm/core-hw.inc +++ b/repos/base-hw/lib/mk/spec/arm/core-hw.inc @@ -8,6 +8,7 @@ INC_DIR += $(BASE_DIR)/../base-hw/src/core/spec/arm # add C++ sources +SRC_CC += spec/32bit/memory_map.cc SRC_CC += spec/arm/kernel/thread.cc SRC_CC += spec/arm/kernel/cpu_idle.cc SRC_CC += spec/arm/kernel/pd.cc @@ -16,5 +17,7 @@ SRC_CC += spec/arm/platform_support.cc # add assembly sources SRC_S += spec/arm/crt0.s +vpath spec/32bit/memory_map.cc $(BASE_DIR)/../base-hw/src/lib/hw + # include less specific configuration include $(BASE_DIR)/../base-hw/lib/mk/core-hw.inc diff --git a/repos/base-hw/lib/mk/spec/arndale/bootstrap-hw.mk b/repos/base-hw/lib/mk/spec/arndale/bootstrap-hw.mk index a7742f508..b39b09cc7 100644 --- a/repos/base-hw/lib/mk/spec/arndale/bootstrap-hw.mk +++ b/repos/base-hw/lib/mk/spec/arndale/bootstrap-hw.mk @@ -4,6 +4,7 @@ SRC_CC += bootstrap/spec/arm/cortex_a15_cpu.cc SRC_CC += bootstrap/spec/arndale/pic.cc SRC_CC += bootstrap/spec/arndale/platform.cc SRC_CC += hw/spec/arm/arm_v7_cpu.cc +SRC_CC += hw/spec/32bit/memory_map.cc SRC_S += bootstrap/spec/arm/crt0.s NR_OF_CPUS = 2 diff --git a/repos/base-hw/lib/mk/spec/imx53_qsb/bootstrap-hw.mk b/repos/base-hw/lib/mk/spec/imx53_qsb/bootstrap-hw.mk index 54946fea0..7fb52ce7b 100644 --- a/repos/base-hw/lib/mk/spec/imx53_qsb/bootstrap-hw.mk +++ b/repos/base-hw/lib/mk/spec/imx53_qsb/bootstrap-hw.mk @@ -6,6 +6,7 @@ SRC_CC += bootstrap/spec/arm/cortex_a8_mmu.cc SRC_CC += bootstrap/spec/arm/cpu.cc SRC_CC += bootstrap/spec/arm/imx_tzic.cc SRC_CC += hw/spec/arm/arm_v7_cpu.cc +SRC_CC += hw/spec/32bit/memory_map.cc ifneq ($(filter-out $(SPECS),trustzone),) SRC_CC += bootstrap/spec/imx53_qsb/platform.cc diff --git a/repos/base-hw/lib/mk/spec/odroid_xu/bootstrap-hw.mk b/repos/base-hw/lib/mk/spec/odroid_xu/bootstrap-hw.mk index cb1f113a9..8ac33e629 100644 --- a/repos/base-hw/lib/mk/spec/odroid_xu/bootstrap-hw.mk +++ b/repos/base-hw/lib/mk/spec/odroid_xu/bootstrap-hw.mk @@ -4,6 +4,7 @@ SRC_CC += bootstrap/spec/arm/cortex_a15_cpu.cc SRC_CC += bootstrap/spec/arm/pic.cc SRC_CC += bootstrap/spec/odroid_xu/platform.cc SRC_CC += hw/spec/arm/arm_v7_cpu.cc +SRC_CC += hw/spec/32bit/memory_map.cc SRC_S += bootstrap/spec/arm/crt0.s include $(REP_DIR)/lib/mk/bootstrap-hw.inc diff --git a/repos/base-hw/lib/mk/spec/panda/bootstrap-hw.mk b/repos/base-hw/lib/mk/spec/panda/bootstrap-hw.mk index c5cf0f769..b4fafa440 100644 --- a/repos/base-hw/lib/mk/spec/panda/bootstrap-hw.mk +++ b/repos/base-hw/lib/mk/spec/panda/bootstrap-hw.mk @@ -6,6 +6,7 @@ SRC_CC += bootstrap/spec/arm/cortex_a9_mmu.cc SRC_CC += bootstrap/spec/arm/pic.cc SRC_CC += bootstrap/spec/panda/platform.cc SRC_CC += hw/spec/arm/arm_v7_cpu.cc +SRC_CC += hw/spec/32bit/memory_map.cc SRC_S += bootstrap/spec/arm/crt0.s include $(BASE_DIR)/../base-hw/lib/mk/bootstrap-hw.inc diff --git a/repos/base-hw/lib/mk/spec/pbxa9/bootstrap-hw.mk b/repos/base-hw/lib/mk/spec/pbxa9/bootstrap-hw.mk index 618077340..96a604c33 100644 --- a/repos/base-hw/lib/mk/spec/pbxa9/bootstrap-hw.mk +++ b/repos/base-hw/lib/mk/spec/pbxa9/bootstrap-hw.mk @@ -7,5 +7,6 @@ SRC_CC += bootstrap/spec/arm/cortex_a9_mmu.cc SRC_CC += bootstrap/spec/arm/pic.cc SRC_CC += bootstrap/spec/pbxa9/platform.cc SRC_CC += hw/spec/arm/arm_v7_cpu.cc +SRC_CC += hw/spec/32bit/memory_map.cc include $(BASE_DIR)/../base-hw/lib/mk/bootstrap-hw.inc diff --git a/repos/base-hw/lib/mk/spec/riscv/bootstrap-hw.mk b/repos/base-hw/lib/mk/spec/riscv/bootstrap-hw.mk index 3015751ca..a36ecd166 100644 --- a/repos/base-hw/lib/mk/spec/riscv/bootstrap-hw.mk +++ b/repos/base-hw/lib/mk/spec/riscv/bootstrap-hw.mk @@ -2,6 +2,9 @@ INC_DIR += $(BASE_DIR)/../base-hw/src/bootstrap/spec/riscv SRC_CC += bootstrap/spec/riscv/platform.cc SRC_CC += lib/base/riscv/kernel/interface.cc +SRC_CC += spec/64bit/memory_map.cc SRC_S += bootstrap/spec/riscv/crt0.s +vpath spec/64bit/memory_map.cc $(BASE_DIR)/../base-hw/src/lib/hw + include $(BASE_DIR)/../base-hw/lib/mk/bootstrap-hw.inc diff --git a/repos/base-hw/lib/mk/spec/riscv/core-hw.mk b/repos/base-hw/lib/mk/spec/riscv/core-hw.mk index 46bf63c09..bba7102cc 100644 --- a/repos/base-hw/lib/mk/spec/riscv/core-hw.mk +++ b/repos/base-hw/lib/mk/spec/riscv/core-hw.mk @@ -11,10 +11,13 @@ SRC_CC += spec/riscv/kernel/pd.cc SRC_CC += spec/riscv/kernel/cpu.cc SRC_CC += spec/riscv/platform_support.cc SRC_CC += spec/riscv/timer.cc +SRC_CC += spec/64bit/memory_map.cc #add assembly sources SRC_S += spec/riscv/exception_vector.s SRC_S += spec/riscv/crt0.s +vpath spec/64bit/memory_map.cc $(BASE_DIR)/../base-hw/src/lib/hw + # include less specific configuration include $(REP_DIR)/lib/mk/core-hw.inc diff --git a/repos/base-hw/lib/mk/spec/rpi/bootstrap-hw.mk b/repos/base-hw/lib/mk/spec/rpi/bootstrap-hw.mk index 0588218dc..2d7149d43 100644 --- a/repos/base-hw/lib/mk/spec/rpi/bootstrap-hw.mk +++ b/repos/base-hw/lib/mk/spec/rpi/bootstrap-hw.mk @@ -2,6 +2,7 @@ INC_DIR += $(BASE_DIR)/../base-hw/src/bootstrap/spec/rpi SRC_CC += bootstrap/spec/rpi/platform.cc SRC_CC += hw/spec/arm/arm_v6_cpu.cc +SRC_CC += hw/spec/32bit/memory_map.cc SRC_S += bootstrap/spec/arm/crt0.s include $(BASE_DIR)/../base-hw/lib/mk/bootstrap-hw.inc diff --git a/repos/base-hw/lib/mk/spec/usb_armory/bootstrap-hw.mk b/repos/base-hw/lib/mk/spec/usb_armory/bootstrap-hw.mk index 9b978e2fb..914da2d13 100644 --- a/repos/base-hw/lib/mk/spec/usb_armory/bootstrap-hw.mk +++ b/repos/base-hw/lib/mk/spec/usb_armory/bootstrap-hw.mk @@ -7,5 +7,6 @@ SRC_CC += bootstrap/spec/arm/cpu.cc SRC_CC += bootstrap/spec/arm/imx_tzic.cc SRC_CC += bootstrap/spec/usb_armory/platform.cc SRC_CC += hw/spec/arm/arm_v7_cpu.cc +SRC_CC += hw/spec/32bit/memory_map.cc include $(BASE_DIR)/../base-hw/lib/mk/bootstrap-hw.inc diff --git a/repos/base-hw/lib/mk/spec/wand_quad/bootstrap-hw.mk b/repos/base-hw/lib/mk/spec/wand_quad/bootstrap-hw.mk index f172feac8..4e9cc4f3b 100644 --- a/repos/base-hw/lib/mk/spec/wand_quad/bootstrap-hw.mk +++ b/repos/base-hw/lib/mk/spec/wand_quad/bootstrap-hw.mk @@ -7,6 +7,7 @@ SRC_CC += bootstrap/spec/arm/cortex_a9_mmu.cc SRC_CC += bootstrap/spec/arm/pic.cc SRC_CC += bootstrap/spec/wand_quad/platform.cc SRC_CC += hw/spec/arm/arm_v7_cpu.cc +SRC_CC += hw/spec/32bit/memory_map.cc NR_OF_CPUS = 4 diff --git a/repos/base-hw/lib/mk/spec/x86_pc/bootstrap-hw.mk b/repos/base-hw/lib/mk/spec/x86_pc/bootstrap-hw.mk index 4d4067234..fb1c93dce 100644 --- a/repos/base-hw/lib/mk/spec/x86_pc/bootstrap-hw.mk +++ b/repos/base-hw/lib/mk/spec/x86_pc/bootstrap-hw.mk @@ -4,4 +4,6 @@ SRC_S += bootstrap/spec/x86_64/crt0.s SRC_CC += bootstrap/spec/x86_64/platform.cc SRC_S += bootstrap/spec/x86_64/crt0_translation_table.s +SRC_CC += hw/spec/64bit/memory_map.cc + include $(BASE_DIR)/../base-hw/lib/mk/bootstrap-hw.inc diff --git a/repos/base-hw/lib/mk/spec/x86_pc/core-hw.mk b/repos/base-hw/lib/mk/spec/x86_pc/core-hw.mk index c2a54f8f0..3258d32e0 100644 --- a/repos/base-hw/lib/mk/spec/x86_pc/core-hw.mk +++ b/repos/base-hw/lib/mk/spec/x86_pc/core-hw.mk @@ -34,5 +34,9 @@ SRC_CC += spec/x86_64/kernel/thread.cc SRC_CC += spec/x86_64/kernel/thread.cc SRC_CC += spec/x86_64/platform_support_common.cc +SRC_CC += spec/64bit/memory_map.cc + +vpath spec/64bit/memory_map.cc $(BASE_DIR)/../base-hw/src/lib/hw + # include less specific configuration include $(BASE_DIR)/../base-hw/lib/mk/core-hw.inc diff --git a/repos/base-hw/lib/mk/spec/zynq_qemu/bootstrap-hw.mk b/repos/base-hw/lib/mk/spec/zynq_qemu/bootstrap-hw.mk index e15b86e72..cfec2c59b 100644 --- a/repos/base-hw/lib/mk/spec/zynq_qemu/bootstrap-hw.mk +++ b/repos/base-hw/lib/mk/spec/zynq_qemu/bootstrap-hw.mk @@ -7,5 +7,6 @@ SRC_CC += bootstrap/spec/arm/cortex_a9_mmu.cc SRC_CC += bootstrap/spec/arm/pic.cc SRC_CC += bootstrap/spec/zynq/platform.cc SRC_CC += hw/spec/arm/arm_v7_cpu.cc +SRC_CC += hw/spec/32bit/memory_map.cc include $(BASE_DIR)/../base-hw/lib/mk/bootstrap-hw.inc diff --git a/repos/base-hw/src/bootstrap/platform.cc b/repos/base-hw/src/bootstrap/platform.cc index c5f040039..dbacd7ade 100644 --- a/repos/base-hw/src/bootstrap/platform.cc +++ b/repos/base-hw/src/bootstrap/platform.cc @@ -62,9 +62,10 @@ Platform::Pd::Pd(Platform::Ram_allocator & alloc) array(*Genode::construct_at(array_base)) { using namespace Genode; - map_insert(Mapping((addr_t)table_base, (addr_t)table_base, + addr_t const table_virt_base = Hw::Mm::core_page_tables().base; + map_insert(Mapping((addr_t)table_base, table_virt_base, sizeof(Table), Hw::PAGE_FLAGS_KERN_DATA)); - map_insert(Mapping((addr_t)array_base, (addr_t)array_base, + map_insert(Mapping((addr_t)array_base, table_virt_base + sizeof(Table), sizeof(Table_array), Hw::PAGE_FLAGS_KERN_DATA)); } @@ -93,16 +94,14 @@ void Platform::Pd::map_insert(Mapping m) ** Platform ** **************/ -addr_t Platform::_load_elf() +Mapping Platform::_load_elf() { using namespace Genode; using namespace Hw; - addr_t start = ~0UL; - addr_t end = 0; + Mapping ret; auto lambda = [&] (Genode::Elf_segment & segment) { void * phys = (void*)(core_elf_addr + segment.file_offset()); - start = min(start, (addr_t) phys); size_t const size = round_page(segment.mem_size()); if (segment.flags().w) { @@ -123,13 +122,22 @@ addr_t Platform::_load_elf() //FIXME: set read-only, privileged and global accordingly Page_flags flags{RW, segment.flags().x ? EXEC : NO_EXEC, - USER, NO_GLOBAL, RAM, CACHED}; + USER, GLOBAL, RAM, CACHED}; Mapping m((addr_t)phys, (addr_t)segment.start(), size, flags); - core_pd->map_insert(m); - end = max(end, (addr_t)segment.start() + size); + + /* + * Do not map the read-only, non-executable segment containing + * the boot modules, although it is a loadable segment, which we + * define so that the modules are loaded as ELF image + * via the bootloader + */ + if (segment.flags().x || segment.flags().w) + core_pd->map_insert(m); + else + ret = m; }; core_elf.for_each_segment(lambda); - return end; + return ret; } @@ -173,17 +181,17 @@ Platform::Platform() core_pd->map_insert(m); }); /* load ELF */ - addr_t const elf_end = _load_elf(); + Mapping boot_modules = _load_elf(); /* setup boot info page */ void * bi_base = ram_alloc.alloc(sizeof(Boot_info)); - core_pd->map_insert(Mapping((addr_t)bi_base, elf_end, sizeof(Boot_info), - Hw::PAGE_FLAGS_KERN_TEXT)); + core_pd->map_insert(Mapping((addr_t)bi_base, Hw::Mm::boot_info().base, + sizeof(Boot_info), Hw::PAGE_FLAGS_KERN_TEXT)); Boot_info & bootinfo = *construct_at(bi_base, (addr_t)&core_pd->table, (addr_t)&core_pd->array, - core_pd->mappings, board.core_mmio, - board.acpi_rsdp); + core_pd->mappings, boot_modules, + board.core_mmio, board.acpi_rsdp); /* add all left RAM to bootinfo */ ram_alloc.for_each_free_region([&] (Memory_region const & r) { diff --git a/repos/base-hw/src/bootstrap/platform.h b/repos/base-hw/src/bootstrap/platform.h index fe1ee586e..14fbc25bf 100644 --- a/repos/base-hw/src/bootstrap/platform.h +++ b/repos/base-hw/src/bootstrap/platform.h @@ -129,7 +129,7 @@ class Bootstrap::Platform addr_t core_elf_addr; Elf core_elf; - addr_t _load_elf(); + Mapping _load_elf(); public: diff --git a/repos/base-hw/src/bootstrap/spec/x86_64/crt0.s b/repos/base-hw/src/bootstrap/spec/x86_64/crt0.s index 592c30b54..2c28e0273 100644 --- a/repos/base-hw/src/bootstrap/spec/x86_64/crt0.s +++ b/repos/base-hw/src/bootstrap/spec/x86_64/crt0.s @@ -82,11 +82,14 @@ movl %eax, %cr0 /* Set up GDT */ + movl $_mt_gdt_ptr+2, %eax + movl $_mt_gdt_start, (%eax) lgdt _mt_gdt_ptr /* Indirect long jump to 64-bit code */ ljmp $8, $_start64 + .code64 _start64: @@ -119,7 +122,6 @@ _define_gdt 0 - /********************************* ** .bss (non-initialized data) ** *********************************/ diff --git a/repos/base-hw/src/core/kernel/init.cc b/repos/base-hw/src/core/kernel/init.cc index 1428a7b18..625ca0d32 100644 --- a/repos/base-hw/src/core/kernel/init.cc +++ b/repos/base-hw/src/core/kernel/init.cc @@ -34,7 +34,7 @@ Pd * Kernel::core_pd() { Pic * Kernel::pic() { return unmanaged_singleton(); } -extern "C" void _start() __attribute__((section(".text.crt0"))); +extern "C" void _start(); /** * Setup kernel environment diff --git a/repos/base-hw/src/core/native_utcb.cc b/repos/base-hw/src/core/native_utcb.cc new file mode 100644 index 000000000..54582c449 --- /dev/null +++ b/repos/base-hw/src/core/native_utcb.cc @@ -0,0 +1,21 @@ +/* + * \brief Core-local main thread's UTCB address + * \author Stefan Kalkowski + * \date 2017-06-21 + */ + +/* + * Copyright (C) 2017 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +/* base-internal includes */ +#include + +#include + +Genode::Native_utcb * Genode::utcb_main_thread() { + return (Genode::Native_utcb*) Hw::Mm::core_utcb_main_thread().base; } + diff --git a/repos/base-hw/src/core/platform.cc b/repos/base-hw/src/core/platform.cc index 142a3c70c..0e0adaad3 100644 --- a/repos/base-hw/src/core/platform.cc +++ b/repos/base-hw/src/core/platform.cc @@ -40,19 +40,21 @@ using namespace Genode; **************/ Hw::Boot_info const & Platform::_boot_info() { - return *reinterpret_cast(round_page((addr_t)&_prog_img_end)); } + return *reinterpret_cast(Hw::Mm::boot_info().base); } addr_t Platform::mmio_to_virt(addr_t mmio) { return _boot_info().mmio_space.virt_addr(mmio); } -Hw::Page_table & Platform::core_page_table() { - return *(Hw::Page_table*)_boot_info().table; } +addr_t Platform::core_page_table() { + return (addr_t)_boot_info().table; } Hw::Page_table::Allocator & Platform::core_page_table_allocator() { - using Allocator = Hw::Page_table::Allocator; - using Array = Allocator::Array; - return unmanaged_singleton(*((Array*)_boot_info().table_allocator))->alloc(); + using Allocator = Hw::Page_table::Allocator; + using Array = Allocator::Array; + addr_t virt_addr = Hw::Mm::core_page_tables().base + sizeof(Hw::Page_table); + return *unmanaged_singleton(_boot_info().table_allocator, + virt_addr); } void Platform::_init_io_mem_alloc() @@ -83,6 +85,15 @@ addr_t Platform::core_phys_addr(addr_t virt) } +addr_t Platform::_rom_module_phys(addr_t virt) +{ + Hw::Mapping m = _boot_info().boot_modules; + if (virt >= m.virt() && virt < (m.virt() + m.size())) + return (virt - m.virt()) + m.phys(); + return 0; +} + + Platform::Platform() : _io_mem_alloc(core_mem_alloc()), @@ -91,8 +102,8 @@ Platform::Platform() { struct Kernel_resource : Exception { }; - _core_mem_alloc.virt_alloc()->add_range(VIRT_ADDR_SPACE_START, - VIRT_ADDR_SPACE_SIZE); + _core_mem_alloc.virt_alloc()->add_range(Hw::Mm::core_heap().base, + Hw::Mm::core_heap().size); _core_virt_regions().for_each([this] (Hw::Memory_region const & r) { _core_mem_alloc.virt_alloc()->remove_range(r.base, r.size); }); _boot_info().elf_mappings.for_each([this] (Hw::Mapping const & m) { diff --git a/repos/base-hw/src/core/platform.h b/repos/base-hw/src/core/platform.h index bef41be53..8537b5f29 100644 --- a/repos/base-hw/src/core/platform.h +++ b/repos/base-hw/src/core/platform.h @@ -70,7 +70,7 @@ class Genode::Platform : public Genode::Platform_generic void _init_rom_modules(); - addr_t _rom_module_phys(addr_t virt) { return core_phys_addr(virt); } + addr_t _rom_module_phys(addr_t virt); public: @@ -109,7 +109,7 @@ class Genode::Platform : public Genode::Platform_generic static addr_t core_phys_addr(addr_t virt); - static Hw::Page_table & core_page_table(); + static addr_t core_page_table(); static Hw::Page_table::Allocator & core_page_table_allocator(); @@ -132,9 +132,9 @@ class Genode::Platform : public Genode::Platform_generic Range_allocator * irq_alloc() { return &_irq_alloc; } - addr_t vm_start() const { return VIRT_ADDR_SPACE_START; } + addr_t vm_start() const { return Hw::Mm::user().base; } - size_t vm_size() const { return VIRT_ADDR_SPACE_SIZE; } + size_t vm_size() const { return Hw::Mm::user().size; } Rom_fs *rom_fs() { return &_rom_fs; } diff --git a/repos/base-hw/src/core/platform_pd.cc b/repos/base-hw/src/core/platform_pd.cc index f9f4c256e..32bd62c60 100644 --- a/repos/base-hw/src/core/platform_pd.cc +++ b/repos/base-hw/src/core/platform_pd.cc @@ -80,7 +80,7 @@ void Hw::Address_space::flush(addr_t virt, size_t size, Core_local_addr) Hw::Address_space::Address_space(Kernel::Pd & pd, Page_table & tt, Page_table::Allocator & tt_alloc) -: _tt(tt), _tt_phys(Platform::core_phys_addr((addr_t)&tt)), +: _tt(tt), _tt_phys(Platform::core_page_table()), _tt_alloc(tt_alloc), _kernel_pd(pd) { Kernel::mtc()->map(_tt, _tt_alloc); } @@ -179,7 +179,7 @@ Platform_pd::~Platform_pd() extern int _mt_master_context_begin; Core_platform_pd::Core_platform_pd() -: Platform_pd(Platform::core_page_table(), +: Platform_pd(*(Hw::Page_table*)Hw::Mm::core_page_tables().base, Platform::core_page_table_allocator()) { Genode::construct_at(&_mt_master_context_begin, diff --git a/repos/base-hw/src/core/platform_thread.cc b/repos/base-hw/src/core/platform_thread.cc index 2a4c2cb79..cbfe8822b 100644 --- a/repos/base-hw/src/core/platform_thread.cc +++ b/repos/base-hw/src/core/platform_thread.cc @@ -142,7 +142,7 @@ int Platform_thread::start(void * const ip, void * const sp) error("invalid RM client"); return -1; }; - _utcb_pd_addr = utcb_main_thread(); + _utcb_pd_addr = (Native_utcb *)user_utcb_main_thread(); Hw::Address_space * as = static_cast(&*locked_ptr); if (!as->insert_translation((addr_t)_utcb_pd_addr, dsc->phys_addr(), sizeof(Native_utcb), Hw::PAGE_FLAGS_UTCB)) { diff --git a/repos/base-hw/src/core/spec/x86_64/cpu.cc b/repos/base-hw/src/core/spec/x86_64/cpu.cc index ce9522c61..d8eb68e49 100644 --- a/repos/base-hw/src/core/spec/x86_64/cpu.cc +++ b/repos/base-hw/src/core/spec/x86_64/cpu.cc @@ -15,18 +15,12 @@ #include #include -extern int _mt_begin; extern int _mt_tss; extern int _mt_idt; extern int _mt_gdt_start; extern int _mt_gdt_end; -Genode::addr_t Genode::Cpu::virt_mtc_addr(Genode::addr_t virt_base, - Genode::addr_t label) { - return virt_base + (label - (addr_t)&_mt_begin); } - - void Genode::Cpu::Context::init(addr_t const table, bool core) { /* Constants to handle IF, IOPL values */ @@ -57,7 +51,7 @@ void Genode::Cpu::Idt::init() { Pseudo_descriptor descriptor { (uint16_t)((addr_t)&_mt_tss - (addr_t)&_mt_idt), - (uint64_t)(virt_mtc_addr(exception_entry, (addr_t)&_mt_idt)) }; + (uint64_t)(&_mt_idt) }; asm volatile ("lidt %0" : : "m" (descriptor)); } @@ -66,6 +60,6 @@ void Genode::Cpu::Gdt::init() { addr_t const start = (addr_t)&_mt_gdt_start; uint16_t const limit = _mt_gdt_end - _mt_gdt_start - 1; - uint64_t const base = virt_mtc_addr(exception_entry, start); + uint64_t const base = start; asm volatile ("lgdt %0" :: "m" (Pseudo_descriptor(limit, base))); } diff --git a/repos/base-hw/src/core/spec/x86_64/cpu.h b/repos/base-hw/src/core/spec/x86_64/cpu.h index aa524739b..0f351da25 100644 --- a/repos/base-hw/src/core/spec/x86_64/cpu.h +++ b/repos/base-hw/src/core/spec/x86_64/cpu.h @@ -124,7 +124,7 @@ class Genode::Cpu Fpu & fpu() { return _fpu; } - static constexpr addr_t exception_entry = 0xffff0000; + static constexpr addr_t exception_entry = 0xffffffc000000000; static constexpr addr_t mtc_size = 1 << 13; static addr_t virt_mtc_addr(addr_t virt_base, addr_t label); diff --git a/repos/base-hw/src/core/spec/x86_64/mode_transition.s b/repos/base-hw/src/core/spec/x86_64/mode_transition.s index 37133f1e2..2ae609f0d 100644 --- a/repos/base-hw/src/core/spec/x86_64/mode_transition.s +++ b/repos/base-hw/src/core/spec/x86_64/mode_transition.s @@ -36,7 +36,7 @@ .set TSS_TYPE, 0x8900 /* mtc virt addresses */ -.set MT_BASE, 0xffff0000 +.set MT_BASE, 0xffffffc000000000 .set MT_TSS, MT_BASE + (_mt_tss - _mt_begin) .set MT_ISR, MT_BASE .set MT_IRQ_STACK, MT_BASE + (_mt_kernel_interrupt_stack - _mt_begin) @@ -77,7 +77,7 @@ mov \label@GOTPCREL(%rip), %\reg .endm -.section .text +.section ".text.crt0" /* * Page aligned base of mode transition code. diff --git a/repos/base-hw/src/core/stack_area_addr.cc b/repos/base-hw/src/core/stack_area_addr.cc index 9fca7d46f..a35c3efc6 100644 --- a/repos/base-hw/src/core/stack_area_addr.cc +++ b/repos/base-hw/src/core/stack_area_addr.cc @@ -14,4 +14,7 @@ /* base-internal includes */ #include -Genode::addr_t Genode::stack_area_virtual_base() { return 0xd0000000UL; } +#include + +Genode::addr_t Genode::stack_area_virtual_base() { + return Hw::Mm::core_stack_area().base; } diff --git a/repos/base-hw/src/include/base/internal/native_utcb.h b/repos/base-hw/src/include/base/internal/native_utcb.h index d92f70613..4c55ee0e2 100644 --- a/repos/base-hw/src/include/base/internal/native_utcb.h +++ b/repos/base-hw/src/include/base/internal/native_utcb.h @@ -31,17 +31,20 @@ namespace Genode { struct Native_utcb; - static constexpr addr_t VIRT_ADDR_SPACE_START = 0x1000; - static constexpr size_t VIRT_ADDR_SPACE_SIZE = 0xfffee000; - /** * The main thread's UTCB, used during bootstrap of the main thread before it * allocates its stack area, needs to be outside the virtual memory area * controlled by the RM session, because it is needed before the main * thread can access its RM session. + * We set it architectural independent to the start of the address space, + * but leave out page zero for * null-pointer dereference detection. */ - static constexpr Native_utcb * utcb_main_thread() { - return (Native_utcb *) (VIRT_ADDR_SPACE_START + VIRT_ADDR_SPACE_SIZE); } + static constexpr addr_t user_utcb_main_thread() { return get_page_size(); } + + /** + * Core and user-land components have different main thread's UTCB locations. + */ + Native_utcb * utcb_main_thread(); } diff --git a/repos/base-hw/src/lib/base/native_utcb.cc b/repos/base-hw/src/lib/base/native_utcb.cc new file mode 100644 index 000000000..4275ddd49 --- /dev/null +++ b/repos/base-hw/src/lib/base/native_utcb.cc @@ -0,0 +1,18 @@ +/* + * \brief Component-local main thread's UTCB address + * \author Stefan Kalkowski + * \date 2017-06-21 + */ + +/* + * Copyright (C) 2017 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +/* base-internal includes */ +#include + +Genode::Native_utcb * Genode::utcb_main_thread() { + return (Genode::Native_utcb *)user_utcb_main_thread(); } diff --git a/repos/base-hw/src/lib/hw/boot_info.h b/repos/base-hw/src/lib/hw/boot_info.h index d0946fabf..cf2bb4381 100644 --- a/repos/base-hw/src/lib/hw/boot_info.h +++ b/repos/base-hw/src/lib/hw/boot_info.h @@ -14,8 +14,8 @@ #ifndef _SRC__LIB__HW__BOOT_INFO_H_ #define _SRC__LIB__HW__BOOT_INFO_H_ -#include #include +#include namespace Hw { struct Boot_info; } @@ -26,6 +26,7 @@ struct Hw::Boot_info addr_t const table; addr_t const table_allocator; Mapping_pool const elf_mappings; + Mapping const boot_modules; Mmio_space const mmio_space; Memory_region_array ram_regions; Acpi_rsdp const acpi_rsdp; @@ -33,11 +34,12 @@ struct Hw::Boot_info Boot_info(addr_t const table, addr_t const table_alloc, Mapping_pool const elf_mappings, + Mapping const boot_modules, Mmio_space const mmio_space, Acpi_rsdp const &acpi_rsdp) : table(table), table_allocator(table_alloc), - elf_mappings(elf_mappings), mmio_space(mmio_space), - acpi_rsdp(acpi_rsdp) {} + elf_mappings(elf_mappings), boot_modules(boot_modules), + mmio_space(mmio_space), acpi_rsdp(acpi_rsdp) {} }; #endif /* _SRC__LIB__HW__BOOT_INFO_H_ */ diff --git a/repos/base-hw/src/lib/hw/mmio_space.h b/repos/base-hw/src/lib/hw/memory_map.h similarity index 65% rename from repos/base-hw/src/lib/hw/mmio_space.h rename to repos/base-hw/src/lib/hw/memory_map.h index 19541a55c..e137038f3 100644 --- a/repos/base-hw/src/lib/hw/mmio_space.h +++ b/repos/base-hw/src/lib/hw/memory_map.h @@ -1,5 +1,5 @@ /* - * \brief Representation of MMIO space + * \brief Memory map of core * \author Stefan Kalkowski * \date 2016-11-24 */ @@ -11,14 +11,27 @@ * under the terms of the GNU Affero General Public License version 3. */ -#ifndef _SRC__LIB__HW__MMIO_SPACE_H_ -#define _SRC__LIB__HW__MMIO_SPACE_H_ +#ifndef _SRC__LIB__HW__MEMORY_MAP_H_ +#define _SRC__LIB__HW__MEMORY_MAP_H_ #include #include #include -namespace Hw { struct Mmio_space; } +namespace Hw { + struct Mmio_space; + + namespace Mm { + Memory_region const user(); + Memory_region const core_utcb_main_thread(); + Memory_region const core_stack_area(); + Memory_region const core_page_tables(); + Memory_region const core_mmio(); + Memory_region const core_heap(); + Memory_region const exception_vector(); + Memory_region const boot_info(); + } +} struct Hw::Mmio_space : Hw::Memory_region_array { @@ -27,7 +40,7 @@ struct Hw::Mmio_space : Hw::Memory_region_array template void for_each_mapping(FUNC f) const { - addr_t virt_base = 0xf0000000UL; /* FIXME */ + addr_t virt_base = Mm::core_mmio().base; auto lambda = [&] (Memory_region const & r) { f(Mapping { r.base, virt_base, r.size, PAGE_FLAGS_KERN_IO }); virt_base += r.size + get_page_size(); @@ -52,4 +65,4 @@ struct Hw::Mmio_space : Hw::Memory_region_array } }; -#endif /* _SRC__LIB__HW__MMIO_SPACE_H_ */ +#endif /* _SRC__LIB__HW__MEMORY_MAP_H_ */ diff --git a/repos/base-hw/src/lib/hw/page_table_allocator.h b/repos/base-hw/src/lib/hw/page_table_allocator.h index e5af15486..ca6872d47 100644 --- a/repos/base-hw/src/lib/hw/page_table_allocator.h +++ b/repos/base-hw/src/lib/hw/page_table_allocator.h @@ -46,7 +46,7 @@ class Hw::Page_table_allocator template class Array; Page_table_allocator(addr_t virt_addr, addr_t phys_addr) - : _virt_addr(virt_addr), _phys_addr(phys_addr) {} + : _virt_addr(virt_addr), _phys_addr(phys_addr) { } template addr_t phys_addr(TABLE & table) { static_assert((sizeof(TABLE) == TABLE_SIZE), "unexpected size"); @@ -104,6 +104,7 @@ class Hw::Page_table_allocator::Array::Allocator private: using Bit_allocator = Genode::Bit_allocator; + using Array = Page_table_allocator::Array; Bit_allocator _free_tables; @@ -122,9 +123,9 @@ class Hw::Page_table_allocator::Array::Allocator Allocator(Table * tables, addr_t phys_addr) : Page_table_allocator((addr_t)tables, phys_addr) {} - explicit Allocator(Allocator & o) - : Page_table_allocator(o._virt_addr, o._phys_addr), - _free_tables(o._free_tables) + Allocator(addr_t phys_addr, addr_t virt_addr) + : Page_table_allocator(virt_addr, phys_addr), + _free_tables(static_cast(&reinterpret_cast(virt_addr)->alloc())->_free_tables) { static_assert(!__is_polymorphic(Bit_allocator), "base class needs to be non-virtual"); diff --git a/repos/base-hw/src/lib/hw/spec/32bit/memory_map.cc b/repos/base-hw/src/lib/hw/spec/32bit/memory_map.cc new file mode 100644 index 000000000..dbc571454 --- /dev/null +++ b/repos/base-hw/src/lib/hw/spec/32bit/memory_map.cc @@ -0,0 +1,49 @@ +/* + * \brief Memory map of core on ARM 32-bit + * \author Stefan Kalkowski + * \date 2017-06-21 + */ + +/* + * Copyright (C) 2017 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +/* base-internal includes */ +#include + +#include + +using Hw::Memory_region; +using Genode::addr_t; +using Genode::Native_utcb; + +static constexpr addr_t USER_START = Genode::user_utcb_main_thread() + + sizeof(Native_utcb); +static constexpr addr_t KERNEL_START = 0x80000000UL; + +Memory_region const Hw::Mm::user() { + return Memory_region(USER_START, KERNEL_START - USER_START); } + +Memory_region const Hw::Mm::core_heap() { + return Memory_region(0xa0000000UL, 0x10000000UL); } + +Memory_region const Hw::Mm::core_stack_area() { + return Memory_region(0xb0000000UL, 0x10000000UL); } + +Memory_region const Hw::Mm::core_page_tables() { + return Memory_region(0xc0000000UL, 0x10000000UL); } + +Memory_region const Hw::Mm::core_utcb_main_thread() { + return Memory_region(0xfffef000, sizeof(Native_utcb)); } + +Memory_region const Hw::Mm::core_mmio() { + return Memory_region(0xd0000000UL, 0x10000000UL); } + +Memory_region const Hw::Mm::boot_info() { + return Memory_region(0xfffe0000UL, 0x1000UL); } + +Memory_region const Hw::Mm::exception_vector() { + return Memory_region(0xffff0000UL, 0x1000UL); } diff --git a/repos/base-hw/src/lib/hw/spec/64bit/memory_map.cc b/repos/base-hw/src/lib/hw/spec/64bit/memory_map.cc new file mode 100644 index 000000000..48af72767 --- /dev/null +++ b/repos/base-hw/src/lib/hw/spec/64bit/memory_map.cc @@ -0,0 +1,49 @@ +/* + * \brief Memory map of core on 64bit + * \author Stefan Kalkowski + * \date 2017-08-03 + */ + +/* + * Copyright (C) 2017 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +/* base-internal includes */ +#include + +#include + +using Hw::Memory_region; +using Genode::addr_t; +using Genode::Native_utcb; + +static constexpr addr_t USER_START = Genode::user_utcb_main_thread() + + sizeof(Native_utcb); +static constexpr addr_t KERNEL_START = 0xffffffc000000000UL; + +Memory_region const Hw::Mm::user() { + return Memory_region(USER_START, KERNEL_START - USER_START); } + +Memory_region const Hw::Mm::core_heap() { + return Memory_region(0xffffffd000000000UL, 0x1000000000UL); } + +Memory_region const Hw::Mm::core_stack_area() { + return Memory_region(0xffffffe000000000UL, 0x10000000UL); } + +Memory_region const Hw::Mm::core_page_tables() { + return Memory_region(0xffffffe010000000UL, 0x10000000UL); } + +Memory_region const Hw::Mm::core_utcb_main_thread() { + return Memory_region(0xffffffe020000000UL, sizeof(Native_utcb)); } + +Memory_region const Hw::Mm::core_mmio() { + return Memory_region(0xffffffe030000000UL, 0x10000000UL); } + +Memory_region const Hw::Mm::boot_info() { + return Memory_region(0xffffffe040000000UL, 0x1000UL); } + +Memory_region const Hw::Mm::exception_vector() { + return Memory_region(0xfffffff000000000UL, 0x1000UL); } diff --git a/repos/base-hw/src/lib/hw/spec/x86_64/gdt.s b/repos/base-hw/src/lib/hw/spec/x86_64/gdt.s index 4eec15565..82f10ab4f 100644 --- a/repos/base-hw/src/lib/hw/spec/x86_64/gdt.s +++ b/repos/base-hw/src/lib/hw/spec/x86_64/gdt.s @@ -21,15 +21,15 @@ .align 4 .space 2 .global _mt_gdt_ptr - .global _mt_gdt_start _mt_gdt_ptr: - .word _mt_gdt_end - _mt_gdt_start - 1 /* limit */ - .long _mt_gdt_start /* base address */ + .word 55 /* limit */ + .long 0 /* base address */ .set TSS_LIMIT, 0x68 .set TSS_TYPE, 0x8900 .align 8 + .global _mt_gdt_start _mt_gdt_start: /* Null descriptor */ .quad 0 diff --git a/repos/base-nova/src/kernel/nova/target.mk b/repos/base-nova/src/kernel/nova/target.mk index cfe96b249..65463006d 100644 --- a/repos/base-nova/src/kernel/nova/target.mk +++ b/repos/base-nova/src/kernel/nova/target.mk @@ -23,10 +23,12 @@ CC_OPT += -pipe \ -fno-asynchronous-unwind-tables -std=gnu++0x CC_OPT_PIC := ifeq ($(filter-out $(SPECS),32bit),) +override CC_MARCH = -m32 CC_WARN += -Wframe-larger-than=96 CC_OPT += -mpreferred-stack-boundary=2 -mregparm=3 else ifeq ($(filter-out $(SPECS),64bit),) +override CC_MARCH = -m64 CC_WARN += -Wframe-larger-than=240 CC_OPT += -mpreferred-stack-boundary=4 -mcmodel=kernel -mno-red-zone else diff --git a/repos/base/mk/spec/x86_64.mk b/repos/base/mk/spec/x86_64.mk index 1d131adf3..ce1a8b20e 100644 --- a/repos/base/mk/spec/x86_64.mk +++ b/repos/base/mk/spec/x86_64.mk @@ -9,7 +9,7 @@ SPECS += x86 64bit REP_INC_DIR += include/spec/x86 REP_INC_DIR += include/spec/x86_64 -CC_MARCH ?= -m64 +CC_MARCH ?= -m64 -mcmodel=large # # Avoid wasting almost 4 MiB by telling the linker that the max page size is diff --git a/tool/run/boot_dir/hw b/tool/run/boot_dir/hw index 18fb7c743..9cbdf29ce 100644 --- a/tool/run/boot_dir/hw +++ b/tool/run/boot_dir/hw @@ -6,13 +6,13 @@ proc binary_name_timer { } { return "hw_timer_drv" } proc run_boot_string { } { return "\nkernel initialized" } proc bootstrap_link_address { } { - if {[have_spec "odroid_xu"]} { return "0x80000000" } + if {[have_spec "odroid_xu"]} { return "0x81000000" } if {[have_spec "pbxa9"]} { return "0x70000000" } if {[have_spec "usb_armory"]} { return "0x72000000" } if {[have_spec "x86_64"]} { return "0x00200000" } if {[have_spec "wand_quad"]} { return "0x10001000" } if {[have_spec "imx53_qsb"]} { return "0x70010000" } - if {[have_spec "arndale"]} { return "0x80000000" } + if {[have_spec "arndale"]} { return "0x81000000" } if {[have_spec "panda"]} { return "0x81000000" } if {[have_spec "zynq"]} { return "0x00100000" } if {[have_spec "riscv"]} { return "0x81000000" } @@ -23,9 +23,9 @@ proc bootstrap_link_address { } { } proc core_link_address { } { - if {[have_spec "riscv"]} { return "0x1000000" } - scan [bootstrap_link_address] 0x%x link_address - return [format 0x%08x [expr {$link_address + 0x10000000}]] + if {[have_spec "64bit"]} { return "0xffffffc000000000" } + if {[have_spec "32bit"]} { return "0x80000000" } + return 0; } diff --git a/tool/run/run b/tool/run/run index 543db76c0..53678caa6 100755 --- a/tool/run/run +++ b/tool/run/run @@ -770,7 +770,7 @@ proc build_core {lib modules target link_address} { # architecture dependent definitions set arch {} - if {[have_spec "x86_64"]} { set arch -m64 } + if {[have_spec "x86_64"]} { set arch { -m64 -mcmodel=large } } if {[have_spec "x86_32"]} { set arch -m32 } # determine the libgcc