summaryrefslogtreecommitdiff
path: root/i386/i386/locore.S
diff options
context:
space:
mode:
Diffstat (limited to 'i386/i386/locore.S')
-rw-r--r--i386/i386/locore.S216
1 files changed, 85 insertions, 131 deletions
diff --git a/i386/i386/locore.S b/i386/i386/locore.S
index eeef09d7..a44be04d 100644
--- a/i386/i386/locore.S
+++ b/i386/i386/locore.S
@@ -119,6 +119,7 @@ LEXT(retry_table_end) ;\
* Uses %eax, %ebx, %ecx.
*/
#define TIME_TRAP_UENTRY \
+ pushf /* Save flags */ ;\
cli /* block interrupts */ ;\
movl VA_ETC,%ebx /* get timer value */ ;\
movl CX(EXT(current_tstamp),%edx),%ecx /* get old time stamp */;\
@@ -131,7 +132,7 @@ LEXT(retry_table_end) ;\
0: addl $(TH_SYSTEM_TIMER-TH_USER_TIMER),%ecx ;\
/* switch to sys timer */;\
movl %ecx,CX(EXT(current_timer),%edx) /* make it current */ ;\
- sti /* allow interrupts */
+ popf /* allow interrupts */
/*
* Update time on system call entry.
@@ -141,6 +142,7 @@ LEXT(retry_table_end) ;\
* Same as TIME_TRAP_UENTRY, but preserves %eax.
*/
#define TIME_TRAP_SENTRY \
+ pushf /* Save flags */ ;\
cli /* block interrupts */ ;\
movl VA_ETC,%ebx /* get timer value */ ;\
movl CX(EXT(current_tstamp),%edx),%ecx /* get old time stamp */;\
@@ -155,7 +157,7 @@ LEXT(retry_table_end) ;\
0: addl $(TH_SYSTEM_TIMER-TH_USER_TIMER),%ecx ;\
/* switch to sys timer */;\
movl %ecx,CX(EXT(current_timer),%edx) /* make it current */ ;\
- sti /* allow interrupts */
+ popf /* allow interrupts */
/*
* update time on user trap exit.
@@ -1241,13 +1243,12 @@ ENTRY(discover_x86_cpu_type)
*/
/*
- * Copy from user address space.
+ * Copy from user address space - generic version.
* arg0: user address
* arg1: kernel address
* arg2: byte count
*/
ENTRY(copyin)
-Entry(copyinmsg)
pushl %esi
pushl %edi /* save registers */
@@ -1284,13 +1285,48 @@ copyin_fail:
jmp copyin_ret /* pop frame and return */
/*
- * Copy to user address space.
+ * Copy from user address space - version for copying messages.
+ * arg0: user address
+ * arg1: kernel address
+ * arg2: byte count - must be a multiple of four
+ */
+ENTRY(copyinmsg)
+ pushl %esi
+ pushl %edi /* save registers */
+
+ movl 8+S_ARG0,%esi /* get user start address */
+ movl 8+S_ARG1,%edi /* get kernel destination address */
+ movl 8+S_ARG2,%ecx /* get count */
+
+ movl $USER_DS,%eax /* use user data segment for accesses */
+ mov %ax,%ds
+
+ /*cld*/ /* count up: default mode in all GCC code */
+ shrl $2,%ecx
+ RECOVER(copyinmsg_fail)
+ rep
+ movsl /* move longwords */
+ xorl %eax,%eax /* return 0 for success */
+
+copyinmsg_ret:
+ mov %ss,%di /* restore DS to kernel segment */
+ mov %di,%ds
+
+ popl %edi /* restore registers */
+ popl %esi
+ ret /* and return */
+
+copyinmsg_fail:
+ movl $1,%eax /* return 1 for failure */
+ jmp copyinmsg_ret /* pop frame and return */
+
+/*
+ * Copy to user address space - generic version.
* arg0: kernel address
* arg1: user address
* arg2: byte count
*/
ENTRY(copyout)
-Entry(copyoutmsg)
pushl %esi
pushl %edi /* save registers */
@@ -1306,14 +1342,13 @@ Entry(copyoutmsg)
jbe copyout_retry /* Use slow version on i386 */
#endif /* !defined(MACH_HYP) && !PAE */
- movl %edx,%eax /* use count */
/*cld*/ /* count up: always this way in GCC code */
- movl %eax,%ecx /* move by longwords first */
+ movl %edx,%ecx /* move by longwords first */
shrl $2,%ecx
RECOVER(copyout_fail)
rep
movsl
- movl %eax,%ecx /* now move remaining bytes */
+ movl %edx,%ecx /* now move remaining bytes */
andl $3,%ecx
RECOVER(copyout_fail)
rep
@@ -1332,6 +1367,47 @@ copyout_fail:
movl $1,%eax /* return 1 for failure */
jmp copyout_ret /* pop frame and return */
+/*
+ * Copy to user address space - version for copying messages.
+ * arg0: kernel address
+ * arg1: user address
+ * arg2: byte count - must be a multiple of four
+ */
+ENTRY(copyoutmsg)
+ pushl %esi
+ pushl %edi /* save registers */
+
+ movl 8+S_ARG0,%esi /* get kernel start address */
+ movl 8+S_ARG1,%edi /* get user start address */
+ movl 8+S_ARG2,%ecx /* get count */
+
+ movl $USER_DS,%eax /* use user data segment for accesses */
+ mov %ax,%es
+
+#if !defined(MACH_HYP) && !PAE
+ movl 8+S_ARG2,%edx /* copyout_retry expects count here */
+ cmpl $3,machine_slot+SUB_TYPE_CPU_TYPE
+ jbe copyout_retry /* Use slow version on i386 */
+#endif /* !defined(MACH_HYP) && !PAE */
+
+ shrl $2,%ecx /* move by longwords */
+ RECOVER(copyoutmsg_fail)
+ rep
+ movsl
+ xorl %eax,%eax /* return 0 for success */
+
+copyoutmsg_ret:
+ mov %ss,%di /* restore ES to kernel segment */
+ mov %di,%es
+
+ popl %edi /* restore registers */
+ popl %esi
+ ret /* and return */
+
+copyoutmsg_fail:
+ movl $1,%eax /* return 1 for failure */
+ jmp copyoutmsg_ret /* pop frame and return */
+
#if !defined(MACH_HYP) && !PAE
/*
* Check whether user address space is writable
@@ -1422,128 +1498,6 @@ _inst_fetch_fault:
-ENTRY(dr6)
-#ifdef MACH_RING1
- pushl %ebx
- movl $6, %ebx
- call __hyp_get_debugreg
- popl %ebx
-#else /* MACH_RING1 */
- movl %db6, %eax
-#endif /* MACH_RING1 */
- ret
-
-/* dr<i>(address, type, len, persistence)
- */
-ENTRY(dr0)
- movl S_ARG0, %eax
- movl %eax,EXT(dr_addr)
-#ifdef MACH_RING1
- pushl %ebx
- movl $0,%ebx
- movl %eax,%ecx
- call __hyp_set_debugreg
-#else /* MACH_RING1 */
- movl %eax, %db0
-#endif /* MACH_RING1 */
- movl $0, %ecx
- jmp 0f
-ENTRY(dr1)
- movl S_ARG0, %eax
- movl %eax,EXT(dr_addr)+1*4
-#ifdef MACH_RING1
- pushl %ebx
- movl $1,%ebx
- movl %eax,%ecx
- call __hyp_set_debugreg
-#else /* MACH_RING1 */
- movl %eax, %db1
-#endif /* MACH_RING1 */
- movl $2, %ecx
- jmp 0f
-ENTRY(dr2)
- movl S_ARG0, %eax
- movl %eax,EXT(dr_addr)+2*4
-#ifdef MACH_RING1
- pushl %ebx
- movl $2,%ebx
- movl %eax,%ecx
- call __hyp_set_debugreg
-#else /* MACH_RING1 */
- movl %eax, %db2
-#endif /* MACH_RING1 */
- movl $4, %ecx
- jmp 0f
-
-ENTRY(dr3)
- movl S_ARG0, %eax
- movl %eax,EXT(dr_addr)+3*4
-#ifdef MACH_RING1
- pushl %ebx
- movl $3,%ebx
- movl %eax,%ecx
- call __hyp_set_debugreg
-#else /* MACH_RING1 */
- movl %eax, %db3
-#endif /* MACH_RING1 */
- movl $6, %ecx
-
-0:
- pushl %ebp
- movl %esp, %ebp
-
-#ifdef MACH_RING1
- movl $7,%ebx
- call __hyp_get_debugreg
- movl %eax, %edx
-#else /* MACH_RING1 */
- movl %db7, %edx
-#endif /* MACH_RING1 */
- movl %edx,EXT(dr_addr)+4*4
- andl dr_msk(,%ecx,2),%edx /* clear out new entry */
- movl %edx,EXT(dr_addr)+5*4
- movzbl B_ARG3, %eax
- andb $3, %al
- shll %cl, %eax
- orl %eax, %edx
-
- movzbl B_ARG1, %eax
- andb $3, %al
- addb %cl, %cl
- addb $0x10, %cl
- shll %cl, %eax
- orl %eax, %edx
-
- movzbl B_ARG2, %eax
- andb $3, %al
- addb $0x2, %cl
- shll %cl, %eax
- orl %eax, %edx
-
-#ifdef MACH_RING1
- movl $7,%ebx
- movl %edx, %ecx
- call __hyp_set_debugreg
- popl %ebx
-#else /* MACH_RING1 */
- movl %edx, %db7
-#endif /* MACH_RING1 */
- movl %edx,EXT(dr_addr)+7*4
- movl %edx, %eax
- leave
- ret
-
- .data
-dr_msk:
- .long ~0x000f0003
- .long ~0x00f0000c
- .long ~0x0f000030
- .long ~0xf00000c0
-ENTRY(dr_addr)
- .long 0,0,0,0
- .long 0,0,0,0
- .text
-
/*
* cpu_shutdown()
* Force reboot