VirtualBox

Changeset 17545 in vbox


Ignore:
Timestamp:
Mar 8, 2009 1:12:25 PM (16 years ago)
Author:
vboxsync
Message:

DevPcBios.cpp,rombios.c: 4GB changes, synced the 0E820 code with current bochs code.

Location:
trunk/src/VBox/Devices/PC
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/PC/BIOS/rombios.c

    r16537 r17545  
    22692269#define ATA_TYPE_ATA      0x02
    22702270#define ATA_TYPE_ATAPI    0x03
     2271#ifdef VBOX
    22712272#define ATA_TYPE_SCSI     0x04 // SCSI disk
     2273#endif
    22722274
    22732275#define ATA_DEVICE_NONE  0x00
     
    42254227
    42264228      break;
    4227 #endif
     4229#endif /* VBOX */
    42284230
    42294231    case 0x90:
     
    45974599    write_word(ES, DI, start);
    45984600    write_word(ES, DI+2, start >> 16);
    4599     write_word(ES, DI+4, 0x00); /** @todo r=bird: why write it twice? */
    46004601    write_word(ES, DI+4, extra_start);
    46014602    write_word(ES, DI+6, 0x00);
     
    46054606    write_word(ES, DI+8, end);
    46064607    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);
    46164609    write_word(ES, DI+14, 0x0000);
    46174610
     
    46264619{
    46274620  Bit32u  extended_memory_size=0; // 64bits long
    4628 #ifdef VBOX_WITH_MORE_THAN_4GB
    46294621  Bit32u  extra_lowbits_memory_size=0;
    4630 #endif
    46314622  Bit16u  CX,DX;
    4632 #ifdef VBOX_WITH_MORE_THAN_4GB
    46334623  Bit8u   extra_highbits_memory_size=0;
    4634 #endif
    46354624
    46364625BX_DEBUG_INT15("int15 AX=%04x\n",regs.u.r16.ax);
     
    46924681                extended_memory_size |= inb_cmos(0x34);
    46934682                extended_memory_size *= 64;
     4683#ifndef VBOX /* The following excludes 0xf0000000 thru 0xffffffff. Trust DevPcBios.cpp to get this right. */
    46944684                // greater than EFF00000???
    46954685                if(extended_memory_size > 0x3bc000) {
    46964686                    extended_memory_size = 0x3bc000; // everything after this is reserved memory until we get to 0x100000000
    46974687                }
     4688#endif /* !VBOX */
    46984689                extended_memory_size *= 1024;
    46994690                extended_memory_size += (16L * 1024 * 1024);
     
    47044695                    extended_memory_size |= inb_cmos(0x30);
    47054696                    extended_memory_size *= 1024;
     4697                    extended_memory_size += (1L * 1024 * 1024);
    47064698                }
    47074699
    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);
    47104703                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);
    47124712                extra_lowbits_memory_size *= 64;
    47134713                extra_lowbits_memory_size *= 1024;
    4714                 extra_highbits_memory_size = inb_cmos(0x63);
    4715 #endif
     4714                extra_highbits_memory_size = inb_cmos(0x5d);
     4715#endif /* !VBOX */
    47164716
    47174717                switch(regs.u.r16.bx)
     
    47194719                    case 0:
    47204720                        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
    47214724                                       0x0000000L, 0x0009fc00L, 0, 0, 1);
     4725#endif
    47224726                        regs.u.r32.ebx = 1;
    4723                         regs.u.r32.eax = 0x534D4150;
    4724                         regs.u.r32.ecx = 0x14;
    4725                         CLEAR_CF();
    4726                         return;
    47274727                        break;
    47284728                    case 1:
    47294729                        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
    47304733                                       0x0009fc00L, 0x000a0000L, 0, 0, 2);
     4734#endif
    47314735                        regs.u.r32.ebx = 2;
    4732                         regs.u.r32.eax = 0x534D4150;
    4733                         regs.u.r32.ecx = 0x14;
    4734                         CLEAR_CF();
    4735                         return;
    47364736                        break;
    47374737                    case 2:
     
    47524752#endif /* !VBOX */
    47534753                        regs.u.r32.ebx = 3;
    4754                         regs.u.r32.eax = 0x534D4150;
    4755                         regs.u.r32.ecx = 0x14;
    4756                         CLEAR_CF();
    4757                         return;
    47584754                        break;
    47594755                    case 3:
     4756#if BX_ROMBIOS32 || defined(VBOX)
    47604757                        set_e820_range(ES, regs.u.r16.di,
    47614758                                       0x00100000L,
    47624759                                       extended_memory_size - ACPI_DATA_SIZE, 0, 0, 1);
    47634760                        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
    47684767                        break;
    47694768                    case 4:
     
    47724771                                       extended_memory_size, 0, 0, 3); // ACPI RAM
    47734772                        regs.u.r32.ebx = 5;
    4774                         regs.u.r32.eax = 0x534D4150;
    4775                         regs.u.r32.ecx = 0x14;
    4776                         CLEAR_CF();
    4777                         return;
    47784773                        break;
    47794774                    case 5:
    47804775                        /* 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
    47814780                        set_e820_range(ES, regs.u.r16.di,
    47824781                                       0xfffc0000L, 0x00000000L, 0, 0, 2);
    4783 #ifdef VBOX_WITH_MORE_THAN_4GB
    47844782                        if (extra_highbits_memory_size || extra_lowbits_memory_size)
    47854783                            regs.u.r32.ebx = 6;
    47864784                        else
    4787 #endif
    47884785                            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;
    47944787                    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);
    47994806                        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 */
    48054809                    default:  /* AX=E820, DX=534D4150, BX unrecognized */
    48064810                        goto int15_unimplemented;
    48074811                        break;
    48084812                }
     4813                regs.u.r32.eax = 0x534D4150;
     4814                regs.u.r32.ecx = 0x14;
     4815                CLEAR_CF();
    48094816            } else {
    48104817              // if DX != 0x534D4150)
  • trunk/src/VBox/Devices/PC/DevPcBios.cpp

    r17542 r17545  
    9090    Number of CPUs:
    9191         0x60
    92     RAM above 4G (in 64M units):
    93          0x61 - 0x63
     92    RAM above 4G (in 64KB units):
     93         0x61 - 0x65
    9494@endverbatim
    9595 *
     
    526526     * Memory sizes.
    527527     */
    528 #ifdef VBOX_WITH_MORE_THAN_4GB
    529     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     else
    539     {
    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     else
    563         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. */
    573528    /* base memory. */
    574529    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 */
     
    584539
    585540    /* 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. */
    587544    uint64_t const offRamHole = _4G - pThis->cbRamHole;
    588545    if (pThis->cbRam > 16 * _1M)
    589546    {
    590547        u32 = (uint32_t)( (RT_MIN(pThis->cbRam, offRamHole) - 16 * _1M) / _64K );
    591         u32 = RT_MIN(u32, 0xffff);
     548        u32 = RT_MIN(u32, 0xfefc);
    592549    }
    593550    else
     
    596553    pcbiosCmosWrite(pDevIns, 0x35, u32 >> 8);
    597554
    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 a
    600                    total around 2**52 bytes or 4EB if you like. The max of what
    601                    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;
    602559    if (pThis->cbRam <= offRamHole)
    603         u32 = 0;
     560        c64KBAbove4GB = 0;
    604561    else
    605562    {
    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, 0xY1, (u32 >>  8) & 0xff);
    611     pcbiosCmosWrite(pDevIns, 0xY2, (u32 >> 16) & 0xff);
    612     pcbiosCmosWrite(pDevIns, 0xY3,  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);
    615572
    616573    /*
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette