summaryrefslogtreecommitdiffstats
path: root/src/arch/i386/core/virtaddr.S
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/i386/core/virtaddr.S')
-rw-r--r--src/arch/i386/core/virtaddr.S62
1 files changed, 52 insertions, 10 deletions
diff --git a/src/arch/i386/core/virtaddr.S b/src/arch/i386/core/virtaddr.S
index aae1e1edd..5e5d77352 100644
--- a/src/arch/i386/core/virtaddr.S
+++ b/src/arch/i386/core/virtaddr.S
@@ -36,6 +36,7 @@ _virt_to_phys:
addl %ebp, 12(%esp)
/* Switch to physical code segment */
+ cli
pushl $PHYSICAL_CS
leal 1f(%ebp), %eax
pushl %eax
@@ -44,10 +45,10 @@ _virt_to_phys:
/* Reload other segment registers and adjust %esp */
movl $PHYSICAL_DS, %eax
movl %eax, %ds
- movl %eax, %es
- movl %eax, %fs
+ movl %eax, %es
+ movl %eax, %fs
movl %eax, %gs
- movl %eax, %ss
+ movl %eax, %ss
addl %ebp, %esp
/* Restore registers and flags, and return */
@@ -64,9 +65,6 @@ _virt_to_phys:
* selectors. All other registers are preserved. Flags are
* preserved.
*
- * Note that this depends on the GDT already being correctly set up
- * (e.g. by a call to run_here()).
- *
* Parameters: none
* Returns: none
****************************************************************************
@@ -79,18 +77,19 @@ _phys_to_virt:
pushl %ebp
/* Switch to virtual code segment */
+ cli
ljmp $VIRTUAL_CS, $1f
-1:
+1:
/* Reload data segment registers */
movl $VIRTUAL_DS, %eax
movl %eax, %ds
- movl %eax, %es
- movl %eax, %fs
+ movl %eax, %es
+ movl %eax, %fs
movl %eax, %gs
/* Reload stack segment and adjust %esp */
movl virt_offset, %ebp
- movl %eax, %ss
+ movl %eax, %ss
subl %ebp, %esp
/* Change the return address to a virtual address */
@@ -101,3 +100,46 @@ _phys_to_virt:
popl %eax
popfl
ret
+
+/****************************************************************************
+ * _intr_to_virt (virtual code segment, virtual or physical stack segment)
+ *
+ * Switch from virtual code segment with either a virtual or physical
+ * stack segment to using virtual addressing. %esp is adjusted if
+ * necessary to a virtual value. Segment registers are set to virtual
+ * selectors. All other registers are preserved. Flags are
+ * preserved.
+ *
+ * Parameters: none
+ * Returns: none
+ ****************************************************************************
+ */
+ .globl _intr_to_virt
+_intr_to_virt:
+ /* Preserve registers and flags */
+ pushfl
+ pushl %eax
+ pushl %ebp
+
+ /* Check whether stack segment is physical or virtual */
+ movl %ss, %eax
+ cmpw $VIRTUAL_DS, %ax
+ movl $VIRTUAL_DS, %eax
+
+ /* Reload data segment registers */
+ movl %eax, %ds
+ movl %eax, %es
+ movl %eax, %fs
+ movl %eax, %gs
+
+ /* Reload stack segment and adjust %esp if necessary */
+ je 1f
+ movl virt_offset, %ebp
+ movl %eax, %ss
+ subl %ebp, %esp
+1:
+ /* Restore registers and flags, and return */
+ popl %ebp
+ popl %eax
+ popfl
+ ret