From mboxrd@z Thu Jan 1 00:00:00 1970 From: Samuel Thibault Subject: [PATCH] LBA48 support in rombios Date: Thu, 27 Dec 2007 12:53:20 +0100 Message-ID: <20071227115320.GB4239@implementation.uk.xensource.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Return-path: Content-Disposition: inline List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xensource.com Errors-To: xen-devel-bounces@lists.xensource.com To: xen-devel@lists.xensource.com List-Id: xen-devel@lists.xenproject.org INT13 LBA48 support for disks bigger than 128GB. The new limit should be 2TB. Signed-off-by: Samuel Thibault diff -r d048ef27cb02 tools/firmware/rombios/rombios.c --- a/tools/firmware/rombios/rombios.c Fri Nov 09 15:21:01 2007 +0000 +++ b/tools/firmware/rombios/rombios.c Mon Nov 12 14:26:16 2007 +0000 @@ -2538,7 +2538,10 @@ case ATA_TYPE_ATA: printf("ata%d %s: ",channel,slave?" slave":"master"); i=0; while(c=read_byte(get_SS(),model+i++)) printf("%c",c); - printf(" ATA-%d Hard-Disk (%d MBytes)\n",version,(Bit16u)sizeinmb); + if (sizeinmb < 1UL<<16) + printf(" ATA-%d Hard-Disk (%04u MBytes)\n",version,(Bit16u)sizeinmb); + else + printf(" ATA-%d Hard-Disk (%04u GBytes)\n",version,(Bit16u)(sizeinmb>>10)); break; case ATA_TYPE_ATAPI: printf("ata%d %s: ",channel,slave?" slave":"master"); @@ -2671,8 +2674,28 @@ if (mode == ATA_MODE_PIO32) blksize>>=2; else blksize>>=1; + // Reset count of transferred data + write_word(ebda_seg, &EbdaData->ata.trsfsectors,0); + write_dword(ebda_seg, &EbdaData->ata.trsfbytes,0L); + current = 0; + + status = inb(iobase1 + ATA_CB_STAT); + if (status & ATA_CB_STAT_BSY) return 1; + + outb(iobase2 + ATA_CB_DC, ATA_CB_DC_HD15 | ATA_CB_DC_NIEN); + // sector will be 0 only on lba access. Convert to lba-chs if (sector == 0) { + if ((count >= 1 << 8) || (lba + count >= 1UL << 28)) { + outb(iobase1 + ATA_CB_FR, 0x00); + outb(iobase1 + ATA_CB_SC, (count >> 8) & 0xff); + outb(iobase1 + ATA_CB_SN, lba >> 24); + outb(iobase1 + ATA_CB_CL, 0); + outb(iobase1 + ATA_CB_CH, 0); + command |= 0x04; + count &= (1UL << 8) - 1; + lba &= (1UL << 24) - 1; + } sector = (Bit16u) (lba & 0x000000ffL); lba >>= 8; cylinder = (Bit16u) (lba & 0x0000ffffL); @@ -2680,15 +2703,6 @@ head = ((Bit16u) (lba & 0x0000000fL)) | 0x40; } - // Reset count of transferred data - write_word(ebda_seg, &EbdaData->ata.trsfsectors,0); - write_dword(ebda_seg, &EbdaData->ata.trsfbytes,0L); - current = 0; - - status = inb(iobase1 + ATA_CB_STAT); - if (status & ATA_CB_STAT_BSY) return 1; - - outb(iobase2 + ATA_CB_DC, ATA_CB_DC_HD15 | ATA_CB_DC_NIEN); outb(iobase1 + ATA_CB_FR, 0x00); outb(iobase1 + ATA_CB_SC, count); outb(iobase1 + ATA_CB_SN, sector); @@ -2814,8 +2828,28 @@ if (mode == ATA_MODE_PIO32) blksize>>=2; else blksize>>=1; + // Reset count of transferred data + write_word(ebda_seg, &EbdaData->ata.trsfsectors,0); + write_dword(ebda_seg, &EbdaData->ata.trsfbytes,0L); + current = 0; + + status = inb(iobase1 + ATA_CB_STAT); + if (status & ATA_CB_STAT_BSY) return 1; + + outb(iobase2 + ATA_CB_DC, ATA_CB_DC_HD15 | ATA_CB_DC_NIEN); + // sector will be 0 only on lba access. Convert to lba-chs if (sector == 0) { + if ((count >= 1 << 8) || (lba + count >= 1UL << 28)) { + outb(iobase1 + ATA_CB_FR, 0x00); + outb(iobase1 + ATA_CB_SC, (count >> 8) & 0xff); + outb(iobase1 + ATA_CB_SN, lba >> 24); + outb(iobase1 + ATA_CB_CL, 0); + outb(iobase1 + ATA_CB_CH, 0); + command |= 0x04; + count &= (1UL << 8) - 1; + lba &= (1UL << 24) - 1; + } sector = (Bit16u) (lba & 0x000000ffL); lba >>= 8; cylinder = (Bit16u) (lba & 0x0000ffffL); @@ -2823,15 +2857,6 @@ head = ((Bit16u) (lba & 0x0000000fL)) | 0x40; } - // Reset count of transferred data - write_word(ebda_seg, &EbdaData->ata.trsfsectors,0); - write_dword(ebda_seg, &EbdaData->ata.trsfbytes,0L); - current = 0; - - status = inb(iobase1 + ATA_CB_STAT); - if (status & ATA_CB_STAT_BSY) return 1; - - outb(iobase2 + ATA_CB_DC, ATA_CB_DC_HD15 | ATA_CB_DC_NIEN); outb(iobase1 + ATA_CB_FR, 0x00); outb(iobase1 + ATA_CB_SC, count); outb(iobase1 + ATA_CB_SN, sector);