Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / ipxe / 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         cli
40         pushl   $PHYSICAL_CS
41         leal    1f(%ebp), %eax
42         pushl   %eax
43         lret
44 1:
45         /* Reload other segment registers and adjust %esp */
46         movl    $PHYSICAL_DS, %eax
47         movl    %eax, %ds
48         movl    %eax, %es
49         movl    %eax, %fs
50         movl    %eax, %gs
51         movl    %eax, %ss
52         addl    %ebp, %esp
53
54         /* Restore registers and flags, and return */
55         popl    %ebp
56         popl    %eax
57         popfl
58         ret
59
60 /****************************************************************************
61  * _phys_to_virt (flat physical addressing)
62  *
63  * Switch from flat physical to virtual addresses.  %esp is adjusted
64  * to a virtual value.  Segment registers are set to virtual
65  * selectors.  All other registers are preserved.  Flags are
66  * preserved.
67  *
68  * Parameters: none
69  * Returns: none
70  ****************************************************************************
71  */
72         .globl _phys_to_virt
73 _phys_to_virt:
74         /* Preserve registers and flags */
75         pushfl
76         pushl   %eax
77         pushl   %ebp
78
79         /* Switch to virtual code segment */
80         cli
81         ljmp    $VIRTUAL_CS, $1f
82 1:
83         /* Reload data segment registers */
84         movl    $VIRTUAL_DS, %eax
85         movl    %eax, %ds
86         movl    %eax, %es
87         movl    %eax, %fs
88         movl    %eax, %gs
89
90         /* Reload stack segment and adjust %esp */
91         movl    virt_offset, %ebp
92         movl    %eax, %ss
93         subl    %ebp, %esp
94
95         /* Change the return address to a virtual address */
96         subl    %ebp, 12(%esp)
97
98         /* Restore registers and flags, and return */
99         popl    %ebp
100         popl    %eax
101         popfl
102         ret
103
104 /****************************************************************************
105  * _intr_to_virt (virtual code segment, virtual or physical stack segment)
106  *
107  * Switch from virtual code segment with either a virtual or physical
108  * stack segment to using virtual addressing.  %esp is adjusted if
109  * necessary to a virtual value.  Segment registers are set to virtual
110  * selectors.  All other registers are preserved.  Flags are
111  * preserved.
112  *
113  * Parameters: none
114  * Returns: none
115  ****************************************************************************
116  */
117         .globl _intr_to_virt
118 _intr_to_virt:
119         /* Preserve registers and flags */
120         pushfl
121         pushl   %eax
122         pushl   %ebp
123
124         /* Check whether stack segment is physical or virtual */
125         movl    %ss, %eax
126         cmpw    $VIRTUAL_DS, %ax
127         movl    $VIRTUAL_DS, %eax
128
129         /* Reload data segment registers */
130         movl    %eax, %ds
131         movl    %eax, %es
132         movl    %eax, %fs
133         movl    %eax, %gs
134
135         /* Reload stack segment and adjust %esp if necessary */
136         je      1f
137         movl    virt_offset, %ebp
138         movl    %eax, %ss
139         subl    %ebp, %esp
140 1:
141         /* Restore registers and flags, and return */
142         popl    %ebp
143         popl    %eax
144         popfl
145         ret