summaryrefslogtreecommitdiffstats
path: root/include/asm-mips64/stackframe.h
diff options
context:
space:
mode:
authorKanoj Sarcar <kanoj@engr.sgi.com>2000-04-25 16:04:51 +0000
committerKanoj Sarcar <kanoj@engr.sgi.com>2000-04-25 16:04:51 +0000
commit3eae3bd10dd78ad075f2e70d511534becaae7914 (patch)
tree5ea53d7ee9fd35af22416abba831e124fc160ac5 /include/asm-mips64/stackframe.h
parent35cf77f2195a9d93146076702d991663edddd267 (diff)
We use the ST0_CU0 bit to determine whether we are coming into
kernel mode for the first time from user mode (on intr/exception/ syscall etc). If so, we need to set the sp to point to the kernel stack. On UP kernels, the kernel stack pointer is stored in the global variable "kernelsp". For SMP kernel, the physical address of the current task structure is stuffed into the watchlo/watchhi registers, so on first entry into the kernel, we need to munge this value properly to setup the sp register.
Diffstat (limited to 'include/asm-mips64/stackframe.h')
-rw-r--r--include/asm-mips64/stackframe.h14
1 files changed, 14 insertions, 0 deletions
diff --git a/include/asm-mips64/stackframe.h b/include/asm-mips64/stackframe.h
index aa0a15fc9..0257bb07a 100644
--- a/include/asm-mips64/stackframe.h
+++ b/include/asm-mips64/stackframe.h
@@ -11,8 +11,12 @@
#ifndef _ASM_STACKFRAME_H
#define _ASM_STACKFRAME_H
+#include <linux/config.h>
+
#include <asm/asm.h>
#include <asm/offset.h>
+#include <asm/processor.h>
+#include <asm/addrspace.h>
#ifdef _LANGUAGE_C
@@ -82,8 +86,18 @@
move k1, sp
.set reorder
/* Called from user mode, new stack. */
+#ifndef CONFIG_SMP
lui k1, %hi(kernelsp)
ld k1, %lo(kernelsp)(k1)
+#else
+ mfc0 k1, CP0_WATCHHI
+ mfc0 k0, CP0_WATCHLO
+ dsll32 k1, k1, 0
+ or k1, k1, k0
+ li k0, K0BASE
+ or k1, k1, k0
+ daddiu k1, k1, KERNEL_STACK_SIZE-32
+#endif
8: move k0, sp
dsubu sp, k1, PT_SIZE
sd k0, PT_R29(sp)