summaryrefslogtreecommitdiff
path: root/sys/src/9/omap/lproc.s
diff options
context:
space:
mode:
authorTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
committerTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
commite5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch)
treed8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/9/omap/lproc.s
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/9/omap/lproc.s')
-rwxr-xr-xsys/src/9/omap/lproc.s47
1 files changed, 47 insertions, 0 deletions
diff --git a/sys/src/9/omap/lproc.s b/sys/src/9/omap/lproc.s
new file mode 100755
index 000000000..0b4eac238
--- /dev/null
+++ b/sys/src/9/omap/lproc.s
@@ -0,0 +1,47 @@
+#include "mem.h"
+#include "arm.h"
+
+/*
+ * This is the first jump from kernel to user mode.
+ * Fake a return from interrupt.
+ *
+ * Enter with R0 containing the user stack pointer.
+ * UTZERO + 0x20 is always the entry point.
+ *
+ */
+TEXT touser(SB), 1, $-4
+ /* store the user stack pointer into the USR_r13 */
+ MOVM.DB.W [R0], (R13)
+ /* avoid the ambiguity described in notes/movm.w. */
+// MOVM.S.IA.W (R13), [R13]
+ MOVM.S (R13), [R13]
+ ADD $4, R13
+
+ /* set up a PSR for user level */
+ MOVW $(PsrMusr), R0
+ MOVW R0, SPSR
+
+ /* save the PC on the stack */
+ MOVW $(UTZERO+0x20), R0
+ MOVM.DB.W [R0], (R13)
+
+ /*
+ * note that 5a's RFE is not the v6 arch. instruction (0xe89d0a00,
+ * I think), which loads CPSR from the word after the PC at (R13),
+ * but rather the pre-v6 simulation `MOVM.IA.S.W (R13), [R15]'
+ * (0xe8fd8000 since MOVM is LDM in this case), which loads CPSR
+ * not from memory but from SPSR due to `.S'.
+ */
+ RFE
+
+/*
+ * here to jump to a newly forked process
+ */
+TEXT forkret(SB), 1, $-4
+ ADD $(4*15), R13 /* make r13 point to ureg->type */
+ MOVW 8(R13), R14 /* restore link */
+ MOVW 4(R13), R0 /* restore SPSR */
+ MOVW R0, SPSR /* ... */
+ MOVM.DB.S (R13), [R0-R14] /* restore registers */
+ ADD $8, R13 /* pop past ureg->{type+psr} */
+ RFE /* MOVM.IA.S.W (R13), [R15] */