david/ipxe
david
/
ipxe
Archived
1
0
Fork 0
This repository has been archived on 2020-12-06. You can view files and clone it, but cannot push or open issues or pull requests.
ipxe/src/arch/i386/core/virtaddr.S

146 lines
3.2 KiB
ArmAsm

/*
* Functions to support the virtual addressing method of relocation
* that Etherboot uses.
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
#include "librm.h"
.arch i386
.text
.code32
/****************************************************************************
* _virt_to_phys (virtual addressing)
*
* Switch from virtual to flat physical addresses. %esp is adjusted
* to a physical value. Segment registers are set to flat physical
* selectors. All other registers are preserved. Flags are
* preserved.
*
* Parameters: none
* Returns: none
****************************************************************************
*/
.globl _virt_to_phys
_virt_to_phys:
/* Preserve registers and flags */
pushfl
pushl %eax
pushl %ebp
/* Change return address to a physical address */
movl virt_offset, %ebp
addl %ebp, 12(%esp)
/* Switch to physical code segment */
cli
pushl $PHYSICAL_CS
leal 1f(%ebp), %eax
pushl %eax
lret
1:
/* Reload other segment registers and adjust %esp */
movl $PHYSICAL_DS, %eax
movl %eax, %ds
movl %eax, %es
movl %eax, %fs
movl %eax, %gs
movl %eax, %ss
addl %ebp, %esp
/* Restore registers and flags, and return */
popl %ebp
popl %eax
popfl
ret
/****************************************************************************
* _phys_to_virt (flat physical addressing)
*
* Switch from flat physical to virtual addresses. %esp is adjusted
* to a virtual value. Segment registers are set to virtual
* selectors. All other registers are preserved. Flags are
* preserved.
*
* Parameters: none
* Returns: none
****************************************************************************
*/
.globl _phys_to_virt
_phys_to_virt:
/* Preserve registers and flags */
pushfl
pushl %eax
pushl %ebp
/* Switch to virtual code segment */
cli
ljmp $VIRTUAL_CS, $1f
1:
/* Reload data segment registers */
movl $VIRTUAL_DS, %eax
movl %eax, %ds
movl %eax, %es
movl %eax, %fs
movl %eax, %gs
/* Reload stack segment and adjust %esp */
movl virt_offset, %ebp
movl %eax, %ss
subl %ebp, %esp
/* Change the return address to a virtual address */
subl %ebp, 12(%esp)
/* Restore registers and flags, and return */
popl %ebp
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