- Timestamp:
- Oct 4, 2018 1:24:24 PM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/PC/BIOS/system.c
r71423 r74612 85 85 */ 86 86 87 void pm_stack_save(uint16_t cx, uint16_t es, uint16_t si , uint16_t frame);87 void pm_stack_save(uint16_t cx, uint16_t es, uint16_t si); 88 88 #pragma aux pm_stack_save = \ 89 89 ".386" \ 90 90 "push ds" \ 91 91 "push eax" \ 92 "xor eax, eax"\92 "xor ax, ax" \ 93 93 "mov ds, ax" \ 94 94 "mov ds:[467h], sp" \ 95 95 "mov ds:[469h], ss" \ 96 parm [cx] [es] [si] [ax] modify nomemory; 97 98 /* Uses position independent code... because it was too hard to figure 99 * out how to code the far call in inline assembler. 96 parm [cx] [es] [si] modify nomemory; 97 98 /* Uses position independent code to build a far return... because it was 99 * too hard to figure out how to code the far call in inline assembler. 100 * 101 * NB: It would be lovely to do 'add [sp],N' instead of 'pop ax; add ax,M; 102 * push ax'. Unfortunately the former cannot be encoded, though 'add [esp],N' 103 * can be on 386 and later -- but it may be unwise to assume that the high 104 * bits of ESP are all zero. 100 105 */ 101 106 void pm_enter(void); 102 107 #pragma aux pm_enter = \ 103 108 ".386p" \ 109 "lgdt fword ptr es:[si+8]" \ 110 "lidt fword ptr cs:pmode_IDT" \ 111 "push 20h" \ 104 112 "call pentry" \ 105 113 "pentry:" \ 106 114 "pop ax" \ 107 "add ax, 1Bh" \ 108 "push 20h" \ 115 "add ax, 0Eh" \ 109 116 "push ax" \ 110 "lgdt fword ptr es:[si+8]" \111 "lidt fword ptr cs:pmode_IDT" \112 117 "mov eax, cr0" \ 113 118 "or al, 1" \ … … 115 120 "retf" \ 116 121 "pm_pm:" \ 117 "mov ax, 28h" \118 "mov ss, ax" \119 122 "mov ax, 10h" \ 120 123 "mov ds, ax" \ 121 " mov ax, 18h" \124 "add al, 08h" \ 122 125 "mov es, ax" \ 126 "add al, 10h" \ 127 "mov ss, ax" \ 123 128 modify nomemory; 124 129 … … 129 134 #pragma aux pm_exit = \ 130 135 ".386p" \ 136 "mov ax, 28h" \ 137 "mov ds, ax" \ 138 "mov es, ax" \ 139 "push 0F000h" \ 131 140 "call pexit" \ 132 141 "pexit:" \ 133 142 "pop ax" \ 134 "push 0F000h" \ 135 "add ax, 18h" \ 143 "add ax, 0Eh" \ 136 144 "push ax" \ 137 "mov ax, 28h" \138 "mov ds, ax" \139 "mov es, ax" \140 145 "mov eax, cr0" \ 141 146 "and al, 0FEh" \ … … 176 181 /* Uses position independent code... because it was too hard to figure 177 182 * out how to code the far call in inline assembler. 178 * NB: Trashes MSW bits but the CPU will be reset anyway.179 183 */ 180 184 void pm_enter(void); 181 185 #pragma aux pm_enter = \ 182 186 ".286p" \ 187 "lgdt fword ptr es:[si+8]" \ 188 "lidt fword ptr cs:pmode_IDT" \ 189 "push 20h" \ 183 190 "call pentry" \ 184 191 "pentry:" \ 185 "pop di" \ 186 "add di, 18h" \ 187 "push 20h" \ 188 "push di" \ 189 "lgdt fword ptr es:[si+8]" \ 190 "lidt fword ptr cs:pmode_IDT" \ 192 "pop ax" \ 193 "add ax, 0Eh" \ 194 "push ax" \ 195 "smsw ax" \ 191 196 "or al, 1" \ 192 197 "lmsw ax" \ 193 198 "retf" \ 194 199 "pm_pm:" \ 195 "mov ax, 28h" \196 "mov ss, ax" \197 200 "mov ax, 10h" \ 198 201 "mov ds, ax" \ 199 " mov ax, 18h" \202 "add al, 08h" \ 200 203 "mov es, ax" \ 204 "add al, 10h" \ 205 "mov ss, ax" \ 201 206 modify nomemory; 202 207 … … 227 232 #endif 228 233 234 /* NB: CX is set earlier in pm_stack_save */ 229 235 void pm_copy(void); 230 236 #pragma aux pm_copy = \ … … 233 239 "cld" \ 234 240 "rep movsw" \ 235 modify [ di] nomemory;241 modify [si di cx] nomemory; 236 242 237 243 /* The pm_switch has a few crucial differences from pm_enter, hence … … 241 247 #pragma aux pm_switch = \ 242 248 ".286p" \ 249 "lgdt fword ptr es:[si+08h]" \ 250 "lidt fword ptr es:[si+10h]" \ 251 "push 38h" \ 243 252 "call pentry" \ 244 253 "pentry:" \ 245 "pop di" \ 246 "add di, 18h" \ 247 "push 38h" \ 248 "push di" \ 249 "lgdt fword ptr es:[si+08h]" \ 250 "lidt fword ptr es:[si+10h]" \ 251 "mov ax, 1" \ 254 "pop ax" \ 255 "add ax, 0Eh" \ 256 "push ax" \ 257 "smsw ax" \ 258 "or al, 1" \ 252 259 "lmsw ax" \ 253 260 "retf" \ 254 261 "pm_pm:" \ 255 "mov ax, 28h" \256 "mov ss, ax" \257 262 "mov ax, 18h" \ 258 263 "mov ds, ax" \ 259 " mov ax, 20h" \264 "add al, 08h" \ 260 265 "mov es, ax" \ 266 "add al, 08h" \ 267 "mov ss, ax" \ 261 268 parm [si] modify nomemory; 262 269 … … 861 868 // ============================================== 862 869 // 00..07 Unused zeros Null descriptor 863 // 08..0f GDT zeros filled inby BIOS870 // 08..0f scratch zeros work area used by BIOS 864 871 // 10..17 source ssssssss source of data 865 872 // 18..1f dest dddddddd destination of data … … 902 909 write_word(ES, SI+0x28+6, 0x0000); // base 31:24/reserved/limit 19:16 903 910 911 #if VBOX_BIOS_CPU >= 80386 912 /* Not taking the address of the parameter allows the code generator 913 * produce slightly better code for some unknown reason. 914 */ 915 pm_stack_save(CX, ES, SI); 916 #else 904 917 pm_stack_save(CX, ES, SI, FP_OFF(&r)); 918 #endif 905 919 pm_enter(); 906 920 pm_copy();
Note:
See TracChangeset
for help on using the changeset viewer.