summaryrefslogtreecommitdiff
path: root/i386/pc/rv86/rv86_reflect_irq.S
diff options
context:
space:
mode:
Diffstat (limited to 'i386/pc/rv86/rv86_reflect_irq.S')
-rw-r--r--i386/pc/rv86/rv86_reflect_irq.S113
1 files changed, 113 insertions, 0 deletions
diff --git a/i386/pc/rv86/rv86_reflect_irq.S b/i386/pc/rv86/rv86_reflect_irq.S
new file mode 100644
index 0000000..5d68fae
--- /dev/null
+++ b/i386/pc/rv86/rv86_reflect_irq.S
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 1995 The University of Utah and
+ * the Computer Systems Laboratory at the University of Utah (CSL).
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify and distribute this software is hereby
+ * granted provided that (1) source code retains these copyright, permission,
+ * and disclaimer notices, and (2) redistributions including binaries
+ * reproduce the notices in supporting documentation, and (3) all advertising
+ * materials mentioning features or use of this software display the following
+ * acknowledgement: ``This product includes software developed by the
+ * Computer Systems Laboratory at the University of Utah.''
+ *
+ * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS
+ * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF
+ * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * CSL requests users of this software to return to csl-dist@cs.utah.edu any
+ * improvements that they make and grant CSL redistribution rights.
+ *
+ * Author: Bryan Ford, University of Utah CSL
+ */
+
+#include <mach/machine/asm.h>
+#include <mach/machine/eflags.h>
+
+#include "trap.h"
+#include "trap_asm.h"
+#include "pc_asm.h"
+#include "i386_asm.h"
+
+/*
+ * Define a set of interrupt handlers to reflect interrupts to v86 mode.
+ */
+
+ .text
+
+#define master_base 0x08
+#define slave_base 0x70
+
+#define irq(pic,picnum,irqnum) \
+ENTRY(rv86_reflect_irq##irqnum) ;\
+ pushl $pic##_base+picnum ;\
+ pushl $0x80000000+irqnum /* (for debug) */ ;\
+ jmp allintrs
+
+#include "irq_list.h"
+
+
+allintrs:
+ pusha
+ pushl %ds
+ pushl %es
+ pushl %fs
+ pushl %gs
+
+ /* Load the normal kernel segment registers. */
+ movw %ss,%ax
+ movw %ax,%ds
+ movw %ax,%es
+
+ /* See if we came from v86 mode. */
+ testl $EFL_VM,TR_EFLAGS(%esp)
+ jnz int_from_v86
+
+ movl TR_ERR(%esp),%eax
+ pushl $dummy_rcd
+ pushl %eax
+ call EXT(rv86_real_int)
+ addl $2*4,%esp
+
+ popl %gs
+ popl %fs
+ popl %es
+ popl %ds
+ popa
+ addl $2*4,%esp
+ iret
+
+int_from_v86:
+
+ /* Save the v86 stack pointer before handling the interrupt.
+ We need this in order to handle recursive reflected interrupts
+ possibly interspersed with protected-mode interrupts. */
+ movl EXT(rv86_usp),%esi
+ movl EXT(rv86_usp)+4,%edi
+ movl EXT(real_tss)+TSS_ESP0,%ebx
+
+ movl TR_ESP(%esp),%eax
+ subw $6,%ax /* allocate a real-mode interrupt stack frame. */
+ movl %eax,EXT(rv86_usp)
+ movl TR_SS(%esp),%eax
+ movw %ax,EXT(rv86_usp)+4
+
+ movl TR_ERR(%esp),%eax
+ pushl $dummy_rcd
+ pushl %eax
+ call EXT(rv86_real_int)
+ addl $2*4,%esp
+
+ movl %esi,EXT(rv86_usp)
+ movl %edi,EXT(rv86_usp)+4
+ movl %ebx,EXT(real_tss)+TSS_ESP0
+
+ addl $4*4,%esp
+ popa
+ addl $2*4,%esp
+ iret
+
+ /* Dummy real_call_data structure (always all zero)
+ to use when reflecting hardware interrupts. */
+ .comm dummy_rcd,RCD_SIZE
+