VirtualBox

Changeset 43483 in vbox for trunk/src/VBox/Devices/PC/BIOS


Ignore:
Timestamp:
Oct 1, 2012 10:13:16 AM (12 years ago)
Author:
vboxsync
Message:

BIOS: Build default logical geometry if none was provided in CMOS.

Location:
trunk/src/VBox/Devices/PC/BIOS
Files:
4 edited

Legend:

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

    r43438 r43483  
    608608}
    609609
    610 static void ahci_port_detect_device(ahci_t __far *ahci, uint8_t u8Port)
     610void ahci_port_detect_device(ahci_t __far *ahci, uint8_t u8Port)
    611611{
    612612    uint32_t            val;
     
    651651                uint32_t    sectors;
    652652                uint16_t    cylinders, heads, spt;
    653                 uint16_t    lcylinders, lheads, lspt;
     653                chs_t       lgeo;
    654654                uint8_t     idxCmosChsBase;
    655655
     
    711711                if (idxCmosChsBase && inb_cmos(idxCmosChsBase+7))
    712712                {
    713                     lcylinders = inb_cmos(idxCmosChsBase + 0) + (inb_cmos(idxCmosChsBase + 1) << 8);
    714                     lheads     = inb_cmos(idxCmosChsBase + 2);
    715                     lspt       = inb_cmos(idxCmosChsBase + 7);
     713                    lgeo.cylinders = inb_cmos(idxCmosChsBase + 0) + (inb_cmos(idxCmosChsBase + 1) << 8);
     714                    lgeo.heads     = inb_cmos(idxCmosChsBase + 2);
     715                    lgeo.spt       = inb_cmos(idxCmosChsBase + 7);
    716716                }
    717717                else
    718                 {
    719                     //@todo: What should we really do if logical geometry isn't in the CMOS?
    720                     lcylinders = cylinders;
    721                     lheads     = heads;
    722                     lspt       = spt;
    723                 }
     718                    set_geom_lba(&lgeo, sectors);   /* Default EDD-style translated LBA geometry. */
     719
    724720                BX_INFO("AHCI %d-P#%d: PCHS=%u/%d/%d LCHS=%u/%u/%u %ld sectors\n", devcount_ahci,
    725                         u8Port, cylinders, heads, spt, lcylinders, lheads, lspt, sectors);
    726 
    727                 bios_dsk->devices[hd_index].lchs.heads     = lheads;
    728                 bios_dsk->devices[hd_index].lchs.cylinders = lcylinders;
    729                 bios_dsk->devices[hd_index].lchs.spt       = lspt;
     721                        u8Port, cylinders, heads, spt, lgeo.cylinders, lgeo.heads, lgeo.spt, sectors);
     722
     723                bios_dsk->devices[hd_index].lchs = lgeo;
    730724
    731725                /* Store the ID of the disk in the BIOS hdidmap. */
  • trunk/src/VBox/Devices/PC/BIOS/ata.c

    r43440 r43483  
    462462            uint32_t    sectors;
    463463            uint16_t    cylinders, heads, spt, blksize;
    464             uint16_t    lcylinders, lheads, lspt;
     464            chs_t       lgeo;
    465465            uint8_t     chsgeo_base;
    466466            uint8_t     removable, mode;
     
    506506            if (chsgeo_base)
    507507            {
    508                 lcylinders = inb_cmos(chsgeo_base) + (inb_cmos(chsgeo_base+1) << 8);
    509                 lheads = inb_cmos(chsgeo_base+2);
    510                 lspt = inb_cmos(chsgeo_base+7);
     508                lgeo.cylinders = inb_cmos(chsgeo_base) + (inb_cmos(chsgeo_base + 1) << 8);
     509                lgeo.heads     = inb_cmos(chsgeo_base + 2);
     510                lgeo.spt       = inb_cmos(chsgeo_base + 7);
    511511            }
    512512            else
    513             {
    514                 lcylinders = 0;
    515                 lheads = 0;
    516                 lspt = 0;
    517             }
     513                set_geom_lba(&lgeo, sectors);   /* Default EDD-style translated LBA geometry. */
     514
    518515            BX_INFO("ata%d-%d: PCHS=%u/%d/%d LCHS=%u/%u/%u\n", channel, slave,
    519                     cylinders,heads, spt, lcylinders, lheads, lspt);
     516                    cylinders,heads, spt, lgeo.cylinders, lgeo.heads, lgeo.spt);
    520517
    521518            bios_dsk->devices[device].device         = DSK_DEVICE_HD;
     
    527524            bios_dsk->devices[device].pchs.spt       = spt;
    528525            bios_dsk->devices[device].sectors        = sectors;
    529             bios_dsk->devices[device].lchs.heads     = lheads;
    530             bios_dsk->devices[device].lchs.cylinders = lcylinders;
    531             bios_dsk->devices[device].lchs.spt       = lspt;
     526            bios_dsk->devices[device].lchs           = lgeo;
    532527            if (device < 2)
    533528            {
     
    544539                 * isn't worth the effort of converting from AMI to Award CMOS
    545540                 * format. Just do it here. */
    546                 fdpt->lcyl  = lcylinders;
    547                 fdpt->lhead = lheads;
     541                fdpt->lcyl  = lgeo.cylinders;
     542                fdpt->lhead = lgeo.heads;
    548543                fdpt->sig   = 0xa0;
    549544                fdpt->spt   = spt;
  • trunk/src/VBox/Devices/PC/BIOS/disk.c

    r39651 r43483  
    9292#define ES      r.es
    9393#define FLAGS   r.ra.flags.u.r16.flags
     94
     95
     96/*
     97 * Build translated CHS geometry given a disk size in sectors. Based on
     98 * Phoenix EDD 3.0. This is used as a fallback to generate sane logical
     99 * geometry in case none was provided in CMOS.
     100 */
     101void set_geom_lba(chs_t __far *lgeo, uint32_t nsectors)
     102{
     103    uint32_t    limit = 8257536;    /* 1024 * 128 * 63 */
     104    unsigned    heads = 255;
     105    int         i;
     106   
     107    /* Start with ~4GB limit, go down to 504MB. */
     108    for (i = 0; i < 4; ++i) {
     109        if (nsectors <= limit)
     110            heads = (heads + 1) / 2;
     111        limit /= 2;
     112    }
     113
     114    lgeo->cylinders = nsectors / (heads * 63UL);
     115    if (lgeo->cylinders > 1024)
     116        lgeo->cylinders = 1024;
     117    lgeo->heads     = heads;
     118    lgeo->spt       = 63;   /* Always 63 sectors per track, the maximum. */
     119}
     120
    94121
    95122void BIOSCALL int13_harddisk(disk_regs_t r)
  • trunk/src/VBox/Devices/PC/BIOS/ebda.h

    r43475 r43483  
    316316int __fastcall ahci_write_sectors(bio_dsk_t __far *bios_dsk);
    317317
     318extern void set_geom_lba(chs_t __far *lgeo, uint32_t nsectors);
     319
    318320// @todo: put this elsewhere (and change/eliminate?)
    319321#define SET_DISK_RET_STATUS(status) write_byte(0x0040, 0x0074, status)
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