From b22c6f6f297e30eefd79b6b21555337e98729096 Mon Sep 17 00:00:00 2001 From: David Karoly Date: Sat, 19 Feb 2022 16:06:59 +0100 Subject: [PATCH] kernel/arch/arm: swap TTBR on thread context switch Change-Id: Ie85742d077866c10ba57b46848d5acaef932615e Reviewed-on: https://review.haiku-os.org/c/haiku/+/4982 Tested-by: Commit checker robot Reviewed-by: waddlesplash Reviewed-by: X512 Reviewed-by: Fredrik Holmqvist --- src/system/kernel/arch/arm/arch_thread.cpp | 37 +++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/src/system/kernel/arch/arm/arch_thread.cpp b/src/system/kernel/arch/arm/arch_thread.cpp index 2de87612e8..e364e5e6a4 100644 --- a/src/system/kernel/arch/arm/arch_thread.cpp +++ b/src/system/kernel/arch/arm/arch_thread.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2003-2010, Haiku Inc. All rights reserved. + * Copyright 2003-2022, Haiku Inc. All rights reserved. * Distributed under the terms of the MIT License. * * Authors: @@ -28,6 +28,9 @@ #include +#include "ARMPagingStructures.h" +#include "ARMVMTranslationMap.h" + //#define TRACE_ARCH_THREAD #ifdef TRACE_ARCH_THREAD # define TRACE(x) dprintf x @@ -131,9 +134,41 @@ arch_thread_init_tls(Thread *thread) extern "C" void arm_context_switch(void *from, void *to); + +void +arm_swap_pgdir(uint32_t pageDirectoryAddress) +{ + // Set translation table base + asm volatile("MCR p15, 0, %[addr], c2, c0, 0"::[addr] "r" (pageDirectoryAddress)); + isb(); + + arch_cpu_global_TLB_invalidate(); + + //TODO: update Context ID (incl. ASID) + //TODO: check if any additional TLB or Cache maintenance is needed +} + + void arch_thread_context_switch(Thread *from, Thread *to) { + VMAddressSpace *oldAddressSpace = from->team->address_space; + VMTranslationMap *oldTranslationMap = oldAddressSpace->TranslationMap(); + phys_addr_t oldPageDirectoryAddress = + ((ARMVMTranslationMap *)oldTranslationMap)->PagingStructures()->pgdir_phys; + + VMAddressSpace *newAddressSpace = to->team->address_space; + VMTranslationMap *newTranslationMap = newAddressSpace->TranslationMap(); + phys_addr_t newPageDirectoryAddress = + ((ARMVMTranslationMap *)newTranslationMap)->PagingStructures()->pgdir_phys; + + if (oldPageDirectoryAddress != newPageDirectoryAddress) { + TRACE(("arch_thread_context_switch: swap pgdir: " + "0x%08" B_PRIxPHYSADDR " -> 0x%08" B_PRIxPHYSADDR "\n", + oldPageDirectoryAddress, newPageDirectoryAddress)); + arm_swap_pgdir(newPageDirectoryAddress); + } + TRACE(("arch_thread_context_switch: %p(%s/%p) -> %p(%s/%p)\n", from, from->name, from->arch_info.sp, to, to->name, to->arch_info.sp)); arm_context_switch(&from->arch_info, &to->arch_info);