Initial code release
[external/syslinux.git] / gpxe / src / arch / i386 / core / virtaddr.S
1 /*
2  * Functions to support the virtual addressing method of relocation
3  * that Etherboot uses.
4  *
5  */
6
7 FILE_LICENCE ( GPL2_OR_LATER )
8
9 #include "librm.h"
10                 
11         .arch i386
12         .text
13         .code32
14         
15 /****************************************************************************
16  * _virt_to_phys (virtual addressing)
17  *
18  * Switch from virtual to flat physical addresses.  %esp is adjusted
19  * to a physical value.  Segment registers are set to flat physical
20  * selectors.  All other registers are preserved.  Flags are
21  * preserved.
22  *
23  * Parameters: none
24  * Returns: none
25  ****************************************************************************
26  */
27         .globl _virt_to_phys
28 _virt_to_phys:
29         /* Preserve registers and flags */
30         pushfl
31         pushl   %eax
32         pushl   %ebp
33
34         /* Change return address to a physical address */
35         movl    virt_offset, %ebp
36         addl    %ebp, 12(%esp)
37
38         /* Switch to physical code segment */
39         pushl   $PHYSICAL_CS
40         leal    1f(%ebp), %eax
41         pushl   %eax
42         lret
43 1:
44         /* Reload other segment registers and adjust %esp */
45         movl    $PHYSICAL_DS, %eax
46         movl    %eax, %ds
47         movl    %eax, %es       
48         movl    %eax, %fs       
49         movl    %eax, %gs
50         movl    %eax, %ss       
51         addl    %ebp, %esp
52
53         /* Restore registers and flags, and return */
54         popl    %ebp
55         popl    %eax
56         popfl
57         ret
58
59 /****************************************************************************
60  * _phys_to_virt (flat physical addressing)
61  *
62  * Switch from flat physical to virtual addresses.  %esp is adjusted
63  * to a virtual value.  Segment registers are set to virtual
64  * selectors.  All other registers are preserved.  Flags are
65  * preserved.
66  *
67  * Note that this depends on the GDT already being correctly set up
68  * (e.g. by a call to run_here()).
69  *
70  * Parameters: none
71  * Returns: none
72  ****************************************************************************
73  */
74         .globl _phys_to_virt
75 _phys_to_virt:
76         /* Preserve registers and flags */
77         pushfl
78         pushl   %eax
79         pushl   %ebp
80
81         /* Switch to virtual code segment */
82         ljmp    $VIRTUAL_CS, $1f
83 1:      
84         /* Reload data segment registers */
85         movl    $VIRTUAL_DS, %eax
86         movl    %eax, %ds
87         movl    %eax, %es       
88         movl    %eax, %fs       
89         movl    %eax, %gs
90
91         /* Reload stack segment and adjust %esp */
92         movl    virt_offset, %ebp
93         movl    %eax, %ss       
94         subl    %ebp, %esp
95
96         /* Change the return address to a virtual address */
97         subl    %ebp, 12(%esp)
98
99         /* Restore registers and flags, and return */
100         popl    %ebp
101         popl    %eax
102         popfl
103         ret