From 7d7f338b2bf6462becde97334dcb8ea485ede7bc Mon Sep 17 00:00:00 2001 From: Adrian Danis Date: Tue, 8 Aug 2017 01:34:13 +1000 Subject: [PATCH] arm: Provide TLS_BASE virtual register This commit provides a universal TLS_BASE virtual register on ARM, similar to as exists on x86. Depending on the precise configuration this virtual register maps to a different register * aarch64: TPIDRURW is used for the TLS_BASE and is already declared and being saved and restored on context switches, so this just adds TLS_BASE as an alias of it * armv6: Has no hardware register for use for a TLS_BASE, and so the virtual register gets stored into the globals frame * armv7+: TPIDURO is used for TLS_BASE and so the restore paths are modified to load TLS_BASE into it --- include/arch/arm/arch/32/mode/fastpath/fastpath.h | 1 + include/arch/arm/arch/32/mode/machine/registerset.h | 7 ++++--- include/arch/arm/arch/64/mode/machine/registerset.h | 1 + src/arch/arm/32/c_traps.c | 1 + src/arch/arm/32/kernel/thread.c | 2 ++ 5 files changed, 9 insertions(+), 3 deletions(-) diff --git a/include/arch/arm/arch/32/mode/fastpath/fastpath.h b/include/arch/arm/arch/32/mode/fastpath/fastpath.h index a22671172..bc39e2e32 100644 --- a/include/arch/arm/arch/32/mode/fastpath/fastpath.h +++ b/include/arch/arm/arch/32/mode/fastpath/fastpath.h @@ -135,6 +135,7 @@ fastpath_restore(word_t badge, word_t msgInfo, tcb_t *cur_thread) #ifndef CONFIG_ARCH_ARM_V6 writeTPIDRURW(getRegister(NODE_STATE(ksCurThread), TPIDRURW)); + writeTPIDRURO(getRegister(NODE_STATE(ksCurThread), TLS_BASE)); #endif #ifdef CONFIG_HAVE_FPU diff --git a/include/arch/arm/arch/32/mode/machine/registerset.h b/include/arch/arm/arch/32/mode/machine/registerset.h index 4781c710e..e75c9461c 100644 --- a/include/arch/arm/arch/32/mode/machine/registerset.h +++ b/include/arch/arm/arch/32/mode/machine/registerset.h @@ -95,13 +95,14 @@ enum _register { CPSR = 16, FaultInstruction = 17, + TLS_BASE = 18, #ifndef CONFIG_ARCH_ARM_V6 /* user readable/writable thread ID register. * name comes from the ARM manual */ - TPIDRURW = 18, - n_contextRegisters = 19, + TPIDRURW = 19, + n_contextRegisters = 20, #else - n_contextRegisters = 18, + n_contextRegisters = 19, #endif }; diff --git a/include/arch/arm/arch/64/mode/machine/registerset.h b/include/arch/arm/arch/64/mode/machine/registerset.h index ce38bcaa2..1d641704d 100644 --- a/include/arch/arm/arch/64/mode/machine/registerset.h +++ b/include/arch/arm/arch/64/mode/machine/registerset.h @@ -143,6 +143,7 @@ enum _register { /* user readable/writable thread ID register. * name comes from the ARM manual */ TPIDRURW = 35, + TLS_BASE = 35, n_contextRegisters = 36, }; diff --git a/src/arch/arm/32/c_traps.c b/src/arch/arm/32/c_traps.c index 25f2d1093..902424f55 100644 --- a/src/arch/arm/32/c_traps.c +++ b/src/arch/arm/32/c_traps.c @@ -40,6 +40,7 @@ void VISIBLE NORETURN restore_user_context(void) #ifndef CONFIG_ARCH_ARM_V6 writeTPIDRURW(getRegister(NODE_STATE(ksCurThread), TPIDRURW)); + writeTPIDRURO(getRegister(NODE_STATE(ksCurThread), TLS_BASE)); #endif if (config_set(CONFIG_ARM_HYPERVISOR_SUPPORT)) { diff --git a/src/arch/arm/32/kernel/thread.c b/src/arch/arm/32/kernel/thread.c index fdbab4a3a..53186f902 100644 --- a/src/arch/arm/32/kernel/thread.c +++ b/src/arch/arm/32/kernel/thread.c @@ -22,6 +22,7 @@ Arch_switchToThread(tcb_t *tcb) setVMRoot(tcb); #if defined(CONFIG_IPC_BUF_GLOBALS_FRAME) *armKSGlobalsFrame = tcb->tcbIPCBuffer; + armKSGlobalsFrame[1] = getRegister(tcb, TLS_BASE); #endif clearExMonitor(); } @@ -45,6 +46,7 @@ Arch_switchToIdleThread(void) #ifdef CONFIG_IPC_BUF_GLOBALS_FRAME *armKSGlobalsFrame = 0; + armKSGlobalsFrame[1] = 0; #endif /* CONFIG_IPC_BUF_GLOBALS_FRAME */ }