mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-18 21:27:56 +00:00
parent
6afe4f79a2
commit
9258004cc7
@ -30,3 +30,5 @@ vpath bootstrap/% $(BASE_HW_DIR)/src
|
||||
vpath hw/% $(BASE_HW_DIR)/src/lib
|
||||
vpath lib/base/% $(BASE_HW_DIR)/src
|
||||
vpath lib/base/% $(BASE_DIR)/src
|
||||
|
||||
include $(call select_from_repositories,lib/mk/consts-hw.inc)
|
||||
|
13
repos/base-hw/lib/mk/consts-hw.inc
Normal file
13
repos/base-hw/lib/mk/consts-hw.inc
Normal file
@ -0,0 +1,13 @@
|
||||
REP_INC_DIR += src/lib/hw/$(ARCH_WIDTH_PATH)
|
||||
|
||||
SRC_CC += $(ARCH_WIDTH_PATH)/memory_map.cc
|
||||
|
||||
hw/memory_consts.h: $(call select_from_repositories,src/lib/hw/$(ARCH_WIDTH_PATH))/memory_consts.s $(MAKEFILE_LIST)
|
||||
$(MSG_CONVERT)$@
|
||||
$(VERBOSE)mkdir -p $(dir $@)
|
||||
$(VERBOSE)sed -e 's/^HW_MM_\([0-9A-Z_]*\)\s*=\s*\(.*\)/ static constexpr Genode::size_t \1 = \2;/' -e 's/^#//' $< > $@
|
||||
|
||||
$(SRC_CC:.cc=.o) $(SRC_S:.s=.o): hw/memory_consts.h
|
||||
|
||||
vpath hw/memory_consts.h $(LIB_CACHE_DIR)/$(LIB)
|
||||
vpath $(ARCH_WIDTH_PATH)/memory_map.cc $(call select_from_repositories,src/lib/hw)
|
@ -72,3 +72,5 @@ BASE_HW_DIR := $(TMP:%/lib/mk/core-hw.inc=%)
|
||||
vpath % $(BASE_HW_DIR)/src/core
|
||||
vpath % $(BASE_DIR)/src/core
|
||||
vpath % $(BASE_DIR)/src/lib/startup
|
||||
|
||||
include $(call select_from_repositories,lib/mk/consts-hw.inc)
|
||||
|
@ -10,7 +10,6 @@ REP_INC_DIR += src/core/spec/arm
|
||||
LIBS += syscall-hw
|
||||
|
||||
# add C++ sources
|
||||
SRC_CC += spec/32bit/memory_map.cc
|
||||
SRC_CC += spec/arm/kernel/cpu.cc
|
||||
SRC_CC += spec/arm/kernel/pd.cc
|
||||
SRC_CC += spec/arm/cpu.cc
|
||||
@ -22,7 +21,7 @@ SRC_CC += spec/arm/platform_support.cc
|
||||
SRC_S += spec/arm/crt0.s
|
||||
SRC_S += spec/arm/exception_vector.S
|
||||
|
||||
vpath spec/32bit/memory_map.cc $(call select_from_repositories,src/lib/hw)
|
||||
ARCH_WIDTH_PATH := spec/32bit
|
||||
|
||||
# include less specific configuration
|
||||
include $(call select_from_repositories,lib/mk/core-hw.inc)
|
||||
|
@ -1,5 +1,5 @@
|
||||
SRC_CC += bootstrap/platform_cpu_memory_area.cc
|
||||
SRC_CC += bootstrap/spec/arm/arm_v7_cpu.cc
|
||||
SRC_CC += hw/spec/32bit/memory_map.cc
|
||||
SRC_S += bootstrap/spec/arm/crt0.s
|
||||
|
||||
#
|
||||
@ -8,4 +8,6 @@ SRC_S += bootstrap/spec/arm/crt0.s
|
||||
#
|
||||
CC_MARCH = -march=armv7-a+nofp -mfpu=vfpv3
|
||||
|
||||
ARCH_WIDTH_PATH := spec/32bit
|
||||
|
||||
include $(call select_from_repositories,lib/mk/bootstrap-hw.inc)
|
||||
|
@ -1,9 +1,9 @@
|
||||
CC_MARCH = -march=armv8-a -mstrict-align
|
||||
|
||||
SRC_CC += bootstrap/platform_cpu_memory_area.cc
|
||||
SRC_CC += lib/base/arm_64/kernel/interface.cc
|
||||
SRC_CC += spec/64bit/memory_map.cc
|
||||
SRC_S += bootstrap/spec/arm_64/crt0.s
|
||||
|
||||
vpath spec/64bit/memory_map.cc $(call select_from_repositories,src/lib/hw)
|
||||
ARCH_WIDTH_PATH := spec/64bit
|
||||
|
||||
include $(call select_from_repositories,lib/mk/bootstrap-hw.inc)
|
||||
|
@ -9,7 +9,6 @@ LIBS += syscall-hw
|
||||
|
||||
# add C++ sources
|
||||
SRC_CC += kernel/cpu_mp.cc
|
||||
SRC_CC += spec/64bit/memory_map.cc
|
||||
SRC_CC += spec/arm/generic_timer.cc
|
||||
SRC_CC += spec/arm/kernel/lock.cc
|
||||
SRC_CC += spec/arm/kernel/thread_caches.cc
|
||||
@ -26,7 +25,8 @@ PD_SESSION_SUPPORT_CC_PATH := \
|
||||
$(call select_from_repositories,src/core/spec/arm_v8/pd_session_support.cc)
|
||||
|
||||
vpath pd_session_support.cc $(dir $(PD_SESSION_SUPPORT_CC_PATH))
|
||||
vpath spec/64bit/memory_map.cc $(call select_from_repositories,src/lib/hw)
|
||||
|
||||
ARCH_WIDTH_PATH := spec/64bit
|
||||
|
||||
# include less specific configuration
|
||||
include $(call select_from_repositories,lib/mk/core-hw.inc)
|
||||
|
@ -4,6 +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
|
||||
ARCH_WIDTH_PATH := spec/64bit
|
||||
|
||||
include $(call select_from_repositories,lib/mk/bootstrap-hw.inc)
|
||||
|
@ -42,13 +42,12 @@ 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
|
||||
|
||||
PD_SESSION_SUPPORT_CC_PATH := \
|
||||
$(call select_from_repositories,src/core/spec/x86_64/pd_session_support.cc)
|
||||
|
||||
vpath pd_session_support.cc $(dir $(PD_SESSION_SUPPORT_CC_PATH))
|
||||
vpath spec/64bit/memory_map.cc $(call select_from_repositories,src/lib/hw)
|
||||
|
||||
ARCH_WIDTH_PATH := spec/64bit
|
||||
|
||||
# include less specific configuration
|
||||
include $(call select_from_repositories,lib/mk/core-hw.inc)
|
||||
|
@ -107,7 +107,7 @@ SRC_INCLUDE_HW += $(notdir $(wildcard $(BASE_HW_DIR)/src/include/hw/*.h)) \
|
||||
uart
|
||||
|
||||
SRC_BOOTSTRAP += hw env.cc init.cc lock.cc log.cc thread.cc \
|
||||
platform.cc platform.h \
|
||||
platform.cc platform.h platform_cpu_memory_area.cc \
|
||||
$(addprefix spec/,${call selected_content,SRC_BOOTSTRAP_SPECS}) \
|
||||
$(addprefix board/,$(BOARD))
|
||||
|
||||
@ -138,7 +138,7 @@ LIB_MK_FILES := base-common.inc base-hw-common.mk \
|
||||
core-hw.inc core-hw-$(BOARD).inc core-hw-$(BOARD).mk \
|
||||
core-hw-cortex_a9.inc core-hw-cortex_a15.inc \
|
||||
startup.inc startup-hw.mk \
|
||||
timeout-hw.mk cxx.mk ld-hw.mk syscall-hw.mk
|
||||
timeout-hw.mk cxx.mk ld-hw.mk syscall-hw.mk consts-hw.inc
|
||||
|
||||
LIB_MK_DIRS := lib/mk $(addprefix lib/mk/spec/,${call selected_content,LIB_MK_SPECS})
|
||||
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
#include <base/internal/crt0.h>
|
||||
#include <hw/assert.h>
|
||||
#include <hw/memory_consts.h>
|
||||
|
||||
#include <boot_modules.h>
|
||||
#include <platform.h>
|
||||
@ -149,6 +150,36 @@ Mapping Platform::_load_elf()
|
||||
}
|
||||
|
||||
|
||||
void Platform::_prepare_cpu_memory_area(size_t cpu_id)
|
||||
{
|
||||
using namespace Genode;
|
||||
using namespace Hw;
|
||||
using namespace Hw::Mm;
|
||||
|
||||
size_t slots = cpu_local_memory().size / CPU_LOCAL_MEMORY_SLOT_SIZE;
|
||||
|
||||
if (cpu_id >= slots) {
|
||||
error("CPU memory area too small for cpu id ", cpu_id);
|
||||
error("CPU memory area can hold ", slots, " at max");
|
||||
return;
|
||||
}
|
||||
|
||||
Page_flags flags{RW, NO_EXEC, KERN, GLOBAL, RAM, CACHED};
|
||||
|
||||
addr_t base = cpu_local_memory().base + CPU_LOCAL_MEMORY_SLOT_SIZE*cpu_id;
|
||||
void * const stack_ram = ram_alloc.alloc_aligned(KERNEL_STACK_SIZE, 1);
|
||||
void * const cpu_ram =
|
||||
ram_alloc.alloc_aligned(CPU_LOCAL_MEMORY_SLOT_OBJECT_SIZE, 1);
|
||||
|
||||
core_pd->map_insert(Mapping((addr_t)stack_ram,
|
||||
base+CPU_LOCAL_MEMORY_SLOT_STACK_OFFSET,
|
||||
KERNEL_STACK_SIZE, flags));
|
||||
core_pd->map_insert(Mapping((addr_t)cpu_ram,
|
||||
base+CPU_LOCAL_MEMORY_SLOT_OBJECT_OFFSET,
|
||||
CPU_LOCAL_MEMORY_SLOT_OBJECT_SIZE, flags));
|
||||
}
|
||||
|
||||
|
||||
void Platform::start_core(unsigned cpu_id)
|
||||
{
|
||||
typedef void (* Entry)(unsigned) __attribute__((noreturn));
|
||||
@ -185,6 +216,8 @@ Platform::Platform()
|
||||
core_pd->map_insert(Mapping(bootstrap_region.base, bootstrap_region.base,
|
||||
(addr_t)&_bss_end - (addr_t)&_prog_img_beg, Genode::PAGE_FLAGS_KERN_TEXT));
|
||||
|
||||
board.cpus = _prepare_cpu_memory_area();
|
||||
|
||||
/* map memory-mapped I/O for core */
|
||||
board.core_mmio.for_each_mapping([&] (Mapping const & m) {
|
||||
core_pd->map_insert(m); });
|
||||
|
@ -46,8 +46,8 @@ class Bootstrap::Platform
|
||||
Memory_region_array early_ram_regions { };
|
||||
Memory_region_array late_ram_regions { };
|
||||
Mmio_space core_mmio;
|
||||
unsigned cpus { ::Board::NR_OF_CPUS };
|
||||
::Board::Boot_info info { };
|
||||
unsigned cpus { };
|
||||
::Board::Boot_info info { };
|
||||
|
||||
Board();
|
||||
};
|
||||
@ -134,7 +134,9 @@ class Bootstrap::Platform
|
||||
addr_t core_elf_addr;
|
||||
Elf core_elf;
|
||||
|
||||
Mapping _load_elf();
|
||||
Mapping _load_elf();
|
||||
void _prepare_cpu_memory_area(size_t id);
|
||||
unsigned _prepare_cpu_memory_area();
|
||||
|
||||
public:
|
||||
|
||||
|
24
repos/base-hw/src/bootstrap/platform_cpu_memory_area.cc
Normal file
24
repos/base-hw/src/bootstrap/platform_cpu_memory_area.cc
Normal file
@ -0,0 +1,24 @@
|
||||
/*
|
||||
* \brief Platform CPU memory area preparation
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2024-04-25
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2024 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.
|
||||
*/
|
||||
|
||||
#include <platform.h>
|
||||
|
||||
|
||||
unsigned Bootstrap::Platform::_prepare_cpu_memory_area()
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
for (size_t id = 0; id < ::Board::NR_OF_CPUS; id++)
|
||||
_prepare_cpu_memory_area(id);
|
||||
return ::Board::NR_OF_CPUS;
|
||||
}
|
@ -19,6 +19,7 @@
|
||||
#include <multiboot.h>
|
||||
#include <multiboot2.h>
|
||||
|
||||
#include <hw/memory_consts.h>
|
||||
#include <hw/spec/x86_64/acpi.h>
|
||||
#include <hw/spec/x86_64/apic.h>
|
||||
|
||||
@ -65,31 +66,6 @@ static Hw::Acpi_rsdp search_rsdp(addr_t area, addr_t area_size)
|
||||
}
|
||||
|
||||
|
||||
static Genode::uint8_t apic_id()
|
||||
{
|
||||
X86_64_CPUID_REGISTER(Cpuid_1_ebx, 1, ebx,
|
||||
struct Apic_id : Bitfield<24, 8> { };
|
||||
);
|
||||
|
||||
return uint8_t(Cpuid_1_ebx::Apic_id::get(Cpuid_1_ebx::read()));
|
||||
}
|
||||
|
||||
|
||||
unsigned apic_to_cpu_id(Genode::uint8_t apic_id, Genode::uint8_t dense_id)
|
||||
{
|
||||
static Genode::uint8_t cpu_id[256] { };
|
||||
static bool valid [256] { };
|
||||
|
||||
/* if apic_id is valid, return stored cpu_id and ignore new dense_id */
|
||||
if (!valid[apic_id]) {
|
||||
cpu_id[apic_id] = dense_id;
|
||||
valid [apic_id] = true;
|
||||
}
|
||||
|
||||
return cpu_id[apic_id];
|
||||
}
|
||||
|
||||
|
||||
Bootstrap::Platform::Board::Board()
|
||||
:
|
||||
core_mmio(Memory_region { 0, 0x1000 },
|
||||
@ -213,7 +189,8 @@ Bootstrap::Platform::Board::Board()
|
||||
}
|
||||
|
||||
/* remember max supported CPUs and use ACPI to get the actual number */
|
||||
unsigned const max_cpus = cpus;
|
||||
unsigned const max_cpus =
|
||||
Hw::Mm::CPU_LOCAL_MEMORY_AREA_SIZE / Hw::Mm::CPU_LOCAL_MEMORY_SLOT_SIZE;
|
||||
cpus = 0;
|
||||
|
||||
/* scan ACPI tables to find out number of CPUs in this machine */
|
||||
@ -316,12 +293,8 @@ unsigned Bootstrap::Platform::enable_mmu()
|
||||
|
||||
Cpu::Cr3::write(Cpu::Cr3::Pdb::masked((addr_t)core_pd->table_base));
|
||||
|
||||
addr_t const stack_base = reinterpret_cast<addr_t>(&bootstrap_stack);
|
||||
addr_t const this_stack = reinterpret_cast<addr_t>(&stack_base);
|
||||
addr_t const stack_id = (this_stack - stack_base) / bootstrap_stack_size;
|
||||
|
||||
/* determine dense packed cpu_id based on apic_id */
|
||||
auto const cpu_id = apic_to_cpu_id(apic_id(), uint8_t(stack_id));
|
||||
auto const cpu_id =
|
||||
Cpu::Cpuid_1_ebx::Apic_id::get(Cpu::Cpuid_1_ebx::read());
|
||||
|
||||
/* we like to use local APIC */
|
||||
Cpu::IA32_apic_base::access_t lapic_msr = Cpu::IA32_apic_base::read();
|
||||
@ -370,3 +343,13 @@ Board::Serial::Serial(addr_t, size_t, unsigned baudrate)
|
||||
:
|
||||
X86_uart(Bios_data_area::singleton()->serial_port(), 0, baudrate)
|
||||
{ }
|
||||
|
||||
|
||||
unsigned Bootstrap::Platform::_prepare_cpu_memory_area()
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
for (size_t id = 0; id < board.cpus; id++)
|
||||
_prepare_cpu_memory_area(id);
|
||||
return board.cpus;
|
||||
}
|
||||
|
@ -21,7 +21,7 @@
|
||||
|
||||
/* core includes */
|
||||
#include <core_log.h>
|
||||
#include <kernel/cpu.h>
|
||||
#include <hw/memory_map.h>
|
||||
#include <kernel/log.h>
|
||||
|
||||
using namespace Core;
|
||||
@ -41,17 +41,13 @@ void Genode::raw_write_string(char const *str)
|
||||
** Utility to check whether kernel or core code is active **
|
||||
************************************************************/
|
||||
|
||||
extern void const * const kernel_stack;
|
||||
|
||||
static inline bool running_in_kernel()
|
||||
{
|
||||
addr_t const stack_base = reinterpret_cast<addr_t>(&kernel_stack);
|
||||
static constexpr size_t stack_size =
|
||||
Board::NR_OF_CPUS * Kernel::Cpu::KERNEL_STACK_SIZE;
|
||||
Hw::Memory_region const cpu_region = Hw::Mm::cpu_local_memory();
|
||||
|
||||
/* check stack variable against kernel stack area */
|
||||
return ((addr_t)&stack_base) >= stack_base &&
|
||||
((addr_t)&stack_base) < (stack_base + stack_size);
|
||||
/* check stack variable against kernel's cpu local memory area */
|
||||
return ((addr_t)&cpu_region) >= cpu_region.base &&
|
||||
((addr_t)&cpu_region) < cpu_region.end();
|
||||
}
|
||||
|
||||
|
||||
|
@ -12,6 +12,8 @@
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#include <cpu/consts.h>
|
||||
|
||||
/* core includes */
|
||||
#include <kernel/cpu.h>
|
||||
#include <kernel/thread.h>
|
||||
@ -162,14 +164,10 @@ Cpu_job & Cpu::schedule()
|
||||
}
|
||||
|
||||
|
||||
Genode::size_t kernel_stack_size = Cpu::KERNEL_STACK_SIZE;
|
||||
Genode::uint8_t kernel_stack[Board::NR_OF_CPUS][Cpu::KERNEL_STACK_SIZE]
|
||||
__attribute__((aligned(Genode::get_page_size())));
|
||||
|
||||
|
||||
addr_t Cpu::stack_start()
|
||||
{
|
||||
return (addr_t)&kernel_stack + KERNEL_STACK_SIZE * (_id + 1);
|
||||
return Abi::stack_align(Hw::Mm::cpu_local_memory().base +
|
||||
(1024*1024*_id) + (64*1024));
|
||||
}
|
||||
|
||||
|
||||
|
@ -145,9 +145,6 @@ class Kernel::Cpu : public Core::Cpu, private Irq::Pool, private Timeout
|
||||
|
||||
State state() { return _state; }
|
||||
|
||||
static constexpr size_t KERNEL_STACK_SIZE =
|
||||
16 * 1024 * sizeof(Genode::addr_t);
|
||||
|
||||
/**
|
||||
* Construct object for CPU 'id'
|
||||
*/
|
||||
|
@ -11,6 +11,8 @@
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
.include "memory_consts.s"
|
||||
|
||||
.section ".text"
|
||||
|
||||
/***********************
|
||||
@ -21,20 +23,22 @@
|
||||
_start:
|
||||
|
||||
/* switch to cpu-specific kernel stack */
|
||||
adr r1, _kernel_stack
|
||||
adr r2, _kernel_stack_size
|
||||
adr r1, _cpu_mem_area_base
|
||||
adr r2, _cpu_mem_slot_size
|
||||
adr r3, _kernel_stack_size
|
||||
ldr r1, [r1]
|
||||
ldr r2, [r2]
|
||||
ldr r2, [r2]
|
||||
add r0, #1
|
||||
ldr r3, [r3]
|
||||
mul r0, r0, r2
|
||||
add sp, r1, r0
|
||||
add r0, r0, r1
|
||||
add sp, r0, r3
|
||||
|
||||
/* jump into init C code */
|
||||
b _ZN6Kernel39main_initialize_and_handle_kernel_entryEv
|
||||
|
||||
_kernel_stack: .long kernel_stack
|
||||
_kernel_stack_size: .long kernel_stack_size
|
||||
_cpu_mem_area_base: .long HW_MM_CPU_LOCAL_MEMORY_AREA_START
|
||||
_cpu_mem_slot_size: .long HW_MM_CPU_LOCAL_MEMORY_SLOT_SIZE
|
||||
_kernel_stack_size: .long HW_MM_KERNEL_STACK_SIZE
|
||||
|
||||
|
||||
/*********************************
|
||||
|
@ -67,7 +67,6 @@ bool secure_irq(unsigned const i);
|
||||
|
||||
|
||||
extern "C" void monitor_mode_enter_normal_world(Genode::Vcpu_state&, void*);
|
||||
extern void * kernel_stack;
|
||||
|
||||
|
||||
void Vm::proceed(Cpu & cpu)
|
||||
|
@ -11,6 +11,20 @@
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
.include "memory_consts.s"
|
||||
|
||||
/**
|
||||
* Store CPU number in register x0
|
||||
*/
|
||||
.macro _cpu_number
|
||||
mrs x0, mpidr_el1
|
||||
and x8, x0, #(1<<24) /* MT bit */
|
||||
cbz x8, 1f
|
||||
lsr x0, x0, #8
|
||||
1:
|
||||
and x0, x0, #0b11111111
|
||||
.endm
|
||||
|
||||
.section ".text"
|
||||
|
||||
/***********************
|
||||
@ -21,20 +35,22 @@
|
||||
_start:
|
||||
|
||||
/* switch to cpu-specific kernel stack */
|
||||
/*adr r1, _kernel_stack
|
||||
adr r2, _kernel_stack_size
|
||||
ldr r1, [r1]
|
||||
ldr r2, [r2]
|
||||
ldr r2, [r2]
|
||||
add r0, #1
|
||||
mul r0, r0, r2
|
||||
add sp, r1, r0*/
|
||||
_cpu_number
|
||||
ldr x1, =_cpus_base
|
||||
ldr x1, [x1]
|
||||
mov x2, #HW_MM_CPU_LOCAL_MEMORY_SLOT_SIZE
|
||||
mul x0, x0, x2
|
||||
add x1, x1, x0
|
||||
mov x2, #HW_MM_KERNEL_STACK_SIZE
|
||||
add x1, x1, x2
|
||||
mov x2, #0x10 /* minus 16-byte to be aligned in stack */
|
||||
sub x1, x1, x2
|
||||
mov sp, x1
|
||||
|
||||
/* jump into init C code */
|
||||
b _ZN6Kernel39main_initialize_and_handle_kernel_entryEv
|
||||
|
||||
_kernel_stack: .quad kernel_stack
|
||||
_kernel_stack_size: .quad kernel_stack_size
|
||||
_cpus_base: .quad HW_MM_CPU_LOCAL_MEMORY_AREA_START
|
||||
|
||||
|
||||
/*********************************
|
||||
|
@ -11,6 +11,8 @@
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
.include "memory_consts.s"
|
||||
|
||||
.section ".text"
|
||||
|
||||
/***********************
|
||||
@ -20,9 +22,10 @@
|
||||
.global _start
|
||||
_start:
|
||||
|
||||
la x29, kernel_stack
|
||||
la x30, kernel_stack_size
|
||||
ld x30, (x30)
|
||||
li x29, HW_MM_CPU_LOCAL_MEMORY_AREA_START
|
||||
li x30, HW_MM_CPU_LOCAL_MEMORY_SLOT_STACK_OFFSET
|
||||
add x29, x29, x30
|
||||
li x30, HW_MM_KERNEL_STACK_SIZE
|
||||
add sp, x29, x30
|
||||
la x30, _ZN6Kernel39main_initialize_and_handle_kernel_entryEv
|
||||
|
||||
|
@ -12,6 +12,8 @@
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
.include "memory_consts.s"
|
||||
|
||||
.set CPU_IP, 0
|
||||
.set CPU_EXCEPTION, 8
|
||||
.set CPU_X1, 2*8
|
||||
@ -45,9 +47,10 @@ _kernel_entry:
|
||||
csrr x30, sscratch
|
||||
sd x30, CPU_X1 + 8 * 30(x31)
|
||||
|
||||
la x29, kernel_stack
|
||||
la x30, kernel_stack_size
|
||||
ld x30, (x30)
|
||||
li x29, HW_MM_CPU_LOCAL_MEMORY_AREA_START
|
||||
li x30, HW_MM_CPU_LOCAL_MEMORY_SLOT_STACK_OFFSET
|
||||
add x29, x29, x30
|
||||
li x30, HW_MM_KERNEL_STACK_SIZE
|
||||
add sp, x29, x30
|
||||
la x30, _ZN6Kernel24main_handle_kernel_entryEv
|
||||
|
||||
|
@ -108,10 +108,6 @@ void Cpu::mmu_fault(Context ®s, Kernel::Thread_fault &fault)
|
||||
}
|
||||
|
||||
|
||||
extern void const * const kernel_stack;
|
||||
extern size_t const kernel_stack_size;
|
||||
|
||||
|
||||
bool Cpu::active(Mmu_context &mmu_context)
|
||||
{
|
||||
return (mmu_context.cr3 == Cr3::read());
|
||||
@ -127,23 +123,12 @@ void Cpu::switch_to(Mmu_context &mmu_context)
|
||||
void Cpu::switch_to(Context &context)
|
||||
{
|
||||
tss.ist[0] = (addr_t)&context + sizeof(Cpu_state);
|
||||
|
||||
addr_t const stack_base = reinterpret_cast<addr_t>(&kernel_stack);
|
||||
context.kernel_stack = stack_base +
|
||||
(Cpu::executing_id() + 1) * kernel_stack_size -
|
||||
sizeof(addr_t);
|
||||
}
|
||||
|
||||
|
||||
unsigned Cpu::executing_id()
|
||||
{
|
||||
void * const stack_ptr = nullptr;
|
||||
addr_t const stack_addr = reinterpret_cast<addr_t>(&stack_ptr);
|
||||
addr_t const stack_base = reinterpret_cast<addr_t>(&kernel_stack);
|
||||
|
||||
unsigned const cpu_id = (unsigned)((stack_addr - stack_base) / kernel_stack_size);
|
||||
|
||||
return cpu_id;
|
||||
return Cpu::Cpuid_1_ebx::Apic_id::get(Cpu::Cpuid_1_ebx::read());
|
||||
}
|
||||
|
||||
|
||||
|
@ -91,13 +91,7 @@ class Core::Cpu : public Hw::X86_64_cpu
|
||||
} __attribute__((packed)) gdt { };
|
||||
|
||||
|
||||
/**
|
||||
* Extend basic CPU state by members relevant for 'base-hw' only
|
||||
*/
|
||||
struct Kernel_stack { unsigned long kernel_stack { }; };
|
||||
|
||||
/* exception_vector.s depends on the position of the Kernel_stack */
|
||||
struct alignas(16) Context : Cpu_state, Kernel_stack, Fpu_context
|
||||
struct alignas(16) Context : Cpu_state, Fpu_context
|
||||
{
|
||||
enum Eflags {
|
||||
EFLAGS_TF = 1 << 8,
|
||||
|
@ -13,6 +13,8 @@
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
.include "stack_switch.s"
|
||||
|
||||
.section ".text"
|
||||
|
||||
/***********************
|
||||
@ -22,20 +24,7 @@
|
||||
.global _start
|
||||
_start:
|
||||
|
||||
/* load kernel stack size */
|
||||
movq kernel_stack_size@GOTPCREL(%rip), %rbx
|
||||
movq (%rbx), %rax
|
||||
|
||||
/* calculate stack top (rdi contains cpu_id), stack top is stored in rax */
|
||||
movq %rdi, %rbx
|
||||
inc %rbx
|
||||
mulq %rbx
|
||||
|
||||
/* switch to kernel stack */
|
||||
movq kernel_stack@GOTPCREL(%rip), %rbx
|
||||
addq %rbx, %rax
|
||||
subq $8, %rax
|
||||
movq %rax, %rsp
|
||||
switch_to_kernel_stack
|
||||
|
||||
/* jump to C entry code */
|
||||
jmp _ZN6Kernel39main_initialize_and_handle_kernel_entryEv
|
||||
|
@ -14,13 +14,14 @@
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
.include "stack_switch.s"
|
||||
|
||||
/* offsets of member variables in a CPU context */
|
||||
.set IP_OFFSET, 17 * 8
|
||||
.set SP_OFFSET, 20 * 8
|
||||
|
||||
/* virtual addresses */
|
||||
.set BASE, 0xffffffc000000000
|
||||
.set ISR, BASE
|
||||
.set ISR, HW_MM_KERNEL_START
|
||||
.set ISR_ENTRY_SIZE, 12
|
||||
|
||||
.set IDT_FLAGS_PRIVILEGED, 0x8e01
|
||||
@ -114,13 +115,12 @@
|
||||
|
||||
/**
|
||||
* Calculate offset into Kernel_stack member of Cpu::Context as defined
|
||||
* in cpu.h - struct Context : Cpu_state, Kernel_stack, Fpu_context
|
||||
* in cpu.h - struct Context : Cpu_state, Fpu_context
|
||||
*/
|
||||
.set REGISTER_COUNT, 22
|
||||
.set REGISTER_SIZE, 8
|
||||
.set SIZEOF_CPU_STATE, REGISTER_COUNT * REGISTER_SIZE /* sizeof (Cpu_state) */
|
||||
.set KERNEL_STACK_OFFSET, SIZEOF_CPU_STATE
|
||||
.set FPU_CONTEXT_OFFSET, KERNEL_STACK_OFFSET + 8
|
||||
.set FPU_CONTEXT_OFFSET, SIZEOF_CPU_STATE
|
||||
/* rsp contains pointer to Cpu::Context */
|
||||
|
||||
/* save FPU context */
|
||||
@ -129,10 +129,7 @@
|
||||
movq (%rax), %rax
|
||||
fxsave (%rax)
|
||||
|
||||
/* Restore kernel stack and continue kernel execution */
|
||||
movq %rsp, %rax
|
||||
addq $KERNEL_STACK_OFFSET, %rax
|
||||
movq (%rax), %rsp
|
||||
switch_to_kernel_stack
|
||||
|
||||
_load_address _ZN6Kernel24main_handle_kernel_entryEv rcx
|
||||
jmp *%rcx
|
||||
|
@ -27,6 +27,5 @@ void Kernel::Cpu::_arch_init()
|
||||
_ipi_irq.init();
|
||||
|
||||
/* enable timer interrupt */
|
||||
_pic.store_apic_id(id());
|
||||
_pic.unmask(_timer.interrupt_id(), id());
|
||||
}
|
||||
|
@ -136,7 +136,7 @@ void Local_interrupt_controller::send_ipi(unsigned const cpu_id)
|
||||
Icr_high::access_t icr_high = 0;
|
||||
Icr_low::access_t icr_low = 0;
|
||||
|
||||
Icr_high::Destination::set(icr_high, _global_irq_ctrl.lapic_id(cpu_id));
|
||||
Icr_high::Destination::set(icr_high, cpu_id);
|
||||
|
||||
Icr_low::Vector::set(icr_low, Local_interrupt_controller::IPI);
|
||||
Icr_low::Level_assert::set(icr_low);
|
||||
@ -151,19 +151,6 @@ void Local_interrupt_controller::send_ipi(unsigned const cpu_id)
|
||||
** Board::Global_interrupt_controller **
|
||||
****************************************/
|
||||
|
||||
uint8_t Global_interrupt_controller::lapic_id(unsigned cpu_id) const
|
||||
{
|
||||
return _lapic_id[cpu_id];
|
||||
}
|
||||
|
||||
|
||||
void Global_interrupt_controller::lapic_id(unsigned cpu_id,
|
||||
uint8_t lapic_id)
|
||||
{
|
||||
_lapic_id[cpu_id] = lapic_id;
|
||||
}
|
||||
|
||||
|
||||
void Global_interrupt_controller::irq_mode(unsigned irq_number,
|
||||
unsigned trigger,
|
||||
unsigned polarity)
|
||||
|
@ -87,7 +87,6 @@ class Board::Global_interrupt_controller : public Genode::Mmio<Hw::Cpu_memory_ma
|
||||
};
|
||||
|
||||
unsigned _irte_count = 0; /* number of redirection table entries */
|
||||
uint8_t _lapic_id[Board::NR_OF_CPUS]; /* unique name of the LAPIC of each CPU */
|
||||
Irq_mode _irq_mode[IRQ_COUNT];
|
||||
|
||||
/**
|
||||
@ -137,15 +136,6 @@ class Board::Global_interrupt_controller : public Genode::Mmio<Hw::Cpu_memory_ma
|
||||
void irq_mode(unsigned irq_number,
|
||||
unsigned trigger,
|
||||
unsigned polarity);
|
||||
|
||||
|
||||
/***************
|
||||
** Accessors **
|
||||
***************/
|
||||
|
||||
void lapic_id(unsigned cpu_id, uint8_t lapic_id);
|
||||
|
||||
uint8_t lapic_id(unsigned cpu_id) const;
|
||||
};
|
||||
|
||||
|
||||
@ -190,14 +180,6 @@ class Board::Local_interrupt_controller : private Hw::Local_apic
|
||||
|
||||
void irq_mode(unsigned irq, unsigned trigger, unsigned polarity);
|
||||
|
||||
void store_apic_id(unsigned const cpu_id)
|
||||
{
|
||||
if (cpu_id < Board::NR_OF_CPUS) {
|
||||
Id::access_t const lapic_id = read<Id>();
|
||||
_global_irq_ctrl.lapic_id(cpu_id, (unsigned char)((lapic_id >> 24) & 0xff));
|
||||
}
|
||||
}
|
||||
|
||||
void send_ipi(unsigned const);
|
||||
|
||||
void init();
|
||||
|
35
repos/base-hw/src/core/spec/x86_64/stack_switch.s
Normal file
35
repos/base-hw/src/core/spec/x86_64/stack_switch.s
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* \brief Assembler macros for x86 kernel stack switch
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2024-07-02
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2024 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.
|
||||
*/
|
||||
|
||||
.include "memory_consts.s"
|
||||
|
||||
/* calculate stack from cpu memory area and cpu apic id */
|
||||
.macro switch_to_kernel_stack
|
||||
/* request cpuid 1, result in ebx contains 1-byte apic id at bit 24 */
|
||||
movq $1, %rax
|
||||
cpuid
|
||||
shr $24, %rbx
|
||||
and $0xff, %rbx
|
||||
|
||||
/* calculate cpu local memory slot by apic id */
|
||||
movq $HW_MM_CPU_LOCAL_MEMORY_SLOT_SIZE, %rax
|
||||
mulq %rbx
|
||||
movq $HW_MM_CPU_LOCAL_MEMORY_AREA_START, %rbx
|
||||
addq %rbx, %rax
|
||||
|
||||
/* calculate top of stack and switch to it */
|
||||
movq $HW_MM_KERNEL_STACK_SIZE, %rbx
|
||||
addq %rbx, %rax
|
||||
subq $8, %rax
|
||||
movq %rax, %rsp
|
||||
.endm
|
@ -28,6 +28,7 @@ namespace Hw {
|
||||
Memory_region const core_page_tables();
|
||||
Memory_region const core_mmio();
|
||||
Memory_region const core_heap();
|
||||
Memory_region const cpu_local_memory();
|
||||
Memory_region const system_exception_vector();
|
||||
Memory_region const hypervisor_exception_vector();
|
||||
Memory_region const hypervisor_stack();
|
||||
|
@ -65,11 +65,16 @@ struct Hw::Apic_madt
|
||||
|
||||
struct Lapic : Genode::Mmio<0x8>
|
||||
{
|
||||
struct Flags : Register <0x04, 32> { enum { VALID = 1 }; };
|
||||
struct Apic_id : Register<0x3, 8> {};
|
||||
struct Flags : Register<0x4, 32>
|
||||
{
|
||||
enum { VALID = 1 };
|
||||
};
|
||||
|
||||
Lapic(Apic_madt const * a) : Mmio({(char *)a, Mmio::SIZE}) { }
|
||||
|
||||
bool valid() { return read<Flags>() & Flags::VALID; };
|
||||
Genode::uint8_t id() { return read<Apic_id>(); }
|
||||
};
|
||||
|
||||
} __attribute__((packed));
|
||||
|
@ -310,6 +310,10 @@ struct Hw::X86_64_cpu
|
||||
|
||||
X86_64_CPUID_REGISTER(Cpuid_1_eax, 1, eax);
|
||||
|
||||
X86_64_CPUID_REGISTER(Cpuid_1_ebx, 1, ebx,
|
||||
struct Apic_id : Bitfield<24, 8> { };
|
||||
);
|
||||
|
||||
X86_64_CPUID_REGISTER(Cpuid_1_ecx, 1, ecx,
|
||||
struct Vmx : Bitfield< 5, 1> { };
|
||||
struct Tsc_deadline : Bitfield<24, 1> { };
|
||||
|
30
repos/base-hw/src/lib/hw/spec/32bit/memory_consts.s
Normal file
30
repos/base-hw/src/lib/hw/spec/32bit/memory_consts.s
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* \brief Kernel/Bootstrap constants shared in between C++/Assembler
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2024-07-02
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2024 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.
|
||||
*/
|
||||
|
||||
##include <base/stdint.h>
|
||||
|
||||
#namespace Hw {
|
||||
# namespace Mm {
|
||||
|
||||
HW_MM_KERNEL_START = 0x80000000
|
||||
HW_MM_KERNEL_STACK_SIZE = 0x10000
|
||||
|
||||
HW_MM_CPU_LOCAL_MEMORY_AREA_START = 0xd0000000
|
||||
HW_MM_CPU_LOCAL_MEMORY_AREA_SIZE = 0x10000000
|
||||
HW_MM_CPU_LOCAL_MEMORY_SLOT_SIZE = 0x100000
|
||||
HW_MM_CPU_LOCAL_MEMORY_SLOT_STACK_OFFSET = 0x0
|
||||
HW_MM_CPU_LOCAL_MEMORY_SLOT_OBJECT_OFFSET = 0x20000
|
||||
HW_MM_CPU_LOCAL_MEMORY_SLOT_OBJECT_SIZE = 0x2000
|
||||
|
||||
# }
|
||||
#}
|
@ -14,6 +14,7 @@
|
||||
/* base-internal includes */
|
||||
#include <base/internal/native_utcb.h>
|
||||
|
||||
#include <hw/memory_consts.h>
|
||||
#include <hw/memory_map.h>
|
||||
|
||||
using Hw::Memory_region;
|
||||
@ -22,7 +23,6 @@ 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); }
|
||||
@ -36,8 +36,12 @@ Memory_region const Hw::Mm::core_stack_area() {
|
||||
Memory_region const Hw::Mm::core_page_tables() {
|
||||
return Memory_region(0xc0000000UL, 0x10000000UL); }
|
||||
|
||||
Memory_region const Hw::Mm::cpu_local_memory() {
|
||||
return Memory_region(CPU_LOCAL_MEMORY_AREA_START,
|
||||
CPU_LOCAL_MEMORY_AREA_SIZE); }
|
||||
|
||||
Memory_region const Hw::Mm::core_mmio() {
|
||||
return Memory_region(0xd0000000UL, 0x10000000UL); }
|
||||
return Memory_region(0xf0000000UL, 0xf000000UL); }
|
||||
|
||||
Memory_region const Hw::Mm::system_exception_vector() {
|
||||
return Memory_region(0xfff00000UL, 0x1000UL); }
|
||||
|
30
repos/base-hw/src/lib/hw/spec/64bit/memory_consts.s
Normal file
30
repos/base-hw/src/lib/hw/spec/64bit/memory_consts.s
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* \brief Kernel/Bootstrap constants shared in between C++/Assembler
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2024-07-02
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2024 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.
|
||||
*/
|
||||
|
||||
##include <base/stdint.h>
|
||||
|
||||
#namespace Hw {
|
||||
# namespace Mm {
|
||||
|
||||
HW_MM_KERNEL_START = 0xffffffc000000000
|
||||
HW_MM_KERNEL_STACK_SIZE = 0x10000
|
||||
|
||||
HW_MM_CPU_LOCAL_MEMORY_AREA_START = 0xffffffe070000000
|
||||
HW_MM_CPU_LOCAL_MEMORY_AREA_SIZE = 0x10000000
|
||||
HW_MM_CPU_LOCAL_MEMORY_SLOT_SIZE = 0x100000
|
||||
HW_MM_CPU_LOCAL_MEMORY_SLOT_STACK_OFFSET = 0x0
|
||||
HW_MM_CPU_LOCAL_MEMORY_SLOT_OBJECT_OFFSET = 0x20000
|
||||
HW_MM_CPU_LOCAL_MEMORY_SLOT_OBJECT_SIZE = 0x2000
|
||||
|
||||
# }
|
||||
#}
|
@ -14,16 +14,16 @@
|
||||
/* base-internal includes */
|
||||
#include <base/internal/native_utcb.h>
|
||||
|
||||
#include <hw/memory_consts.h>
|
||||
#include <hw/memory_map.h>
|
||||
|
||||
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 USER_END = (1ULL << (39 - 1));
|
||||
static constexpr addr_t KERNEL_START = 0xffffffc000000000UL;
|
||||
static constexpr addr_t USER_START = Genode::user_utcb_main_thread()
|
||||
+ sizeof(Native_utcb);
|
||||
static constexpr addr_t USER_END = (1ULL << (39 - 1));
|
||||
|
||||
|
||||
Memory_region const Hw::Mm::user() {
|
||||
@ -53,5 +53,9 @@ Memory_region const Hw::Mm::hypervisor_exception_vector() {
|
||||
Memory_region const Hw::Mm::hypervisor_stack() {
|
||||
return Memory_region(0xffffffe060000000UL, 0x10000UL); }
|
||||
|
||||
Memory_region const Hw::Mm::cpu_local_memory() {
|
||||
return Memory_region(CPU_LOCAL_MEMORY_AREA_START,
|
||||
CPU_LOCAL_MEMORY_AREA_SIZE); }
|
||||
|
||||
Memory_region const Hw::Mm::supervisor_exception_vector() {
|
||||
return Memory_region(KERNEL_START, 0x1000UL); }
|
||||
|
Loading…
Reference in New Issue
Block a user