Changeset 17545 in vbox
- Timestamp:
- Mar 8, 2009 1:12:25 PM (16 years ago)
- Location:
- trunk/src/VBox/Devices/PC
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/PC/BIOS/rombios.c
r16537 r17545 2269 2269 #define ATA_TYPE_ATA 0x02 2270 2270 #define ATA_TYPE_ATAPI 0x03 2271 #ifdef VBOX 2271 2272 #define ATA_TYPE_SCSI 0x04 // SCSI disk 2273 #endif 2272 2274 2273 2275 #define ATA_DEVICE_NONE 0x00 … … 4225 4227 4226 4228 break; 4227 #endif 4229 #endif /* VBOX */ 4228 4230 4229 4231 case 0x90: … … 4597 4599 write_word(ES, DI, start); 4598 4600 write_word(ES, DI+2, start >> 16); 4599 write_word(ES, DI+4, 0x00); /** @todo r=bird: why write it twice? */4600 4601 write_word(ES, DI+4, extra_start); 4601 4602 write_word(ES, DI+6, 0x00); … … 4605 4606 write_word(ES, DI+8, end); 4606 4607 write_word(ES, DI+10, end >> 16); 4607 #ifdef VBOX 4608 if (end == 0) 4609 write_word(ES, DI+12, 0x0001); 4610 else 4611 /** @todo XXX: nike - is it really correct? see QEMU BIOS patch */ 4612 write_word(ES, DI+12, extra_end); 4613 #else /* !VBOX */ 4614 write_word(ES, DI+12, 0x0000); 4615 #endif /* !VBOX */ 4608 write_word(ES, DI+12, extra_end); 4616 4609 write_word(ES, DI+14, 0x0000); 4617 4610 … … 4626 4619 { 4627 4620 Bit32u extended_memory_size=0; // 64bits long 4628 #ifdef VBOX_WITH_MORE_THAN_4GB4629 4621 Bit32u extra_lowbits_memory_size=0; 4630 #endif4631 4622 Bit16u CX,DX; 4632 #ifdef VBOX_WITH_MORE_THAN_4GB4633 4623 Bit8u extra_highbits_memory_size=0; 4634 #endif4635 4624 4636 4625 BX_DEBUG_INT15("int15 AX=%04x\n",regs.u.r16.ax); … … 4692 4681 extended_memory_size |= inb_cmos(0x34); 4693 4682 extended_memory_size *= 64; 4683 #ifndef VBOX /* The following excludes 0xf0000000 thru 0xffffffff. Trust DevPcBios.cpp to get this right. */ 4694 4684 // greater than EFF00000??? 4695 4685 if(extended_memory_size > 0x3bc000) { 4696 4686 extended_memory_size = 0x3bc000; // everything after this is reserved memory until we get to 0x100000000 4697 4687 } 4688 #endif /* !VBOX */ 4698 4689 extended_memory_size *= 1024; 4699 4690 extended_memory_size += (16L * 1024 * 1024); … … 4704 4695 extended_memory_size |= inb_cmos(0x30); 4705 4696 extended_memory_size *= 1024; 4697 extended_memory_size += (1L * 1024 * 1024); 4706 4698 } 4707 4699 4708 #ifdef VBOX_WITH_MORE_THAN_4GB /* bird: later (btw. this ain't making sense complixity wise, unless its a AMI/AWARD/PHOENIX interface) */ 4709 extra_lowbits_memory_size = inb_cmos(0x61); 4700 #ifdef VBOX /* We've already used the CMOS entries for SATA. 4701 BTW. This is the amount of memory above 4GB measured in 64KB units. */ 4702 extra_lowbits_memory_size = inb_cmos(0x62); 4710 4703 extra_lowbits_memory_size <<= 8; 4711 extra_lowbits_memory_size |= inb_cmos(0x62); 4704 extra_lowbits_memory_size |= inb_cmos(0x61); 4705 extra_lowbits_memory_size <<= 16; 4706 extra_highbits_memory_size = inb_cmos(0x63); 4707 /* 0x64 and 0x65 can be used if we need to dig 1 TB or more at a later point. */ 4708 #else 4709 extra_lowbits_memory_size = inb_cmos(0x5c); 4710 extra_lowbits_memory_size <<= 8; 4711 extra_lowbits_memory_size |= inb_cmos(0x5b); 4712 4712 extra_lowbits_memory_size *= 64; 4713 4713 extra_lowbits_memory_size *= 1024; 4714 extra_highbits_memory_size = inb_cmos(0x 63);4715 #endif 4714 extra_highbits_memory_size = inb_cmos(0x5d); 4715 #endif /* !VBOX */ 4716 4716 4717 4717 switch(regs.u.r16.bx) … … 4719 4719 case 0: 4720 4720 set_e820_range(ES, regs.u.r16.di, 4721 #ifndef VBOX /** @todo Upstream sugggests the following, needs checking. (see next as well) */ 4722 0x0000000L, 0x0009f000L, 0, 0, 1); 4723 #else 4721 4724 0x0000000L, 0x0009fc00L, 0, 0, 1); 4725 #endif 4722 4726 regs.u.r32.ebx = 1; 4723 regs.u.r32.eax = 0x534D4150;4724 regs.u.r32.ecx = 0x14;4725 CLEAR_CF();4726 return;4727 4727 break; 4728 4728 case 1: 4729 4729 set_e820_range(ES, regs.u.r16.di, 4730 #ifndef VBOX /** @todo Upstream sugggests the following, needs checking. (see next as well) */ 4731 0x0009f000L, 0x000a0000L, 0, 0, 2); 4732 #else 4730 4733 0x0009fc00L, 0x000a0000L, 0, 0, 2); 4734 #endif 4731 4735 regs.u.r32.ebx = 2; 4732 regs.u.r32.eax = 0x534D4150;4733 regs.u.r32.ecx = 0x14;4734 CLEAR_CF();4735 return;4736 4736 break; 4737 4737 case 2: … … 4752 4752 #endif /* !VBOX */ 4753 4753 regs.u.r32.ebx = 3; 4754 regs.u.r32.eax = 0x534D4150;4755 regs.u.r32.ecx = 0x14;4756 CLEAR_CF();4757 return;4758 4754 break; 4759 4755 case 3: 4756 #if BX_ROMBIOS32 || defined(VBOX) 4760 4757 set_e820_range(ES, regs.u.r16.di, 4761 4758 0x00100000L, 4762 4759 extended_memory_size - ACPI_DATA_SIZE, 0, 0, 1); 4763 4760 regs.u.r32.ebx = 4; 4764 regs.u.r32.eax = 0x534D4150; 4765 regs.u.r32.ecx = 0x14; 4766 CLEAR_CF(); 4767 return; 4761 #else 4762 set_e820_range(ES, regs.u.r16.di, 4763 0x00100000L, 4764 extended_memory_size, 1); 4765 regs.u.r32.ebx = 5; 4766 #endif 4768 4767 break; 4769 4768 case 4: … … 4772 4771 extended_memory_size, 0, 0, 3); // ACPI RAM 4773 4772 regs.u.r32.ebx = 5; 4774 regs.u.r32.eax = 0x534D4150;4775 regs.u.r32.ecx = 0x14;4776 CLEAR_CF();4777 return;4778 4773 break; 4779 4774 case 5: 4780 4775 /* 256KB BIOS area at the end of 4 GB */ 4776 #ifdef VBOX 4777 /* We don't set the end to 1GB here and rely on the 32-bit 4778 unsigned wrap around effect (0-0xfffc0000L). */ 4779 #endif 4781 4780 set_e820_range(ES, regs.u.r16.di, 4782 4781 0xfffc0000L, 0x00000000L, 0, 0, 2); 4783 #ifdef VBOX_WITH_MORE_THAN_4GB4784 4782 if (extra_highbits_memory_size || extra_lowbits_memory_size) 4785 4783 regs.u.r32.ebx = 6; 4786 4784 else 4787 #endif4788 4785 regs.u.r32.ebx = 0; 4789 regs.u.r32.eax = 0x534D4150; 4790 regs.u.r32.ecx = 0x14; 4791 CLEAR_CF(); 4792 return; 4793 #ifdef VBOX_WITH_MORE_THAN_4GB 4786 break; 4794 4787 case 6: 4795 /* Mapping of memory above 4 GB */ 4796 set_e820_range(ES, regs.u.r16.di, 4797 0x00000000L, extra_lowbits_memory_size, 4798 1, extra_highbits_memory_size + 1, 1); 4788 #ifdef VBOX /* Don't succeeded if no memory above 4 GB. */ 4789 /* Mapping of memory above 4 GB if present. 4790 Note: set_e820_range needs do no borrowing in the 4791 subtraction because of the nice numbers. */ 4792 if (extra_highbits_memory_size || extra_lowbits_memory_size) 4793 { 4794 set_e820_range(ES, regs.u.r16.di, 4795 0x00000000L, extra_lowbits_memory_size, 4796 1 /*GB*/, extra_highbits_memory_size + 1 /*GB*/, 1); 4797 regs.u.r32.ebx = 0; 4798 break; 4799 } 4800 /* fall thru */ 4801 #else /* !VBOX */ 4802 /* Maping of memory above 4 GB */ 4803 set_e820_range(ES, regs.u.r16.di, 0x00000000L, 4804 extra_lowbits_memory_size, 1, extra_highbits_memory_size 4805 + 1, 1); 4799 4806 regs.u.r32.ebx = 0; 4800 regs.u.r32.eax = 0x534D4150; 4801 regs.u.r32.ecx = 0x14; 4802 CLEAR_CF(); 4803 return; 4804 #endif 4807 break; 4808 #endif /* !VBOX */ 4805 4809 default: /* AX=E820, DX=534D4150, BX unrecognized */ 4806 4810 goto int15_unimplemented; 4807 4811 break; 4808 4812 } 4813 regs.u.r32.eax = 0x534D4150; 4814 regs.u.r32.ecx = 0x14; 4815 CLEAR_CF(); 4809 4816 } else { 4810 4817 // if DX != 0x534D4150) -
trunk/src/VBox/Devices/PC/DevPcBios.cpp
r17542 r17545 90 90 Number of CPUs: 91 91 0x60 92 RAM above 4G (in 64 Munits):93 0x61 - 0x6 392 RAM above 4G (in 64KB units): 93 0x61 - 0x65 94 94 @endverbatim 95 95 * … … 526 526 * Memory sizes. 527 527 */ 528 #ifdef VBOX_WITH_MORE_THAN_4GB529 uint64_t cKBRam = pThis->cbRam / _1K;530 uint64_t cKBAbove4GB = 0;531 uint32_t cKBBelow4GB = cKBRam;532 AssertRelease(cKBBelow4GB == cKBRam);533 if (cKBRam > UINT32_C(0xe0000000)) /** @todo this limit must be picked up from CFGM and coordinated with MM/PGM! */534 {535 cKBAbove4GB = cKBRam - UINT32_C(0xe0000000);536 cKBBelow4GB = UINT32_C(0xe0000000);537 }538 else539 {540 cKBAbove4GB = 0;541 cKBBelow4GB = cKBRam;542 }543 544 /* base memory. */545 u32 = cKBBelow4GB > 640 ? 640 : cKBBelow4GB;546 pcbiosCmosWrite(pDevIns, 0x15, u32 & 0xff); /* 15h - Base Memory in K, Low Byte */547 pcbiosCmosWrite(pDevIns, 0x16, u32 >> 8); /* 16h - Base Memory in K, High Byte */548 549 /* Extended memory, up to 65MB */550 u32 = cKBBelow4GB >= 65 * _1K ? 0xffff : (cKBBelow4GB - _1K);551 pcbiosCmosWrite(pDevIns, 0x17, u32 & 0xff); /* 17h - Extended Memory in K, Low Byte */552 pcbiosCmosWrite(pDevIns, 0x18, u32 >> 8); /* 18h - Extended Memory in K, High Byte */553 pcbiosCmosWrite(pDevIns, 0x30, u32 & 0xff); /* 30h - Extended Memory in K, Low Byte */554 pcbiosCmosWrite(pDevIns, 0x31, u32 >> 8); /* 31h - Extended Memory in K, High Byte */555 556 /* Bochs BIOS specific? Anyway, it's the amount of memory above 16MB */557 if (cKBBelow4GB > 16 * _1K)558 {559 u32 = (uint32_t)( (cKBBelow4GB - 16 * _1K) / 64 );560 u32 = RT_MIN(u32, 0xffff);561 }562 else563 u32 = 0;564 pcbiosCmosWrite(pDevIns, 0x34, u32 & 0xff);565 pcbiosCmosWrite(pDevIns, 0x35, u32 >> 8);566 567 /* RAM above 4G, in 64MB units (needs discussing, see comments and @todos elsewhere). */568 pcbiosCmosWrite(pDevIns, 0x61, cKBAbove4GB >> 16);569 pcbiosCmosWrite(pDevIns, 0x62, cKBAbove4GB >> 24);570 pcbiosCmosWrite(pDevIns, 0x63, cKBAbove4GB >> 32);571 572 #else /* old code. */573 528 /* base memory. */ 574 529 u32 = pThis->cbRam > 640 ? 640 : (uint32_t)pThis->cbRam / _1K; /* <-- this test is wrong, but it doesn't matter since we never assign less than 1MB */ … … 584 539 585 540 /* Bochs BIOS specific? Anyway, it's the amount of memory above 16MB 586 and below 4GB (as it can only hold 4GB+16M). */ 541 and below 4GB (as it can only hold 4GB+16M). For 0E820h to work right, 542 this has to indicate less than 0xfffc0000 bytes or it'll conflict with 543 the high BIOS area. */ 587 544 uint64_t const offRamHole = _4G - pThis->cbRamHole; 588 545 if (pThis->cbRam > 16 * _1M) 589 546 { 590 547 u32 = (uint32_t)( (RT_MIN(pThis->cbRam, offRamHole) - 16 * _1M) / _64K ); 591 u32 = RT_MIN(u32, 0xf fff);548 u32 = RT_MIN(u32, 0xfefc); 592 549 } 593 550 else … … 596 553 pcbiosCmosWrite(pDevIns, 0x35, u32 >> 8); 597 554 598 # if 0 /** @todo Report the amount above 4GB and make sure the BIOS is only using 34/35 for the bits below 4GB. */ 599 /* Suggestion: MBs above 4GB, reserve 4 CMOS entries (need 3 now), means a600 total around 2**52 bytes or 4EB if you like. The max of what601 AMD64 is currently specified for IIRC. */555 /* Bochs/VBox BIOS specific way of specifying memory above 4GB in 64KB units. 556 Bochs got these in a different location which we've already used for SATA, 557 it also lacks the last two. */ 558 uint64_t c64KBAbove4GB; 602 559 if (pThis->cbRam <= offRamHole) 603 u32= 0;560 c64KBAbove4GB = 0; 604 561 else 605 562 { 606 u32 = (pThis->cbRam - offRamHole) / _1M;607 AssertMsg((uint64_t)u32 * _1M + offRamHole == pThis->cbRam, ("%RX64 %RX64\n", pThis->cbRam, offRamHole));608 }609 pcbiosCmosWrite(pDevIns, 0xY0, u32 & 0xff);610 pcbiosCmosWrite(pDevIns, 0x Y1, (u32 >> 8)& 0xff);611 pcbiosCmosWrite(pDevIns, 0x Y2, (u32 >> 16) & 0xff);612 pcbiosCmosWrite(pDevIns, 0x Y3, u32 >> 24);613 # endif 614 #endif /* old code */ 563 c64KBAbove4GB = (pThis->cbRam - offRamHole) / _64K; 564 /* Make sure it doesn't hit the limits of the current BIOS code. */ 565 AssertLogRelMsgReturn((c64KBAbove4GB >> (3 * 8)) < 255, ("%#RX64\n", c64KBAbove4GB), VERR_OUT_OF_RANGE); 566 } 567 pcbiosCmosWrite(pDevIns, 0x61, c64KBAbove4GB & 0xff); 568 pcbiosCmosWrite(pDevIns, 0x62, (c64KBAbove4GB >> 8) & 0xff); 569 pcbiosCmosWrite(pDevIns, 0x63, (c64KBAbove4GB >> 16) & 0xff); 570 pcbiosCmosWrite(pDevIns, 0x64, (c64KBAbove4GB >> 24) & 0xff); 571 pcbiosCmosWrite(pDevIns, 0x65, (c64KBAbove4GB >> 32) & 0xff); 615 572 616 573 /*
Note:
See TracChangeset
for help on using the changeset viewer.