+ movl _curpcb,%edx
+ movl $0,PCB_ONFAULT(%edx)
+ movl $EFAULT,%eax
+ ret
+
+ /*
+ * fu{byte,sword,word} : fetch a byte(sword, word) from user memory
+ */
+ALTENTRY(fuiword)
+ENTRY(fuword)
+ movl _curpcb,%ecx
+ movl $fusufault,PCB_ONFAULT(%ecx)
+ movl 4(%esp),%edx
+ gs
+ movl (%edx),%eax
+ movl $0,PCB_ONFAULT(%ecx)
+ ret
+
+ENTRY(fusword)
+ movl _curpcb,%ecx
+ movl $fusufault,PCB_ONFAULT(%ecx)
+ movl 4(%esp),%edx
+ gs
+ movzwl (%edx),%eax
+ movl $0,PCB_ONFAULT(%ecx)
+ ret
+
+ALTENTRY(fuibyte)
+ENTRY(fubyte)
+ movl _curpcb,%ecx
+ movl $fusufault,PCB_ONFAULT(%ecx)
+ movl 4(%esp),%edx
+ gs
+ movzbl (%edx),%eax
+ movl $0,PCB_ONFAULT(%ecx)
+ ret
+
+ ALIGN_TEXT
+fusufault:
+ movl _curpcb,%ecx
+ xorl %eax,%eax
+ movl %eax,PCB_ONFAULT(%ecx)
+ decl %eax
+ ret
+
+ /*
+ * su{byte,sword,word}: write a byte(word, longword) to user memory
+ */
+#ifdef USE_486_WRITE_PROTECT
+ /*
+ * we only have to set the right segment selector.
+ */
+ALTENTRY(suiword)
+ENTRY(suword)
+ movl _curpcb,%ecx
+ movl $fusufault,PCB_ONFAULT(%ecx)
+ movl 4(%esp),%edx
+ movl 8(%esp),%eax
+ gs
+ movl %eax,(%edx)
+ xorl %eax,%eax
+ movl %eax,PCB_ONFAULT(%ecx)
+ ret
+
+ENTRY(susword)
+ movl _curpcb,%ecx
+ movl $fusufault,PCB_ONFAULT(%ecx)
+ movl 4(%esp),%edx
+ movw 8(%esp),%ax
+ gs
+ movw %ax,(%edx)
+ xorl %eax,%eax
+ movl %eax,PCB_ONFAULT(%ecx)
+ ret
+
+ALTENTRY(suibyte)
+ENTRY(subyte)
+ movl _curpcb,%ecx
+ movl $fusufault,PCB_ONFAULT(%ecx)
+ movl 4(%esp),%edx
+ movb 8(%esp),%al
+ gs
+ movb %al,(%edx)
+ xorl %eax,%eax
+ movl %eax,PCB_ONFAULT(%ecx)
+ ret
+
+
+#else /* USE_486_WRITE_PROTECT */
+ /*
+ * here starts the trouble again: check PTE, twice if word crosses
+ * a page boundary.
+ */
+ /* XXX - page boundary crossing is not handled yet */
+
+ALTENTRY(suibyte)
+ENTRY(subyte)
+ movl _curpcb,%ecx
+ movl $fusufault,PCB_ONFAULT(%ecx)
+ movl 4(%esp),%edx
+ movl %edx,%eax
+ shrl $IDXSHIFT,%edx
+ andb $0xfc,%dl
+ movb _PTmap(%edx),%dl
+ andb $0x7,%dl /* must be VALID + USERACC + WRITE */
+ cmpb $0x7,%dl
+ je 1f
+ /* simulate a trap */
+ pushl %eax
+ call _trapwrite
+ popl %edx
+ orl %eax,%eax
+ jnz fusufault
+1:
+ movl 4(%esp),%edx
+ movl 8(%esp),%eax
+ gs
+ movb %al,(%edx)
+ xorl %eax,%eax
+ movl _curpcb,%ecx
+ movl %eax,PCB_ONFAULT(%ecx)
+ ret
+
+ENTRY(susword)
+ movl _curpcb,%ecx
+ movl $fusufault,PCB_ONFAULT(%ecx)
+ movl 4(%esp),%edx
+ movl %edx,%eax
+ shrl $IDXSHIFT,%edx
+ andb $0xfc,%dl
+ movb _PTmap(%edx),%dl
+ andb $0x7,%dl /* must be VALID + USERACC + WRITE */
+ cmpb $0x7,%dl
+ je 1f
+ /* simulate a trap */
+ pushl %eax
+ call _trapwrite
+ popl %edx
+ orl %eax,%eax
+ jnz fusufault
+1:
+ movl 4(%esp),%edx
+ movl 8(%esp),%eax
+ gs
+ movw %ax,(%edx)
+ xorl %eax,%eax
+ movl _curpcb,%ecx
+ movl %eax,PCB_ONFAULT(%ecx)
+ ret
+
+ALTENTRY(suiword)
+ENTRY(suword)
+ movl _curpcb,%ecx
+ movl $fusufault,PCB_ONFAULT(%ecx)
+ movl 4(%esp),%edx
+ movl %edx,%eax
+ shrl $IDXSHIFT,%edx
+ andb $0xfc,%dl
+ movb _PTmap(%edx),%dl
+ andb $0x7,%dl /* must be VALID + USERACC + WRITE */
+ cmpb $0x7,%dl
+ je 1f
+ /* simulate a trap */
+ pushl %eax
+ call _trapwrite
+ popl %edx
+ orl %eax,%eax
+ jnz fusufault
+1:
+ movl 4(%esp),%edx
+ movl 8(%esp),%eax
+ gs
+ movl %eax,0(%edx)