diff options
Diffstat (limited to 'src/arch/i386/core/virtaddr.S')
| -rw-r--r-- | src/arch/i386/core/virtaddr.S | 62 |
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 |
