Changeset 60610 in vbox for trunk/src/VBox/Devices/PC/BIOS/system.c
- Timestamp:
- Apr 20, 2016 5:42:15 PM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/PC/BIOS/system.c
r59495 r60610 65 65 #pragma aux read_ss = "mov ax, ss" modify exact [ax] nomemory; 66 66 67 void pm_stack_save(uint16_t cx, uint16_t es, uint16_t si); 67 #if VBOX_BIOS_CPU >= 80386 68 69 /* The 386+ code uses CR0 to switch to/from protected mode. 70 * Quite straightforward. 71 */ 72 73 void pm_stack_save(uint16_t cx, uint16_t es, uint16_t si, uint16_t frame); 68 74 #pragma aux pm_stack_save = \ 69 75 ".386" \ … … 74 80 "mov ds:[467h], sp" \ 75 81 "mov ds:[469h], ss" \ 76 parm [cx] [es] [si] modify nomemory;82 parm [cx] [es] [si] [ax] modify nomemory; 77 83 78 84 /* Uses position independent code... because it was too hard to figure … … 103 109 modify nomemory; 104 110 105 void pm_copy(void);106 #pragma aux pm_copy = \107 "xor si, si" \108 "xor di, di" \109 "cld" \110 "rep movsw" \111 modify nomemory;112 113 111 /* Restore segment limits to real mode compatible values and 114 112 * return to real mode. … … 146 144 "pop eax" \ 147 145 "pop ds" \ 146 modify nomemory; 147 148 #elif VBOX_BIOS_CPU >= 80286 149 150 /* The 286 code uses LMSW to switch to protected mode but it has to reset 151 * the CPU to get back to real mode. Ugly! See return_blkmove in orgs.asm 152 * for the other matching half. 153 */ 154 void pm_stack_save(uint16_t cx, uint16_t es, uint16_t si, uint16_t frame); 155 #pragma aux pm_stack_save = \ 156 "xor ax, ax" \ 157 "mov ds, ax" \ 158 "mov ds:[467h], bx" \ 159 "mov ds:[469h], ss" \ 160 parm [cx] [es] [si] [bx] modify nomemory; 161 162 /* Uses position independent code... because it was too hard to figure 163 * out how to code the far call in inline assembler. 164 * NB: Trashes MSW bits but the CPU will be reset anyway. 165 */ 166 void pm_enter(void); 167 #pragma aux pm_enter = \ 168 ".286p" \ 169 "call pentry" \ 170 "pentry:" \ 171 "pop di" \ 172 "add di, 18h" \ 173 "push 20h" \ 174 "push di" \ 175 "lgdt fword ptr es:[si+8]" \ 176 "lidt fword ptr cs:pmode_IDT" \ 177 "or al, 1" \ 178 "lmsw ax" \ 179 "retf" \ 180 "pm_pm:" \ 181 "mov ax, 28h" \ 182 "mov ss, ax" \ 183 "mov ax, 10h" \ 184 "mov ds, ax" \ 185 "mov ax, 18h" \ 186 "mov es, ax" \ 187 modify nomemory; 188 189 /* Set up shutdown status and reset the CPU. The POST code 190 * will regain control. Port 80h is written with status. 191 * Code 9 is written to CMOS shutdown status byte (0Fh). 192 * CPU is triple faulted. . 193 */ 194 void pm_exit(void); 195 #pragma aux pm_exit = \ 196 "xor ax, ax" \ 197 "out 80h, al" \ 198 "mov al, 0Fh" \ 199 "out 70h, al" \ 200 "mov al, 09h" \ 201 "out 71h, al" \ 202 ".286p" \ 203 "lidt fword ptr cs:pmode_IDT" \ 204 "int 3" \ 205 modify nomemory; 206 207 /* Dummy. Actually done in return_blkmove. */ 208 void pm_stack_restore(void); 209 #pragma aux pm_stack_restore = \ 210 "rm_return:" \ 211 modify nomemory; 212 213 #endif 214 215 void pm_copy(void); 216 #pragma aux pm_copy = \ 217 "xor si, si" \ 218 "xor di, di" \ 219 "cld" \ 220 "rep movsw" \ 148 221 modify nomemory; 149 222 … … 283 356 void BIOSCALL int15_function(sys_regs_t r) 284 357 { 285 bx_bool prev_a20_enable;286 uint16_t base15_00;287 uint8_t base23_16;288 uint16_t ss;289 358 uint16_t bRegister; 290 359 uint8_t irqDisable; … … 392 461 } 393 462 394 case 0x87:395 #if BX_CPU < 3396 SET_AH(UNSUPPORTED_FUNCTION);397 SET_CF();398 #endif399 // +++ should probably have descriptor checks400 // +++ should have exception handlers401 402 // turn off interrupts403 int_disable(); //@todo: aren't they disabled already?404 405 prev_a20_enable = set_enable_a20(1); // enable A20 line406 407 // 128K max of transfer on 386+ ???408 // source == destination ???409 410 // ES:SI points to descriptor table411 // offset use initially comments412 // ==============================================413 // 00..07 Unused zeros Null descriptor414 // 08..0f GDT zeros filled in by BIOS415 // 10..17 source ssssssss source of data416 // 18..1f dest dddddddd destination of data417 // 20..27 CS zeros filled in by BIOS418 // 28..2f SS zeros filled in by BIOS419 420 //es:si421 //eeee0422 //0ssss423 //-----424 425 // check for access rights of source & dest here426 427 // Initialize GDT descriptor428 base15_00 = (ES << 4) + SI;429 base23_16 = ES >> 12;430 if (base15_00 < (ES<<4))431 base23_16++;432 write_word(ES, SI+0x08+0, 47); // limit 15:00 = 6 * 8bytes/descriptor433 write_word(ES, SI+0x08+2, base15_00);// base 15:00434 write_byte(ES, SI+0x08+4, base23_16);// base 23:16435 write_byte(ES, SI+0x08+5, 0x93); // access436 write_word(ES, SI+0x08+6, 0x0000); // base 31:24/reserved/limit 19:16437 438 // Initialize CS descriptor439 write_word(ES, SI+0x20+0, 0xffff);// limit 15:00 = normal 64K limit440 write_word(ES, SI+0x20+2, 0x0000);// base 15:00441 write_byte(ES, SI+0x20+4, 0x000f);// base 23:16442 write_byte(ES, SI+0x20+5, 0x9b); // access443 write_word(ES, SI+0x20+6, 0x0000);// base 31:24/reserved/limit 19:16444 445 // Initialize SS descriptor446 ss = read_ss();447 base15_00 = ss << 4;448 base23_16 = ss >> 12;449 write_word(ES, SI+0x28+0, 0xffff); // limit 15:00 = normal 64K limit450 write_word(ES, SI+0x28+2, base15_00);// base 15:00451 write_byte(ES, SI+0x28+4, base23_16);// base 23:16452 write_byte(ES, SI+0x28+5, 0x93); // access453 write_word(ES, SI+0x28+6, 0x0000); // base 31:24/reserved/limit 19:16454 455 pm_stack_save(CX, ES, SI);456 pm_enter();457 pm_copy();458 pm_exit();459 pm_stack_restore();460 461 set_enable_a20(prev_a20_enable);462 463 // turn interrupts back on464 int_enable();465 466 SET_AH(0);467 CLEAR_CF();468 break;469 470 463 case 0x88: 471 464 // Get the amount of extended memory (above 1M) … … 830 823 } 831 824 } 825 826 #if VBOX_BIOS_CPU >= 80286 827 828 #undef FLAGS 829 #define FLAGS r.ra.flags.u.r16.flags 830 831 /* Function 0x87 handled separately due to specific stack layout requirements. */ 832 void BIOSCALL int15_blkmove(disk_regs_t r) 833 { 834 bx_bool prev_a20_enable; 835 uint16_t base15_00; 836 uint8_t base23_16; 837 uint16_t ss; 838 839 // +++ should probably have descriptor checks 840 // +++ should have exception handlers 841 842 // turn off interrupts 843 int_disable(); //@todo: aren't they disabled already? 844 845 prev_a20_enable = set_enable_a20(1); // enable A20 line 846 847 // 128K max of transfer on 386+ ??? 848 // source == destination ??? 849 850 // ES:SI points to descriptor table 851 // offset use initially comments 852 // ============================================== 853 // 00..07 Unused zeros Null descriptor 854 // 08..0f GDT zeros filled in by BIOS 855 // 10..17 source ssssssss source of data 856 // 18..1f dest dddddddd destination of data 857 // 20..27 CS zeros filled in by BIOS 858 // 28..2f SS zeros filled in by BIOS 859 860 //es:si 861 //eeee0 862 //0ssss 863 //----- 864 865 // check for access rights of source & dest here 866 867 // Initialize GDT descriptor 868 base15_00 = (ES << 4) + SI; 869 base23_16 = ES >> 12; 870 if (base15_00 < (ES<<4)) 871 base23_16++; 872 write_word(ES, SI+0x08+0, 47); // limit 15:00 = 6 * 8bytes/descriptor 873 write_word(ES, SI+0x08+2, base15_00);// base 15:00 874 write_byte(ES, SI+0x08+4, base23_16);// base 23:16 875 write_byte(ES, SI+0x08+5, 0x93); // access 876 write_word(ES, SI+0x08+6, 0x0000); // base 31:24/reserved/limit 19:16 877 878 // Initialize CS descriptor 879 write_word(ES, SI+0x20+0, 0xffff);// limit 15:00 = normal 64K limit 880 write_word(ES, SI+0x20+2, 0x0000);// base 15:00 881 write_byte(ES, SI+0x20+4, 0x000f);// base 23:16 882 write_byte(ES, SI+0x20+5, 0x9b); // access 883 write_word(ES, SI+0x20+6, 0x0000);// base 31:24/reserved/limit 19:16 884 885 // Initialize SS descriptor 886 ss = read_ss(); 887 base15_00 = ss << 4; 888 base23_16 = ss >> 12; 889 write_word(ES, SI+0x28+0, 0xffff); // limit 15:00 = normal 64K limit 890 write_word(ES, SI+0x28+2, base15_00);// base 15:00 891 write_byte(ES, SI+0x28+4, base23_16);// base 23:16 892 write_byte(ES, SI+0x28+5, 0x93); // access 893 write_word(ES, SI+0x28+6, 0x0000); // base 31:24/reserved/limit 19:16 894 895 pm_stack_save(CX, ES, SI, (uint16_t)(void __near *)&r); 896 pm_enter(); 897 pm_copy(); 898 pm_exit(); 899 pm_stack_restore(); 900 901 set_enable_a20(prev_a20_enable); 902 903 // turn interrupts back on 904 int_enable(); 905 906 SET_AH(0); 907 CLEAR_CF(); 908 } 909 #endif
Note:
See TracChangeset
for help on using the changeset viewer.