mirror of
https://github.com/genodelabs/genode.git
synced 2025-06-17 14:48:20 +00:00
hw: bootstrap into kernel
Put the initialization of the cpu cores, setup of page-tables, enabling of MMU and caches into a separate component that is only used to bootstrap the kernel resp. core. Ref #2092
This commit is contained in:
committed by
Norman Feske
parent
8aa8423cfd
commit
cf943dac65
24
repos/base-hw/src/bootstrap/env.cc
Normal file
24
repos/base-hw/src/bootstrap/env.cc
Normal file
@ -0,0 +1,24 @@
|
||||
/*
|
||||
* \brief Environment dummy implementation needed by cxx library
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2016-09-23
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* base includes */
|
||||
#include <base/env.h>
|
||||
|
||||
/* core includes */
|
||||
#include <assert.h>
|
||||
|
||||
Genode::Env_deprecated * Genode::env_deprecated()
|
||||
{
|
||||
assert(false);
|
||||
return nullptr;
|
||||
}
|
13
repos/base-hw/src/bootstrap/hw/target.mk
Normal file
13
repos/base-hw/src/bootstrap/hw/target.mk
Normal file
@ -0,0 +1,13 @@
|
||||
TARGET = bootstrap
|
||||
LIBS = bootstrap-hw
|
||||
BOOTSTRAP_OBJ = bootstrap.o
|
||||
|
||||
$(TARGET): $(BOOTSTRAP_OBJ)
|
||||
$(VERBOSE)true
|
||||
|
||||
.PHONY: $(BOOTSTRAP_OBJ)
|
||||
$(BOOTSTRAP_OBJ):
|
||||
$(VERBOSE)$(LD) $(LD_MARCH) -u _start --whole-archive -r $(LINK_ITEMS) $(LIBCXX_GCC) -o $@
|
||||
|
||||
clean cleanall:
|
||||
$(VERBOSE)rm -f $(BOOTSTRAP_OBJ)
|
142
repos/base-hw/src/bootstrap/include/platform.h
Normal file
142
repos/base-hw/src/bootstrap/include/platform.h
Normal file
@ -0,0 +1,142 @@
|
||||
/*
|
||||
* \brief Platform interface
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2016-10-19
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2016-2017 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 _PLATFORM_H_
|
||||
#define _PLATFORM_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/allocator_avl.h>
|
||||
#include <base/internal/elf.h>
|
||||
#include <util/reconstructible.h>
|
||||
|
||||
/* core includes */
|
||||
#include <bootinfo.h>
|
||||
#include <board.h>
|
||||
#include <cpu.h>
|
||||
#include <pic.h>
|
||||
#include <rom_fs.h>
|
||||
|
||||
using Genode::addr_t;
|
||||
using Genode::size_t;
|
||||
using Genode::Bootinfo;
|
||||
using Genode::Core_mmio;
|
||||
using Genode::Mapping;
|
||||
using Genode::Memory_region;
|
||||
using Genode::Memory_region_array;
|
||||
using Genode::Rom_module;
|
||||
|
||||
|
||||
class Platform
|
||||
{
|
||||
private:
|
||||
|
||||
struct Board : Genode::Board
|
||||
{
|
||||
Memory_region_array early_ram_regions;
|
||||
Memory_region_array late_ram_regions;
|
||||
Core_mmio const core_mmio;
|
||||
|
||||
Board();
|
||||
};
|
||||
|
||||
|
||||
class Ram_allocator : public Genode::Allocator_avl_base
|
||||
{
|
||||
private:
|
||||
|
||||
using Base = Genode::Allocator_avl_base;
|
||||
|
||||
enum { BSZ = Genode::Allocator_avl::slab_block_size() };
|
||||
|
||||
Genode::Tslab<Base::Block, BSZ> _slab;
|
||||
Genode::uint8_t _first_slab[BSZ];
|
||||
|
||||
public:
|
||||
|
||||
Ram_allocator()
|
||||
: Genode::Allocator_avl_base(&_slab, sizeof(Base::Block)),
|
||||
_slab(this, (Genode::Slab_block*)&_first_slab) {}
|
||||
|
||||
void * alloc_aligned(size_t size, unsigned align);
|
||||
bool alloc(size_t size, void **out_addr) override;
|
||||
void * alloc(size_t size) { return Allocator::alloc(size); }
|
||||
|
||||
void add(Memory_region const &);
|
||||
void remove(Memory_region const &);
|
||||
|
||||
template <typename FUNC>
|
||||
void for_each_free_region(FUNC functor)
|
||||
{
|
||||
_block_tree().for_each([&] (Block const & b)
|
||||
{
|
||||
if (!b.used())
|
||||
functor(Genode::Memory_region(b.addr(), b.size()));
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct Pd
|
||||
{
|
||||
void * const table_base;
|
||||
void * const allocator_base;
|
||||
Bootinfo::Table & table;
|
||||
Bootinfo::Table_allocator & allocator;
|
||||
Bootinfo::Mapping_pool mappings;
|
||||
|
||||
Pd(Ram_allocator & alloc);
|
||||
|
||||
void map(Mapping m);
|
||||
void map_insert(Mapping m);
|
||||
};
|
||||
|
||||
|
||||
struct Elf : Genode::Elf_binary
|
||||
{
|
||||
Elf(addr_t const addr) : Genode::Elf_binary(addr) { }
|
||||
|
||||
template <typename T> void for_each_segment(T functor)
|
||||
{
|
||||
Genode::Elf_segment segment;
|
||||
for (unsigned i = 0; (segment = get_segment(i)).valid(); i++) {
|
||||
if (segment.flags().skip) continue;
|
||||
if (segment.mem_size() == 0) continue;
|
||||
functor(segment);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Board board;
|
||||
Genode::Cpu cpu;
|
||||
Genode::Pic pic;
|
||||
Ram_allocator ram_alloc;
|
||||
Memory_region const bootstrap_region;
|
||||
Genode::Constructible<Pd> core_pd;
|
||||
addr_t core_elf_addr;
|
||||
Elf core_elf;
|
||||
|
||||
addr_t _load_elf();
|
||||
|
||||
public:
|
||||
|
||||
Platform();
|
||||
|
||||
static addr_t mmio_to_virt(addr_t mmio) { return mmio; }
|
||||
|
||||
void enable_mmu();
|
||||
void start_core() __attribute__((noreturn));
|
||||
};
|
||||
|
||||
extern Platform & platform();
|
||||
|
||||
#endif /* _PLATFORM_H_ */
|
30
repos/base-hw/src/bootstrap/init.cc
Normal file
30
repos/base-hw/src/bootstrap/init.cc
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* \brief Initialization code for bootstrap
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2016-09-22
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* local */
|
||||
#include <platform.h>
|
||||
|
||||
/* base includes */
|
||||
#include <base/internal/globals.h>
|
||||
#include <base/internal/unmanaged_singleton.h>
|
||||
|
||||
Platform & platform() { return *unmanaged_singleton<Platform>(); }
|
||||
|
||||
extern "C" void init() __attribute__ ((noreturn));
|
||||
|
||||
extern "C" void init()
|
||||
{
|
||||
Genode::init_log();
|
||||
platform().enable_mmu();
|
||||
platform().start_core();
|
||||
}
|
32
repos/base-hw/src/bootstrap/lock.cc
Normal file
32
repos/base-hw/src/bootstrap/lock.cc
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* \brief Lock dummy implementation
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2016-09-23
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <base/lock.h>
|
||||
#include <assert.h>
|
||||
|
||||
Genode::Cancelable_lock::Cancelable_lock(Genode::Cancelable_lock::State state)
|
||||
: _state(state), _owner(nullptr) { }
|
||||
|
||||
|
||||
void Genode::Cancelable_lock::unlock()
|
||||
{
|
||||
assert(_state == LOCKED);
|
||||
_state = UNLOCKED;
|
||||
}
|
||||
|
||||
|
||||
void Genode::Cancelable_lock::lock()
|
||||
{
|
||||
assert(_state == UNLOCKED);
|
||||
_state = LOCKED;
|
||||
}
|
191
repos/base-hw/src/bootstrap/platform.cc
Normal file
191
repos/base-hw/src/bootstrap/platform.cc
Normal file
@ -0,0 +1,191 @@
|
||||
/*
|
||||
* \brief Platform implementation
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2016-10-19
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* base-internal includes */
|
||||
#include <base/internal/crt0.h>
|
||||
|
||||
/* core includes */
|
||||
#include <assert.h>
|
||||
#include <boot_modules.h>
|
||||
#include <platform.h>
|
||||
|
||||
|
||||
/*****************************
|
||||
** Platform::Ram_allocator **
|
||||
*****************************/
|
||||
|
||||
void * Platform::Ram_allocator::alloc_aligned(size_t size, unsigned align)
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
void * ret;
|
||||
assert(Base::alloc_aligned(round_page(size), &ret,
|
||||
max(align, get_page_size_log2())).ok());
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
bool Platform::Ram_allocator::alloc(size_t size, void **out_addr)
|
||||
{
|
||||
*out_addr = alloc_aligned(size, 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void Platform::Ram_allocator::add(Memory_region const & region) {
|
||||
add_range(region.base, region.size); }
|
||||
|
||||
|
||||
void Platform::Ram_allocator::remove(Memory_region const & region) {
|
||||
remove_range(region.base, region.size); }
|
||||
|
||||
|
||||
/******************
|
||||
** Platform::Pd **
|
||||
******************/
|
||||
|
||||
Platform::Pd::Pd(Platform::Ram_allocator & alloc)
|
||||
: table_base(alloc.alloc_aligned(sizeof(Bootinfo::Table),
|
||||
Bootinfo::Table::ALIGNM_LOG2)),
|
||||
allocator_base(alloc.alloc_aligned(sizeof(Bootinfo::Table_allocator),
|
||||
Bootinfo::Table::ALIGNM_LOG2)),
|
||||
table(*Genode::construct_at<Bootinfo::Table>(table_base)),
|
||||
allocator(*Genode::construct_at<Bootinfo::Table_allocator>(allocator_base))
|
||||
{
|
||||
using namespace Genode;
|
||||
map_insert(Mapping((addr_t)table_base, (addr_t)table_base,
|
||||
sizeof(Bootinfo::Table), PAGE_FLAGS_KERN_DATA));
|
||||
map_insert(Mapping((addr_t)allocator_base, (addr_t)allocator_base,
|
||||
sizeof(Bootinfo::Table_allocator), PAGE_FLAGS_KERN_DATA));
|
||||
}
|
||||
|
||||
|
||||
void Platform::Pd::map(Mapping m)
|
||||
{
|
||||
try {
|
||||
table.insert_translation(m.virt(), m.phys(), m.size(), m.flags(),
|
||||
allocator.alloc());
|
||||
} catch(Genode::Allocator::Out_of_memory) {
|
||||
Genode::error("translation table needs to much RAM");
|
||||
} catch (...) {
|
||||
Genode::error("invalid mapping ", m);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Platform::Pd::map_insert(Mapping m)
|
||||
{
|
||||
mappings.add(m);
|
||||
map(m);
|
||||
}
|
||||
|
||||
|
||||
/**************
|
||||
** Platform **
|
||||
**************/
|
||||
|
||||
addr_t Platform::_load_elf()
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
addr_t start = ~0UL;
|
||||
addr_t end = 0;
|
||||
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) {
|
||||
unsigned align_log2;
|
||||
for (align_log2 = 0; align_log2 < 8*sizeof(addr_t); align_log2++)
|
||||
if ((addr_t)(1 << align_log2) & (addr_t)phys) break;
|
||||
|
||||
void * const dst = ram_alloc.alloc_aligned(segment.mem_size(),
|
||||
align_log2);
|
||||
memcpy(dst, phys, segment.file_size());
|
||||
|
||||
if (size > segment.file_size())
|
||||
memset((void *)((addr_t)dst + segment.file_size()),
|
||||
0, size - segment.file_size());
|
||||
|
||||
phys = dst;
|
||||
}
|
||||
|
||||
//FIXME: set read-only, privileged and global accordingly
|
||||
Page_flags flags{RW, segment.flags().x ? EXEC : NO_EXEC,
|
||||
USER, NO_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);
|
||||
};
|
||||
core_elf.for_each_segment(lambda);
|
||||
return end;
|
||||
}
|
||||
|
||||
|
||||
void Platform::start_core()
|
||||
{
|
||||
typedef void (* Entry)();
|
||||
Entry __attribute__((noreturn)) const entry
|
||||
= reinterpret_cast<Entry>(core_elf.entry());
|
||||
entry();
|
||||
}
|
||||
|
||||
|
||||
static constexpr Genode::Boot_modules_header & header() {
|
||||
return *((Genode::Boot_modules_header*) &_boot_modules_headers_begin); }
|
||||
|
||||
|
||||
Platform::Platform()
|
||||
: bootstrap_region((addr_t)&_prog_img_beg,
|
||||
((addr_t)&_prog_img_end - (addr_t)&_prog_img_beg)),
|
||||
core_pd(ram_alloc),
|
||||
core_elf_addr(header().base),
|
||||
core_elf(core_elf_addr)
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
/* prepare the ram allocator */
|
||||
board.early_ram_regions.for_each([this] (Memory_region const & region) {
|
||||
ram_alloc.add(region); });
|
||||
ram_alloc.remove(bootstrap_region);
|
||||
|
||||
/* now we can use the ram allocator for core's pd */
|
||||
core_pd.construct(ram_alloc);
|
||||
|
||||
/* temporarily map all bootstrap memory 1:1 for transition to core */
|
||||
// FIXME do not insert as mapping for core
|
||||
core_pd->map_insert(Mapping(bootstrap_region.base, bootstrap_region.base,
|
||||
bootstrap_region.size, PAGE_FLAGS_KERN_TEXT));
|
||||
|
||||
/* map memory-mapped I/O for core */
|
||||
board.core_mmio.for_each_mapping([&] (Mapping const & m) {
|
||||
core_pd->map_insert(m); });
|
||||
|
||||
/* load ELF */
|
||||
addr_t const elf_end = _load_elf();
|
||||
|
||||
/* setup boot info page */
|
||||
void * bi_base = ram_alloc.alloc(sizeof(Bootinfo));
|
||||
core_pd->map_insert(Mapping((addr_t)bi_base, elf_end, sizeof(Bootinfo),
|
||||
PAGE_FLAGS_KERN_TEXT));
|
||||
Bootinfo & bootinfo =
|
||||
*construct_at<Bootinfo>(bi_base, &core_pd->table, &core_pd->allocator,
|
||||
core_pd->mappings, board.core_mmio);
|
||||
|
||||
/* add all left RAM to bootinfo */
|
||||
ram_alloc.for_each_free_region([&] (Memory_region const & r) {
|
||||
bootinfo.ram_regions.add(r); });
|
||||
board.late_ram_regions.for_each([&] (Memory_region const & r) {
|
||||
bootinfo.ram_regions.add(r); });
|
||||
}
|
60
repos/base-hw/src/bootstrap/spec/arm/crt0.s
Normal file
60
repos/base-hw/src/bootstrap/spec/arm/crt0.s
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* \brief Startup code for bootstrap
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2016-09-22
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
.include "macros.s"
|
||||
|
||||
.set STACK_SIZE, 4 * 16 * 1024
|
||||
|
||||
.section ".text.crt0"
|
||||
|
||||
.global _start
|
||||
_start:
|
||||
|
||||
/* zero-fill BSS segment */
|
||||
adr r0, _bss_local_start
|
||||
adr r1, _bss_local_end
|
||||
ldr r0, [r0]
|
||||
ldr r1, [r1]
|
||||
mov r2, #0
|
||||
1:
|
||||
cmp r1, r0
|
||||
ble 2f
|
||||
str r2, [r0]
|
||||
add r0, r0, #4
|
||||
b 1b
|
||||
2:
|
||||
|
||||
.global _start_setup_stack
|
||||
_start_setup_stack:
|
||||
|
||||
/* setup multiprocessor-aware kernel stack-pointer */
|
||||
adr r0, _start_stack
|
||||
adr r1, _start_stack_size
|
||||
ldr r1, [r1]
|
||||
_init_kernel_sp r0, r1
|
||||
b init
|
||||
|
||||
_bss_local_start:
|
||||
.long _bss_start
|
||||
|
||||
_bss_local_end:
|
||||
.long _bss_end
|
||||
|
||||
_start_stack_size:
|
||||
.long STACK_SIZE
|
||||
|
||||
.align 3
|
||||
_start_stack:
|
||||
.rept NR_OF_CPUS
|
||||
.space STACK_SIZE
|
||||
.endr
|
23
repos/base-hw/src/bootstrap/spec/arm_v6/cpu.cc
Normal file
23
repos/base-hw/src/bootstrap/spec/arm_v6/cpu.cc
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* \brief CPU driver for core
|
||||
* \author Norman Feske
|
||||
* \author Martin stein
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2012-08-30
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012-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.
|
||||
*/
|
||||
|
||||
#include <cpu.h>
|
||||
|
||||
void Genode::Arm::clean_invalidate_data_cache() {
|
||||
asm volatile ("mcr p15, 0, %[rd], c7, c14, 0" :: [rd]"r"(0) : ); }
|
||||
|
||||
|
||||
void Genode::Cpu::translation_added(Genode::addr_t const addr,
|
||||
Genode::size_t const size) { }
|
108
repos/base-hw/src/bootstrap/spec/arndale/cpu.cc
Normal file
108
repos/base-hw/src/bootstrap/spec/arndale/cpu.cc
Normal file
@ -0,0 +1,108 @@
|
||||
/*
|
||||
* \brief CPU-specific initialization code for Arndale
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2016-01-07
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* core includes */
|
||||
#include <cpu.h>
|
||||
#include <translation_table.h>
|
||||
|
||||
static unsigned char hyp_mode_stack[1024];
|
||||
|
||||
|
||||
static inline void prepare_nonsecure_world()
|
||||
{
|
||||
using Nsacr = Genode::Cpu::Nsacr;
|
||||
using Cpsr = Genode::Cpu::Psr;
|
||||
using Scr = Genode::Cpu::Scr;
|
||||
|
||||
/* if we are already in HYP mode we're done (depends on u-boot version) */
|
||||
if (Cpsr::M::get(Cpsr::read()) == Cpsr::M::HYP)
|
||||
return;
|
||||
|
||||
/* ARM generic timer counter freq needs to be set in secure mode */
|
||||
volatile unsigned long * mct_control = (unsigned long*) 0x101C0240;
|
||||
*mct_control = 0x100;
|
||||
asm volatile ("mcr p15, 0, %0, c14, c0, 0" :: "r" (24000000));
|
||||
|
||||
/*
|
||||
* enable coprocessor 10 + 11 access and SMP bit access in auxiliary control
|
||||
* register for non-secure world
|
||||
*/
|
||||
Nsacr::access_t nsacr = 0;
|
||||
Nsacr::Cpnsae10::set(nsacr, 1);
|
||||
Nsacr::Cpnsae11::set(nsacr, 1);
|
||||
Nsacr::Ns_smp::set(nsacr, 1);
|
||||
Nsacr::write(nsacr);
|
||||
|
||||
asm volatile (
|
||||
"msr sp_mon, sp \n" /* copy current mode's sp */
|
||||
"msr lr_mon, lr \n" /* copy current mode's lr */
|
||||
"cps #22 \n" /* switch to monitor mode */
|
||||
);
|
||||
|
||||
Scr::access_t scr = 0;
|
||||
Scr::Ns::set(scr, 1);
|
||||
Scr::Fw::set(scr, 1);
|
||||
Scr::Aw::set(scr, 1);
|
||||
Scr::Scd::set(scr, 1);
|
||||
Scr::Hce::set(scr, 1);
|
||||
Scr::Sif::set(scr, 1);
|
||||
Scr::write(scr);
|
||||
}
|
||||
|
||||
|
||||
static inline void prepare_hypervisor(Genode::Translation_table & table)
|
||||
{
|
||||
using Genode::Cpu;
|
||||
|
||||
/* set hypervisor exception vector */
|
||||
Cpu::hyp_exception_entry_at((void*)0xfff00000); /* FIXME */
|
||||
|
||||
/* set hypervisor's translation table */
|
||||
Cpu::Httbr::translation_table((Genode::addr_t)&table);
|
||||
|
||||
/* prepare MMU usage by hypervisor code */
|
||||
Cpu::Htcr::write(Cpu::Ttbcr::init_virt_kernel());
|
||||
Cpu::Hcptr::write(Cpu::Hcptr::init());
|
||||
Cpu::Hmair0::write(Cpu::Mair0::init_virt_kernel());
|
||||
Cpu::Vtcr::write(Cpu::Vtcr::init());
|
||||
Cpu::Hsctlr::write(Cpu::Sctlr::init_value());
|
||||
}
|
||||
|
||||
|
||||
static inline void switch_to_supervisor_mode()
|
||||
{
|
||||
using Psr = Genode::Cpu::Psr;
|
||||
|
||||
Psr::access_t psr = 0;
|
||||
Psr::M::set(psr, Psr::M::SVC);
|
||||
Psr::F::set(psr, 1);
|
||||
Psr::I::set(psr, 1);
|
||||
|
||||
asm volatile (
|
||||
"msr sp_svc, sp \n" /* copy current mode's sp */
|
||||
"msr lr_svc, lr \n" /* copy current mode's lr */
|
||||
"msr elr_hyp, lr \n" /* copy current mode's lr to hyp lr */
|
||||
"msr sp_hyp, %[stack] \n" /* copy to hyp stack pointer */
|
||||
"msr spsr_cxfs, %[psr] \n" /* set psr for supervisor mode */
|
||||
"adr lr, 1f \n" /* load exception return address */
|
||||
"eret \n" /* exception return */
|
||||
"1:":: [psr] "r" (psr), [stack] "r" (&hyp_mode_stack));
|
||||
}
|
||||
|
||||
|
||||
void Genode::Cpu::init(Genode::Translation_table & table)
|
||||
{
|
||||
prepare_nonsecure_world();
|
||||
prepare_hypervisor(table);
|
||||
switch_to_supervisor_mode();
|
||||
}
|
169
repos/base-hw/src/bootstrap/spec/cortex_a9/platform.cc
Normal file
169
repos/base-hw/src/bootstrap/spec/cortex_a9/platform.cc
Normal file
@ -0,0 +1,169 @@
|
||||
/*
|
||||
* \brief Cpu class implementation specific to Cortex A9 SMP
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2015-12-09
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2015-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.
|
||||
*/
|
||||
|
||||
#include <base/log.h>
|
||||
|
||||
/* core includes */
|
||||
#include <kernel/lock.h>
|
||||
#include <platform.h>
|
||||
|
||||
//using namespace Kernel;
|
||||
|
||||
/* entrypoint for non-boot CPUs */
|
||||
extern "C" void * _start_setup_stack;
|
||||
|
||||
|
||||
/**
|
||||
* SMP-safe simple counter
|
||||
*/
|
||||
class Cpu_counter
|
||||
{
|
||||
private:
|
||||
|
||||
Kernel::Lock _lock;
|
||||
volatile int _value = 0;
|
||||
|
||||
public:
|
||||
|
||||
void inc()
|
||||
{
|
||||
Kernel::Lock::Guard guard(_lock);
|
||||
Genode::memory_barrier();
|
||||
_value++;
|
||||
}
|
||||
|
||||
void wait_for(int const v) {
|
||||
while (_value < v) ; }
|
||||
};
|
||||
|
||||
|
||||
struct Scu : Genode::Mmio
|
||||
{
|
||||
struct Cr : Register<0x0, 32>
|
||||
{
|
||||
struct Enable : Bitfield<0, 1> { };
|
||||
};
|
||||
|
||||
struct Dcr : Register<0x30, 32>
|
||||
{
|
||||
struct Bit_0 : Bitfield<0, 1> { };
|
||||
};
|
||||
|
||||
struct Iassr : Register<0xc, 32>
|
||||
{
|
||||
struct Cpu0_way : Bitfield<0, 4> { };
|
||||
struct Cpu1_way : Bitfield<4, 4> { };
|
||||
struct Cpu2_way : Bitfield<8, 4> { };
|
||||
struct Cpu3_way : Bitfield<12, 4> { };
|
||||
};
|
||||
|
||||
Scu(Genode::addr_t mmio) : Genode::Mmio(mmio) { }
|
||||
|
||||
void invalidate()
|
||||
{
|
||||
Iassr::access_t iassr = 0;
|
||||
for (Iassr::access_t way = 0; way <= Iassr::Cpu0_way::mask();
|
||||
way++) {
|
||||
Iassr::Cpu0_way::set(iassr, way);
|
||||
Iassr::Cpu1_way::set(iassr, way);
|
||||
Iassr::Cpu2_way::set(iassr, way);
|
||||
Iassr::Cpu3_way::set(iassr, way);
|
||||
write<Iassr>(iassr);
|
||||
}
|
||||
}
|
||||
|
||||
void enable(bool err_arm_764369)
|
||||
{
|
||||
if (err_arm_764369) write<Dcr::Bit_0>(1);
|
||||
write<Cr::Enable>(1);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* The initialization of Cortex A9 multicore systems implies a sophisticated
|
||||
* algorithm in early revisions of this cpu.
|
||||
*
|
||||
* See ARM's Cortex-A9 MPCore TRM r2p0 in section 5.3.5 for more details
|
||||
*/
|
||||
void Platform::enable_mmu()
|
||||
{
|
||||
using Genode::Cpu;
|
||||
static volatile bool primary_cpu = true;
|
||||
static Cpu_counter data_cache_invalidated;
|
||||
static Cpu_counter data_cache_enabled;
|
||||
static Cpu_counter smp_coherency_enabled;
|
||||
|
||||
bool primary = primary_cpu;
|
||||
if (primary) primary_cpu = false;
|
||||
|
||||
Cpu::Sctlr::init();
|
||||
Cpu::Psr::write(Cpu::Psr::init_kernel());
|
||||
|
||||
/* locally initialize interrupt controller */
|
||||
pic.init_cpu_local();
|
||||
|
||||
cpu.invalidate_inner_data_cache();
|
||||
data_cache_invalidated.inc();
|
||||
|
||||
/* primary cpu wakes up all others */
|
||||
if (primary && NR_OF_CPUS > 1) {
|
||||
board.wake_up_all_cpus(&_start_setup_stack);
|
||||
|
||||
/* send an IPI to all other cpus */
|
||||
pic.send_ipi();
|
||||
}
|
||||
|
||||
/* wait for other cores' data cache invalidation */
|
||||
data_cache_invalidated.wait_for(NR_OF_CPUS);
|
||||
|
||||
if (primary) {
|
||||
Scu scu(Board::SCU_MMIO_BASE);
|
||||
scu.invalidate();
|
||||
Board::L2_cache l2_cache(Board::PL310_MMIO_BASE);
|
||||
l2_cache.disable();
|
||||
l2_cache.invalidate();
|
||||
scu.enable(board.errata(Platform::Board::ARM_764369));
|
||||
}
|
||||
|
||||
/* secondary cpus wait for the primary's cache activation */
|
||||
if (!primary) data_cache_enabled.wait_for(1);
|
||||
|
||||
cpu.enable_mmu_and_caches((Genode::addr_t)core_pd->table_base);
|
||||
|
||||
data_cache_enabled.inc();
|
||||
cpu.clean_invalidate_inner_data_cache();
|
||||
|
||||
/* wait for other cores' data cache activation */
|
||||
data_cache_enabled.wait_for(NR_OF_CPUS);
|
||||
|
||||
if (primary) {
|
||||
Board::L2_cache l2_cache(board.core_mmio.virt_addr(Board::PL310_MMIO_BASE));
|
||||
l2_cache.enable();
|
||||
}
|
||||
|
||||
/* secondary cpus wait for the primary's coherency activation */
|
||||
if (!primary) smp_coherency_enabled.wait_for(1);
|
||||
|
||||
Cpu::Actlr::enable_smp(board);
|
||||
smp_coherency_enabled.inc();
|
||||
|
||||
/*
|
||||
* strangely, some older versions (imx6) seem to not work cache coherent
|
||||
* until SMP bit is set, so write back the variable here.
|
||||
*/
|
||||
cpu.clean_invalidate_inner_data_cache();
|
||||
|
||||
/* wait for other cores' coherency activation */
|
||||
smp_coherency_enabled.wait_for(NR_OF_CPUS);
|
||||
}
|
48
repos/base-hw/src/bootstrap/spec/exynos5/platform.cc
Normal file
48
repos/base-hw/src/bootstrap/spec/exynos5/platform.cc
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* \brief Parts of platform that are specific to Arndale
|
||||
* \author Martin Stein
|
||||
* \date 2012-04-27
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 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.
|
||||
*/
|
||||
|
||||
#include <platform.h>
|
||||
|
||||
/* entrypoint for non-boot CPUs */
|
||||
extern "C" void * _start_setup_stack;
|
||||
|
||||
Platform::Board::Board()
|
||||
: early_ram_regions(Memory_region { RAM_0_BASE, RAM_0_SIZE }),
|
||||
core_mmio(Memory_region { IRQ_CONTROLLER_BASE, IRQ_CONTROLLER_SIZE },
|
||||
Memory_region { IRQ_CONTROLLER_VT_CTRL_BASE, IRQ_CONTROLLER_VT_CTRL_SIZE },
|
||||
Memory_region { MCT_MMIO_BASE, MCT_MMIO_SIZE },
|
||||
Memory_region { UART_2_MMIO_BASE, UART_2_MMIO_SIZE }) { }
|
||||
|
||||
|
||||
void Platform::enable_mmu()
|
||||
{
|
||||
using Genode::Cpu;
|
||||
|
||||
static volatile bool primary_cpu = true;
|
||||
pic.init_cpu_local();
|
||||
|
||||
cpu.init(*reinterpret_cast<Genode::Translation_table*>(core_pd->table_base));
|
||||
|
||||
Cpu::Sctlr::init();
|
||||
Cpu::Psr::write(Cpu::Psr::init_kernel());
|
||||
|
||||
cpu.invalidate_inner_data_cache();
|
||||
|
||||
/* primary cpu wakes up all others */
|
||||
if (primary_cpu && NR_OF_CPUS > 1) {
|
||||
primary_cpu = false;
|
||||
board.wake_up_all_cpus(&_start_setup_stack);
|
||||
}
|
||||
|
||||
cpu.enable_mmu_and_caches((Genode::addr_t)core_pd->table_base);
|
||||
}
|
25
repos/base-hw/src/bootstrap/spec/imx53/board.cc
Normal file
25
repos/base-hw/src/bootstrap/spec/imx53/board.cc
Normal file
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* \brief Specific bootstrap implementations
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2017-01-27
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2017 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.
|
||||
*/
|
||||
|
||||
#include <platform.h>
|
||||
#include <board.h>
|
||||
|
||||
using Genode::Memory_region;
|
||||
|
||||
Platform::Board::Board()
|
||||
: early_ram_regions(Memory_region { RAM0_BASE, RAM0_SIZE },
|
||||
Memory_region { RAM1_BASE, RAM1_SIZE }),
|
||||
core_mmio(Memory_region { UART_1_MMIO_BASE, UART_1_MMIO_SIZE },
|
||||
Memory_region { EPIT_1_MMIO_BASE, EPIT_1_MMIO_SIZE },
|
||||
Memory_region { IRQ_CONTROLLER_BASE, IRQ_CONTROLLER_SIZE }) {
|
||||
init(); }
|
27
repos/base-hw/src/bootstrap/spec/imx53/board_trustzone.cc
Normal file
27
repos/base-hw/src/bootstrap/spec/imx53/board_trustzone.cc
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* \brief Specific core implementations
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2017-01-27
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2017 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.
|
||||
*/
|
||||
|
||||
/* core includes */
|
||||
#include <platform.h>
|
||||
#include <drivers/trustzone.h>
|
||||
|
||||
using Genode::Memory_region;
|
||||
|
||||
Platform::Board::Board()
|
||||
: early_ram_regions(Memory_region { Trustzone::SECURE_RAM_BASE,
|
||||
Trustzone::SECURE_RAM_SIZE }),
|
||||
core_mmio(Memory_region { UART_1_MMIO_BASE, UART_1_MMIO_SIZE },
|
||||
Memory_region { EPIT_1_MMIO_BASE, EPIT_1_MMIO_SIZE },
|
||||
Memory_region { IRQ_CONTROLLER_BASE, IRQ_CONTROLLER_SIZE },
|
||||
Memory_region { CSU_BASE, CSU_SIZE }) {
|
||||
init(); }
|
28
repos/base-hw/src/bootstrap/spec/imx53/platform.cc
Normal file
28
repos/base-hw/src/bootstrap/spec/imx53/platform.cc
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* \brief Specific i.MX53 bootstrap implementations
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2012-10-24
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012-2017 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.
|
||||
*/
|
||||
|
||||
/* core includes */
|
||||
#include <platform.h>
|
||||
#include <cpu.h>
|
||||
|
||||
|
||||
void Platform::enable_mmu()
|
||||
{
|
||||
Genode::Cpu::Sctlr::init();
|
||||
|
||||
cpu.enable_mmu_and_caches((addr_t)core_pd->table_base);
|
||||
}
|
||||
|
||||
|
||||
void Genode::Cpu::translation_added(Genode::addr_t const addr,
|
||||
Genode::size_t const size) { }
|
44
repos/base-hw/src/bootstrap/spec/imx6/platform.cc
Normal file
44
repos/base-hw/src/bootstrap/spec/imx6/platform.cc
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* \brief Specific bootstrap implementations
|
||||
* \author Stefan Kalkowski
|
||||
* \author Josef Soentgen
|
||||
* \author Martin Stein
|
||||
* \date 2014-02-25
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2014-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.
|
||||
*/
|
||||
|
||||
/* core includes */
|
||||
#include <platform.h>
|
||||
#include <cpu.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
Platform::Board::Board()
|
||||
: early_ram_regions(Memory_region { RAM0_BASE, RAM0_SIZE }),
|
||||
core_mmio(Memory_region { UART_1_MMIO_BASE,
|
||||
UART_1_MMIO_SIZE },
|
||||
Memory_region { CORTEX_A9_PRIVATE_MEM_BASE,
|
||||
CORTEX_A9_PRIVATE_MEM_SIZE },
|
||||
Memory_region { PL310_MMIO_BASE,
|
||||
PL310_MMIO_SIZE }) { init(); }
|
||||
|
||||
|
||||
bool Cortex_a9::Board::errata(Cortex_a9::Board::Errata err)
|
||||
{
|
||||
switch (err) {
|
||||
case Cortex_a9::Board::ARM_754322:
|
||||
case Cortex_a9::Board::ARM_764369:
|
||||
case Cortex_a9::Board::ARM_775420:
|
||||
case Cortex_a9::Board::PL310_588369:
|
||||
case Cortex_a9::Board::PL310_727915:
|
||||
case Cortex_a9::Board::PL310_769419:
|
||||
return true;
|
||||
};
|
||||
return false;
|
||||
}
|
16
repos/base-hw/src/bootstrap/spec/odroid_xu/cpu.cc
Normal file
16
repos/base-hw/src/bootstrap/spec/odroid_xu/cpu.cc
Normal file
@ -0,0 +1,16 @@
|
||||
/*
|
||||
* \brief Cpu-specific code for Cortex A15
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2016-01-07
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <cpu.h>
|
||||
|
||||
void Genode::Cpu::init(Genode::Translation_table&) {}
|
51
repos/base-hw/src/bootstrap/spec/panda/platform.cc
Normal file
51
repos/base-hw/src/bootstrap/spec/panda/platform.cc
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* \brief Parts of platform that are specific to Pandaboard
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2017-01-30
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2017 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.
|
||||
*/
|
||||
|
||||
#include <platform.h>
|
||||
#include <cortex_a9_wugen.h>
|
||||
|
||||
Platform::Board::Board()
|
||||
: early_ram_regions(Memory_region { RAM_0_BASE, RAM_0_SIZE }),
|
||||
core_mmio(Memory_region { CORTEX_A9_PRIVATE_MEM_BASE,
|
||||
CORTEX_A9_PRIVATE_MEM_SIZE },
|
||||
Memory_region { TL16C750_3_MMIO_BASE,
|
||||
TL16C750_MMIO_SIZE },
|
||||
Memory_region { PL310_MMIO_BASE,
|
||||
PL310_MMIO_SIZE }) { }
|
||||
|
||||
|
||||
void Cortex_a9::Board::wake_up_all_cpus(void * const ip)
|
||||
{
|
||||
Genode::Cortex_a9_wugen wugen;
|
||||
wugen.init_cpu_1(ip);
|
||||
asm volatile("dsb\n"
|
||||
"sev\n");
|
||||
}
|
||||
|
||||
|
||||
bool Cortex_a9::Board::errata(Cortex_a9::Board::Errata err)
|
||||
{
|
||||
switch (err) {
|
||||
case Cortex_a9::Board::PL310_588369:
|
||||
case Cortex_a9::Board::PL310_727915: return true;
|
||||
default: ;
|
||||
};
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void Genode::Cpu::Actlr::enable_smp(Genode::Board & board)
|
||||
{
|
||||
Board::Secure_monitor monitor;
|
||||
monitor.call(Board::Secure_monitor::CPU_ACTLR_SMP_BIT_RAISE, 0);
|
||||
}
|
52
repos/base-hw/src/bootstrap/spec/pbxa9/platform.cc
Normal file
52
repos/base-hw/src/bootstrap/spec/pbxa9/platform.cc
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* \brief Pbxa9 specific platform implementation
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2016-10-20
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* bootstrap includes */
|
||||
#include <platform.h>
|
||||
|
||||
Platform::Board::Board()
|
||||
: early_ram_regions(Memory_region { RAM_0_BASE, RAM_0_SIZE },
|
||||
Memory_region { RAM_1_BASE, RAM_1_SIZE }),
|
||||
core_mmio(Memory_region { Board::CORTEX_A9_PRIVATE_MEM_BASE,
|
||||
Board::CORTEX_A9_PRIVATE_MEM_SIZE },
|
||||
Memory_region { Board::PL011_0_MMIO_BASE,
|
||||
Board::PL011_0_MMIO_SIZE },
|
||||
Memory_region { Board::PL310_MMIO_BASE,
|
||||
Board::PL310_MMIO_SIZE }) { }
|
||||
|
||||
|
||||
bool Cortex_a9::Board::errata(Cortex_a9::Board::Errata err) {
|
||||
return false; }
|
||||
|
||||
|
||||
void Cortex_a9::Board::wake_up_all_cpus(void * const ip)
|
||||
{
|
||||
/**
|
||||
* set the entrypoint for the other CPUs via the flags register
|
||||
* of the system control registers. ARMs boot monitor code will
|
||||
* read out this register and jump to it after the cpu received
|
||||
* an interrupt
|
||||
*/
|
||||
struct System_control : Genode::Mmio
|
||||
{
|
||||
struct Flagsset : Register<0x30, 32> { };
|
||||
struct Flagsclr : Register<0x34, 32> { };
|
||||
|
||||
System_control(void * const ip)
|
||||
: Mmio(SYSTEM_CONTROL_MMIO_BASE)
|
||||
{
|
||||
write<Flagsclr>(~0UL);
|
||||
write<Flagsset>(reinterpret_cast<Flagsset::access_t>(ip));
|
||||
}
|
||||
} sc(ip);
|
||||
}
|
19
repos/base-hw/src/bootstrap/spec/riscv/cpu.cc
Normal file
19
repos/base-hw/src/bootstrap/spec/riscv/cpu.cc
Normal file
@ -0,0 +1,19 @@
|
||||
/*
|
||||
* \brief CPU core implementation
|
||||
* \author Sebastian Sumpf
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2016-02-10
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* core includes */
|
||||
#include <cpu.h>
|
||||
|
||||
void Genode::Cpu::translation_added(addr_t const addr, size_t const size) {
|
||||
Genode::Cpu::sfence(); }
|
51
repos/base-hw/src/bootstrap/spec/riscv/crt0.s
Normal file
51
repos/base-hw/src/bootstrap/spec/riscv/crt0.s
Normal file
@ -0,0 +1,51 @@
|
||||
/**
|
||||
* \brief Kernel startup code
|
||||
* \author Sebastian Sumpf
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2015-06-010
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2015-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.
|
||||
*/
|
||||
|
||||
.set STACK_SIZE, 64 * 1024
|
||||
|
||||
.section ".text.crt0"
|
||||
|
||||
.global _start
|
||||
_start:
|
||||
j _start_next_page
|
||||
|
||||
/* leave first page empty for mode-transition page located at 0x100 */
|
||||
.space 4096
|
||||
|
||||
_start_next_page:
|
||||
|
||||
/* clear the bss segment */
|
||||
la a0, _bss_start
|
||||
la a1, _bss_end
|
||||
1:
|
||||
sd x0, (a0)
|
||||
addi a0, a0, 8
|
||||
bne a0, a1, 1b
|
||||
|
||||
la sp, _stack_area_start
|
||||
la a0, STACK_SIZE
|
||||
ld a0, (a0)
|
||||
add sp, sp, a0
|
||||
|
||||
/* save kernel stack pointer in mscratch */
|
||||
csrw mscratch, sp
|
||||
|
||||
jal setup_riscv_exception_vector
|
||||
jal init
|
||||
|
||||
1: j 1b
|
||||
|
||||
.align 3
|
||||
_stack_area_start:
|
||||
.space STACK_SIZE
|
30
repos/base-hw/src/bootstrap/spec/riscv/exception_vector.cc
Normal file
30
repos/base-hw/src/bootstrap/spec/riscv/exception_vector.cc
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* \brief Exception vector initialization
|
||||
* \author Sebastian Sumpf
|
||||
* \date 2015-07-12
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2015-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.
|
||||
*/
|
||||
|
||||
/* Core includes */
|
||||
#include <kernel/cpu.h>
|
||||
|
||||
extern int _machine_begin, _machine_end;
|
||||
|
||||
extern "C" void setup_riscv_exception_vector()
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
/* retrieve exception vector */
|
||||
addr_t vector;
|
||||
asm volatile ("csrr %0, mtvec\n" : "=r"(vector));
|
||||
|
||||
/* copy machine mode exception vector */
|
||||
memcpy((void *)vector,
|
||||
&_machine_begin, (addr_t)&_machine_end - (addr_t)&_machine_begin);
|
||||
}
|
59
repos/base-hw/src/bootstrap/spec/riscv/platform.cc
Normal file
59
repos/base-hw/src/bootstrap/spec/riscv/platform.cc
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* \brief Platform implementations specific for RISC-V
|
||||
* \author Stefan Kalkowski
|
||||
* \author Sebastian Sumpf
|
||||
* \date 2016-11-23
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <platform.h>
|
||||
|
||||
Platform::Board::Board()
|
||||
: early_ram_regions(Genode::Memory_region { 0, 128 * 1024 * 1024 } ) {}
|
||||
|
||||
|
||||
struct Mstatus : Genode::Register<64>
|
||||
{
|
||||
enum {
|
||||
USER = 0,
|
||||
SUPERVISOR = 1,
|
||||
Sv39 = 9,
|
||||
};
|
||||
struct Ie : Bitfield<0, 1> { };
|
||||
struct Priv : Bitfield<1, 2> { };
|
||||
struct Ie1 : Bitfield<3, 1> { };
|
||||
struct Priv1 : Bitfield<4, 2> { };
|
||||
struct Fs : Bitfield<12, 2> { enum { INITIAL = 1 }; };
|
||||
struct Vm : Bitfield<17, 5> { };
|
||||
};
|
||||
|
||||
|
||||
void Platform::enable_mmu()
|
||||
{
|
||||
using Genode::Cpu;
|
||||
|
||||
/* read status register */
|
||||
Mstatus::access_t mstatus = 0;
|
||||
|
||||
Mstatus::Vm::set(mstatus, Mstatus::Sv39); /* enable Sv39 paging */
|
||||
Mstatus::Fs::set(mstatus, Mstatus::Fs::INITIAL); /* enable FPU */
|
||||
Mstatus::Ie1::set(mstatus, 1); /* user mode interrupt */
|
||||
Mstatus::Priv1::set(mstatus, Mstatus::USER); /* set user mode */
|
||||
Mstatus::Ie::set(mstatus, 0); /* disable interrupts */
|
||||
Mstatus::Priv::set(mstatus, Mstatus::SUPERVISOR); /* set supervisor mode */
|
||||
|
||||
asm volatile ("csrw sasid, %0\n" /* address space id */
|
||||
"csrw sptbr, %1\n" /* set page table */
|
||||
"csrw mstatus, %2\n" /* change mode */
|
||||
:
|
||||
: "r" (0/*core_pd.asid*/),
|
||||
"r" (core_pd->table_base),
|
||||
"r" (mstatus)
|
||||
: "memory");
|
||||
}
|
46
repos/base-hw/src/bootstrap/spec/rpi/platform.cc
Normal file
46
repos/base-hw/src/bootstrap/spec/rpi/platform.cc
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* \brief Platform implementations specific for base-hw and Raspberry Pi
|
||||
* \author Norman Feske
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2013-04-05
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2013-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.
|
||||
*/
|
||||
|
||||
#include <platform.h>
|
||||
|
||||
using Genode::Memory_region;
|
||||
|
||||
/**
|
||||
* Leave out the first page (being 0x0) from bootstraps RAM allocator,
|
||||
* some code does not feel happy with addresses being zero
|
||||
*/
|
||||
Platform::Board::Board()
|
||||
: early_ram_regions(Memory_region { RAM_0_BASE + 0x1000,
|
||||
RAM_0_SIZE - 0x1000 }),
|
||||
late_ram_regions(Memory_region { RAM_0_BASE, 0x1000 }),
|
||||
core_mmio(Memory_region { PL011_0_MMIO_BASE,
|
||||
PL011_0_MMIO_SIZE },
|
||||
Memory_region { SYSTEM_TIMER_MMIO_BASE,
|
||||
SYSTEM_TIMER_MMIO_SIZE },
|
||||
Memory_region { IRQ_CONTROLLER_BASE,
|
||||
IRQ_CONTROLLER_SIZE },
|
||||
Memory_region { USB_DWC_OTG_BASE,
|
||||
USB_DWC_OTG_SIZE }) {}
|
||||
|
||||
|
||||
void Platform::enable_mmu()
|
||||
{
|
||||
Genode::Cpu::Sctlr::init();
|
||||
Genode::Cpu::Psr::write(Genode::Cpu::Psr::init_kernel());
|
||||
|
||||
/* check for mapping restrictions */
|
||||
assert(!Genode::Cpu::restricted_page_mappings());
|
||||
|
||||
cpu.enable_mmu_and_caches((addr_t)core_pd->table_base);
|
||||
}
|
118
repos/base-hw/src/bootstrap/spec/x86_64/crt0.s
Normal file
118
repos/base-hw/src/bootstrap/spec/x86_64/crt0.s
Normal file
@ -0,0 +1,118 @@
|
||||
/*
|
||||
* \brief Startup code for kernel
|
||||
* \author Adrian-Ken Rueegsegger
|
||||
* \author Martin Stein
|
||||
* \author Reto Buerki
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2015-02-06
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2011-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.
|
||||
*/
|
||||
|
||||
.include "macros.s"
|
||||
|
||||
.section ".text.crt0"
|
||||
|
||||
/* magic multi-boot header to make GRUB happy */
|
||||
.long 0x1badb002
|
||||
.long 0x0
|
||||
.long 0xe4524ffe
|
||||
|
||||
/**********************************
|
||||
** Startup code for primary CPU **
|
||||
**********************************/
|
||||
|
||||
.code32
|
||||
.global _start
|
||||
_start:
|
||||
|
||||
/**
|
||||
* zero-fill BSS segment
|
||||
*/
|
||||
leal _bss_start, %edi
|
||||
leal _bss_end, %ecx
|
||||
sub %edi, %ecx
|
||||
shr $2, %ecx
|
||||
xor %eax, %eax
|
||||
rep stosl
|
||||
|
||||
/* Enable PAE (prerequisite for IA-32e mode) */
|
||||
movl %cr4, %eax
|
||||
btsl $5, %eax
|
||||
movl %eax, %cr4
|
||||
|
||||
/* Load initial pagetables */
|
||||
leal _kernel_pml4, %eax
|
||||
mov %eax, %cr3
|
||||
|
||||
/* Enable IA-32e mode and execute-disable */
|
||||
movl $0xc0000080, %ecx
|
||||
rdmsr
|
||||
btsl $8, %eax
|
||||
btsl $11, %eax
|
||||
wrmsr
|
||||
|
||||
/* Enable paging, write protection and caching */
|
||||
movl %cr0, %eax
|
||||
btsl $16, %eax
|
||||
btrl $29, %eax
|
||||
btrl $30, %eax
|
||||
btsl $31, %eax
|
||||
movl %eax, %cr0
|
||||
|
||||
/* Set up GDT */
|
||||
lgdt _mt_gdt_ptr
|
||||
|
||||
/* Indirect long jump to 64-bit code */
|
||||
ljmp $8, $_start64
|
||||
|
||||
.code64
|
||||
_start64:
|
||||
|
||||
/*
|
||||
* Set up kernel segment selectors
|
||||
*/
|
||||
mov $0x10, %eax
|
||||
mov %eax, %ss
|
||||
mov %eax, %ds
|
||||
mov %eax, %es
|
||||
mov %eax, %fs
|
||||
mov %eax, %gs
|
||||
|
||||
/*
|
||||
* Install initial temporary environment that is replaced later by the
|
||||
* environment that init_main_thread creates.
|
||||
*/
|
||||
leaq _stack_high@GOTPCREL(%rip),%rax
|
||||
movq (%rax), %rsp
|
||||
|
||||
movq __initial_bx@GOTPCREL(%rip),%rax
|
||||
movq %rbx, (%rax)
|
||||
|
||||
/* kernel-initialization */
|
||||
call init
|
||||
|
||||
/* catch erroneous return of the kernel initialization */
|
||||
1: jmp 1b
|
||||
|
||||
_define_gdt 0
|
||||
|
||||
|
||||
/*********************************
|
||||
** .bss (non-initialized data) **
|
||||
*********************************/
|
||||
|
||||
.bss
|
||||
|
||||
/* stack of the temporary initial environment */
|
||||
.p2align 8
|
||||
.space 32 * 1024
|
||||
_stack_high:
|
||||
.globl __initial_bx
|
||||
__initial_bx:
|
||||
.space 8
|
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* \brief Initial pagetables for x86_64
|
||||
* \author Adrian-Ken Rueegsegger
|
||||
* \author Reto Buerki
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2015-04-22
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2015-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.
|
||||
*/
|
||||
|
||||
.include "macros.s"
|
||||
|
||||
.data
|
||||
|
||||
/********************************************
|
||||
** Identity mapping from 4KiB to 1GiB **
|
||||
** plus mappings for LAPIC, I/O APIC MMIO **
|
||||
** Page 0 containing the Bios Data Area **
|
||||
** gets mapped to 2MiB - 4KiB readonly. **
|
||||
********************************************/
|
||||
|
||||
/* PML4 */
|
||||
.p2align MIN_PAGE_SIZE_LOG2
|
||||
.global _kernel_pml4
|
||||
_kernel_pml4:
|
||||
.quad _kernel_pdp + 0xf
|
||||
.fill 511, 8, 0x0
|
||||
|
||||
/* PDP */
|
||||
.p2align MIN_PAGE_SIZE_LOG2
|
||||
_kernel_pdp:
|
||||
.quad _kernel_pd + 0xf
|
||||
.fill 2, 8, 0x0
|
||||
.quad _kernel_pd_503 + 0xf
|
||||
.fill 508, 8, 0x0
|
||||
|
||||
/* PD */
|
||||
.p2align MIN_PAGE_SIZE_LOG2
|
||||
_kernel_pd:
|
||||
.quad _kernel_pt_bda + 0xf
|
||||
.set entry, 0x20018f
|
||||
.rept 511
|
||||
.quad entry
|
||||
.set entry, entry + 0x200000
|
||||
.endr
|
||||
|
||||
.p2align MIN_PAGE_SIZE_LOG2
|
||||
_kernel_pd_503:
|
||||
.fill 502, 8, 0x0
|
||||
.quad 0xfec0019f
|
||||
.quad 0xfee0019f
|
||||
.fill 8, 8, 0x0
|
||||
|
||||
.p2align MIN_PAGE_SIZE_LOG2
|
||||
_kernel_pt_bda:
|
||||
.fill 1, 8, 0x0
|
||||
.set entry, 0x118f
|
||||
.rept 510
|
||||
.quad entry
|
||||
.set entry, entry + 0x1000
|
||||
.endr
|
||||
.quad 0x000001
|
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* \brief Initial pagetables for x86_64_muen
|
||||
* \author Adrian-Ken Rueegsegger
|
||||
* \author Reto Buerki
|
||||
* \date 2015-04-22
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
.include "macros.s"
|
||||
|
||||
.data
|
||||
|
||||
/*****************************************
|
||||
** Identity mapping from 2MiB to 1GiB **
|
||||
** plus mappings for Muen pvirt pages **
|
||||
*****************************************/
|
||||
|
||||
/* PML4 */
|
||||
.p2align MIN_PAGE_SIZE_LOG2
|
||||
.global _kernel_pml4
|
||||
_kernel_pml4:
|
||||
.quad _kernel_pdp + 0xf
|
||||
.fill 511, 8, 0x0
|
||||
|
||||
/* PDP */
|
||||
.p2align MIN_PAGE_SIZE_LOG2
|
||||
_kernel_pdp:
|
||||
.quad _kernel_pd + 0xf
|
||||
.fill 55, 8, 0x0
|
||||
.quad _kernel_pd_pvirt + 0xf
|
||||
.fill 455, 8, 0x0
|
||||
|
||||
/* PD */
|
||||
.p2align MIN_PAGE_SIZE_LOG2
|
||||
_kernel_pd:
|
||||
.quad 0
|
||||
.set entry, 0x20018f
|
||||
.rept 511
|
||||
.quad entry
|
||||
.set entry, entry + 0x200000
|
||||
.endr
|
||||
|
||||
.p2align MIN_PAGE_SIZE_LOG2
|
||||
_kernel_pd_pvirt:
|
||||
.quad 0xe0000018f
|
||||
.fill 511, 8, 0x0
|
75
repos/base-hw/src/bootstrap/spec/x86_64/platform.cc
Normal file
75
repos/base-hw/src/bootstrap/spec/x86_64/platform.cc
Normal file
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* \brief Platform implementations specific for x86_64
|
||||
* \author Reto Buerki
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2015-05-04
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2015-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.
|
||||
*/
|
||||
|
||||
/* core includes */
|
||||
#include <bios_data_area.h>
|
||||
#include <cpu.h>
|
||||
#include <platform.h>
|
||||
#include <multiboot.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
/* contains physical pointer to multiboot */
|
||||
extern "C" Genode::addr_t __initial_bx;
|
||||
|
||||
Platform::Board::Board()
|
||||
: core_mmio(Memory_region { 0, 0x1000 },
|
||||
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() })
|
||||
{
|
||||
using Mmap = Multiboot_info::Mmap;
|
||||
static constexpr size_t initial_map_max = 1024 * 1024 * 1024;
|
||||
|
||||
for (unsigned i = 0; true; i++) {
|
||||
Mmap v = Multiboot_info(__initial_bx).phys_ram(i);
|
||||
if (!v.base) break;
|
||||
|
||||
Mmap::Addr::access_t base = v.read<Mmap::Addr>();
|
||||
Mmap::Length::access_t size = v.read<Mmap::Length>();
|
||||
|
||||
/*
|
||||
* Exclude first physical page, so that it will become part of the
|
||||
* MMIO allocator. The framebuffer requests this page as MMIO.
|
||||
*/
|
||||
if (base == 0 && size >= get_page_size()) {
|
||||
base = get_page_size();
|
||||
size -= get_page_size();
|
||||
}
|
||||
|
||||
if (base >= initial_map_max) {
|
||||
late_ram_regions.add(Memory_region { base, size });
|
||||
continue;
|
||||
}
|
||||
|
||||
if (base + size <= initial_map_max) {
|
||||
early_ram_regions.add(Memory_region { base, size });
|
||||
continue;
|
||||
}
|
||||
|
||||
size_t low_size = initial_map_max - base;
|
||||
early_ram_regions.add(Memory_region { base, low_size });
|
||||
late_ram_regions.add(Memory_region { initial_map_max, size - low_size });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Platform::enable_mmu() {
|
||||
Cpu::Cr3::write(Cpu::Cr3::init((addr_t)core_pd->table_base)); }
|
||||
|
||||
|
||||
addr_t Bios_data_area::_mmio_base_virt() { return 0x1ff000; }
|
39
repos/base-hw/src/bootstrap/spec/x86_64/platform_muen.cc
Normal file
39
repos/base-hw/src/bootstrap/spec/x86_64/platform_muen.cc
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* \brief Platform implementations specific for x86_64
|
||||
* \author Reto Buerki
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2015-05-04
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2015-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.
|
||||
*/
|
||||
|
||||
/* core includes */
|
||||
#include <cpu.h>
|
||||
#include <platform.h>
|
||||
#include <muen/sinfo.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
Platform::Board::Board()
|
||||
: core_mmio(Memory_region { Sinfo::PHYSICAL_BASE_ADDR, Sinfo::SIZE },
|
||||
Memory_region { TIMER_BASE_ADDR, TIMER_SIZE },
|
||||
Memory_region { TIMER_PREEMPT_BASE_ADDR, TIMER_PREEMPT_SIZE })
|
||||
{
|
||||
struct Sinfo::Memregion_info region;
|
||||
|
||||
Sinfo sinfo(Sinfo::PHYSICAL_BASE_ADDR);
|
||||
if (!sinfo.get_memregion_info("ram", ®ion))
|
||||
error("Unable to retrieve base-hw ram region");
|
||||
else
|
||||
early_ram_regions.add(Memory_region { region.address, region.size });
|
||||
}
|
||||
|
||||
|
||||
void Platform::enable_mmu() {
|
||||
Cpu::Cr3::write(Cpu::Cr3::init((addr_t)core_pd->table_base)); }
|
32
repos/base-hw/src/bootstrap/spec/zynq/platform.cc
Normal file
32
repos/base-hw/src/bootstrap/spec/zynq/platform.cc
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* \brief Platform implementations specific for base-hw and Zynq
|
||||
* \author Johannes Schlatow
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2014-12-15
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2014-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.
|
||||
*/
|
||||
|
||||
/* core includes */
|
||||
#include <platform.h>
|
||||
|
||||
|
||||
Platform::Board::Board()
|
||||
: early_ram_regions(Memory_region { RAM_0_BASE + 0x1000,
|
||||
RAM_0_SIZE - 0x1000 }),
|
||||
late_ram_regions(Memory_region { RAM_0_BASE, 0x1000 }),
|
||||
core_mmio(Memory_region { CORTEX_A9_PRIVATE_MEM_BASE,
|
||||
CORTEX_A9_PRIVATE_MEM_SIZE },
|
||||
Memory_region { KERNEL_UART_BASE,
|
||||
KERNEL_UART_SIZE },
|
||||
Memory_region { PL310_MMIO_BASE,
|
||||
PL310_MMIO_SIZE }) { }
|
||||
|
||||
|
||||
bool Cortex_a9::Board::errata(Cortex_a9::Board::Errata err) {
|
||||
return false; }
|
28
repos/base-hw/src/bootstrap/thread.cc
Normal file
28
repos/base-hw/src/bootstrap/thread.cc
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* \brief Thread implementation needed by cxx library
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2016-10-19
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* base includes */
|
||||
#include <base/thread.h>
|
||||
|
||||
/* local includes */
|
||||
#include <assert.h>
|
||||
|
||||
|
||||
Genode::Thread * Genode::Thread::myself()
|
||||
{
|
||||
assert(false);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
Genode::Thread::Name Genode::Thread::name() const { return "bootstrap"; }
|
Reference in New Issue
Block a user