hw: move stack into cpu local mem area

Ref genodelabs/genode#5310
This commit is contained in:
Stefan Kalkowski 2024-07-03 14:44:15 +02:00 committed by Christian Helmuth
parent 6afe4f79a2
commit 9258004cc7
37 changed files with 297 additions and 176 deletions

View File

@ -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)

View 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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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})

View File

@ -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); });

View File

@ -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:

View 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;
}

View File

@ -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;
}

View File

@ -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();
}

View File

@ -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));
}

View File

@ -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'
*/

View File

@ -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
/*********************************

View File

@ -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)

View File

@ -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
/*********************************

View File

@ -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

View File

@ -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

View File

@ -108,10 +108,6 @@ void Cpu::mmu_fault(Context &regs, 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());
}

View File

@ -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,

View File

@ -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

View File

@ -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

View File

@ -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());
}

View File

@ -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)

View File

@ -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();

View 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

View File

@ -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();

View File

@ -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));

View File

@ -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> { };

View 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
# }
#}

View File

@ -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); }

View 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
# }
#}

View File

@ -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); }