Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Evergreen:11.1:kernel-2.6.32
xen
int13_hardisk-64bit-lba.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File int13_hardisk-64bit-lba.patch of Package xen
Index: xen-3.3.1-testing/tools/firmware/rombios/rombios.c =================================================================== --- xen-3.3.1-testing.orig/tools/firmware/rombios/rombios.c +++ xen-3.3.1-testing/tools/firmware/rombios/rombios.c @@ -686,7 +686,8 @@ typedef struct { chs_t lchs; // Logical CHS chs_t pchs; // Physical CHS - Bit32u sectors; // Total sectors count + Bit32u sectors_low; // Total sectors count + Bit32u sectors_high; } ata_device_t; typedef struct { @@ -2547,7 +2548,8 @@ void ata_init( ) write_word(ebda_seg,&EbdaData->ata.devices[device].pchs.cylinders,0); write_word(ebda_seg,&EbdaData->ata.devices[device].pchs.spt,0); - write_dword(ebda_seg,&EbdaData->ata.devices[device].sectors,0L); + write_dword(ebda_seg,&EbdaData->ata.devices[device].sectors_low,0L); + write_dword(ebda_seg,&EbdaData->ata.devices[device].sectors_high,0L); } // hdidmap and cdidmap init. @@ -2656,7 +2658,7 @@ void ata_detect( ) // Now we send a IDENTIFY command to ATA device if(type == ATA_TYPE_ATA) { - Bit32u sectors; + Bit32u sectors_low, sectors_high; Bit16u cylinders, heads, spt, blksize; Bit8u translation, removable, mode; @@ -2667,7 +2669,7 @@ void ata_detect( ) write_byte(ebda_seg,&EbdaData->ata.devices[device].device,ATA_DEVICE_HD); write_byte(ebda_seg,&EbdaData->ata.devices[device].mode, ATA_MODE_PIO16); - if (ata_cmd_data_in(device,ATA_CMD_IDENTIFY_DEVICE, 1, 0, 0, 0, 0L, get_SS(),buffer) !=0 ) + if (ata_cmd_data_in(device,ATA_CMD_IDENTIFY_DEVICE, 1, 0, 0, 0, 0L, 0L, get_SS(),buffer) !=0 ) BX_PANIC("ata-detect: Failed to detect ATA device\n"); removable = (read_byte(get_SS(),buffer+0) & 0x80) ? 1 : 0; @@ -2681,7 +2683,13 @@ void ata_detect( ) heads = read_word(get_SS(),buffer+(3*2)); // word 3 spt = read_word(get_SS(),buffer+(6*2)); // word 6 - sectors = read_dword(get_SS(),buffer+(60*2)); // word 60 and word 61 + if (read_word(get_SS(),buffer+(83*2)) & (1 << 10)) { // word 83 - lba48 support + sectors_low = read_dword(get_SS(),buffer+(100*2)); // word 100 and word 101 + sectors_high = read_dword(get_SS(),buffer+(102*2)); // word 102 and word 103 + } else { + sectors_low = read_dword(get_SS(),buffer+(60*2)); // word 60 and word 61 + sectors_high = 0; + } write_byte(ebda_seg,&EbdaData->ata.devices[device].device,ATA_DEVICE_HD); write_byte(ebda_seg,&EbdaData->ata.devices[device].removable, removable); @@ -2690,7 +2698,8 @@ void ata_detect( ) write_word(ebda_seg,&EbdaData->ata.devices[device].pchs.heads, heads); write_word(ebda_seg,&EbdaData->ata.devices[device].pchs.cylinders, cylinders); write_word(ebda_seg,&EbdaData->ata.devices[device].pchs.spt, spt); - write_dword(ebda_seg,&EbdaData->ata.devices[device].sectors, sectors); + write_dword(ebda_seg,&EbdaData->ata.devices[device].sectors_low, sectors_low); + write_dword(ebda_seg,&EbdaData->ata.devices[device].sectors_high, sectors_high); BX_INFO("ata%d-%d: PCHS=%u/%d/%d translation=", channel, slave,cylinders, heads, spt); translation = inb_cmos(0x39 + channel/2); @@ -2718,14 +2727,14 @@ void ata_detect( ) break; case ATA_TRANSLATION_LBA: spt = 63; - sectors /= 63; - heads = sectors / 1024; + sectors_low /= 63; + heads = sectors_low / 1024; if (heads>128) heads = 255; else if (heads>64) heads = 128; else if (heads>32) heads = 64; else if (heads>16) heads = 32; else heads=16; - cylinders = sectors / heads; + cylinders = sectors_low / heads; break; case ATA_TRANSLATION_RECHS: // Take care not to overflow @@ -2771,7 +2780,7 @@ void ata_detect( ) write_byte(ebda_seg,&EbdaData->ata.devices[device].device,ATA_DEVICE_CDROM); write_byte(ebda_seg,&EbdaData->ata.devices[device].mode, ATA_MODE_PIO16); - if (ata_cmd_data_in(device,ATA_CMD_IDENTIFY_DEVICE_PACKET, 1, 0, 0, 0, 0L, get_SS(),buffer) != 0) + if (ata_cmd_data_in(device,ATA_CMD_IDENTIFY_DEVICE_PACKET, 1, 0, 0, 0, 0L, 0L, get_SS(),buffer) != 0) BX_PANIC("ata-detect: Failed to detect ATAPI device\n"); type = read_byte(get_SS(),buffer+1) & 0x1f; @@ -2798,8 +2807,8 @@ void ata_detect( ) switch (type) { case ATA_TYPE_ATA: - sizeinmb = read_dword(ebda_seg,&EbdaData->ata.devices[device].sectors); - sizeinmb >>= 11; + sizeinmb = (read_dword(ebda_seg,&EbdaData->ata.devices[device].sectors_high) << 21) + | (read_dword(ebda_seg,&EbdaData->ata.devices[device].sectors_low) >> 11); case ATA_TYPE_ATAPI: // Read ATA/ATAPI version ataversion=((Bit16u)(read_byte(get_SS(),buffer+161))<<8)|read_byte(get_SS(),buffer+160); @@ -2945,9 +2954,9 @@ Bit16u ata_cmd_non_data() // 5 : more sectors to read/verify // 6 : no sectors left to write // 7 : more sectors to write -Bit16u ata_cmd_data_in(device, command, count, cylinder, head, sector, lba, segment, offset) +Bit16u ata_cmd_data_in(device, command, count, cylinder, head, sector, lba_low, lba_high, segment, offset) Bit16u device, command, count, cylinder, head, sector, segment, offset; -Bit32u lba; +Bit32u lba_low, lba_high; { Bit16u ebda_seg=read_word(0x0040,0x000E); Bit16u iobase1, iobase2, blksize; @@ -2976,21 +2985,21 @@ Bit32u lba; // sector will be 0 only on lba access. Convert to lba-chs if (sector == 0) { - if ((count >= 1 << 8) || (lba + count >= 1UL << 28)) { + if ((count >= 1 << 8) || lba_high || (lba_low + 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); + outb(iobase1 + ATA_CB_SN, lba_low >> 24); + outb(iobase1 + ATA_CB_CL, lba_high & 0xff); + outb(iobase1 + ATA_CB_CH, lba_high >> 8); command |= 0x04; count &= (1UL << 8) - 1; - lba &= (1UL << 24) - 1; + lba_low &= (1UL << 24) - 1; } - sector = (Bit16u) (lba & 0x000000ffL); - lba >>= 8; - cylinder = (Bit16u) (lba & 0x0000ffffL); - lba >>= 16; - head = ((Bit16u) (lba & 0x0000000fL)) | 0x40; + sector = (Bit16u) (lba_low & 0x000000ffL); + lba_low >>= 8; + cylinder = (Bit16u) (lba_low & 0x0000ffffL); + lba_low >>= 16; + head = ((Bit16u) (lba_low & 0x0000000fL)) | 0x40; } outb(iobase1 + ATA_CB_FR, 0x00); @@ -3099,9 +3108,9 @@ ASM_END // 5 : more sectors to read/verify // 6 : no sectors left to write // 7 : more sectors to write -Bit16u ata_cmd_data_out(device, command, count, cylinder, head, sector, lba, segment, offset) +Bit16u ata_cmd_data_out(device, command, count, cylinder, head, sector, lba_low, lba_high, segment, offset) Bit16u device, command, count, cylinder, head, sector, segment, offset; -Bit32u lba; +Bit32u lba_low, lba_high; { Bit16u ebda_seg=read_word(0x0040,0x000E); Bit16u iobase1, iobase2, blksize; @@ -3130,21 +3139,21 @@ Bit32u lba; // sector will be 0 only on lba access. Convert to lba-chs if (sector == 0) { - if ((count >= 1 << 8) || (lba + count >= 1UL << 28)) { + if ((count >= 1 << 8) || lba_high || (lba_low + 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); + outb(iobase1 + ATA_CB_SN, lba_low >> 24); + outb(iobase1 + ATA_CB_CL, lba_high & 0xff); + outb(iobase1 + ATA_CB_CH, lba_high >> 8); command |= 0x04; count &= (1UL << 8) - 1; - lba &= (1UL << 24) - 1; + lba_low &= (1UL << 24) - 1; } - sector = (Bit16u) (lba & 0x000000ffL); - lba >>= 8; - cylinder = (Bit16u) (lba & 0x0000ffffL); - lba >>= 16; - head = ((Bit16u) (lba & 0x0000000fL)) | 0x40; + sector = (Bit16u) (lba_low & 0x000000ffL); + lba_low >>= 8; + cylinder = (Bit16u) (lba_low & 0x0000ffffL); + lba_low >>= 16; + head = ((Bit16u) (lba_low & 0x0000000fL)) | 0x40; } outb(iobase1 + ATA_CB_FR, 0x00); @@ -5151,7 +5160,7 @@ BX_DEBUG_INT74("int74_function: make_far int13_harddisk(DS, ES, DI, SI, BP, ELDX, BX, DX, CX, AX, IP, CS, FLAGS) Bit16u DS, ES, DI, SI, BP, ELDX, BX, DX, CX, AX, IP, CS, FLAGS; { - Bit32u lba; + Bit32u lba_low, lba_high; Bit16u ebda_seg=read_word(0x0040,0x000E); Bit16u cylinder, head, sector; Bit16u segment, offset; @@ -5230,14 +5239,15 @@ int13_harddisk(DS, ES, DI, SI, BP, ELDX, // if needed, translate lchs to lba, and execute command if ( (nph != nlh) || (npspt != nlspt)) { - lba = ((((Bit32u)cylinder * (Bit32u)nlh) + (Bit32u)head) * (Bit32u)nlspt) + (Bit32u)sector - 1; + lba_low = ((((Bit32u)cylinder * (Bit32u)nlh) + (Bit32u)head) * (Bit32u)nlspt) + (Bit32u)sector - 1; + lba_high = 0; sector = 0; // this forces the command to be lba } if ( GET_AH() == 0x02 ) - status=ata_cmd_data_in(device, ATA_CMD_READ_SECTORS, count, cylinder, head, sector, lba, segment, offset); + status=ata_cmd_data_in(device, ATA_CMD_READ_SECTORS, count, cylinder, head, sector, lba_low, lba_high, segment, offset); else - status=ata_cmd_data_out(device, ATA_CMD_WRITE_SECTORS, count, cylinder, head, sector, lba, segment, offset); + status=ata_cmd_data_out(device, ATA_CMD_WRITE_SECTORS, count, cylinder, head, sector, lba_low, lba_high, segment, offset); // Set nb of sector transferred SET_AL(read_word(ebda_seg, &EbdaData->ata.trsfsectors)); @@ -5299,9 +5309,9 @@ int13_harddisk(DS, ES, DI, SI, BP, ELDX, npspt = read_word(ebda_seg, &EbdaData->ata.devices[device].pchs.spt); // Compute sector count seen by int13 - lba = (Bit32u)(npc - 1) * (Bit32u)nph * (Bit32u)npspt; - CX = lba >> 16; - DX = lba & 0xffff; + lba_low = (Bit32u)(nlc - 1) * (Bit32u)nlh * (Bit32u)nlspt; + CX = lba_low >> 16; + DX = lba_low & 0xffff; SET_AH(3); // hard disk accessible goto int13_success_noah; @@ -5323,16 +5333,17 @@ int13_harddisk(DS, ES, DI, SI, BP, ELDX, segment=read_word(DS, SI+(Bit16u)&Int13Ext->segment); offset=read_word(DS, SI+(Bit16u)&Int13Ext->offset); - // Can't use 64 bits lba - lba=read_dword(DS, SI+(Bit16u)&Int13Ext->lba2); - if (lba != 0L) { - BX_PANIC("int13_harddisk: function %02x. Can't use 64bits lba\n",GET_AH()); + // Get 32 msb lba and check + lba_high=read_dword(DS, SI+(Bit16u)&Int13Ext->lba2); + if (lba_high > read_dword(ebda_seg, &EbdaData->ata.devices[device].sectors_high) ) { + BX_INFO("int13_harddisk: function %02x. LBA out of range\n",GET_AH()); goto int13_fail; } - // Get 32 bits lba and check - lba=read_dword(DS, SI+(Bit16u)&Int13Ext->lba1); - if (lba >= read_dword(ebda_seg, &EbdaData->ata.devices[device].sectors) ) { + // Get 32 lsb lba and check + lba_low=read_dword(DS, SI+(Bit16u)&Int13Ext->lba1); + if (lba_high == read_dword(ebda_seg, &EbdaData->ata.devices[device].sectors_high) + && lba_low >= read_dword(ebda_seg, &EbdaData->ata.devices[device].sectors_low) ) { BX_INFO("int13_harddisk: function %02x. LBA out of range\n",GET_AH()); goto int13_fail; } @@ -5343,9 +5354,9 @@ int13_harddisk(DS, ES, DI, SI, BP, ELDX, // Execute the command if ( GET_AH() == 0x42 ) - status=ata_cmd_data_in(device, ATA_CMD_READ_SECTORS, count, 0, 0, 0, lba, segment, offset); + status=ata_cmd_data_in(device, ATA_CMD_READ_SECTORS, count, 0, 0, 0, lba_low, lba_high, segment, offset); else - status=ata_cmd_data_out(device, ATA_CMD_WRITE_SECTORS, count, 0, 0, 0, lba, segment, offset); + status=ata_cmd_data_out(device, ATA_CMD_WRITE_SECTORS, count, 0, 0, 0, lba_low, lba_high, segment, offset); count=read_word(ebda_seg, &EbdaData->ata.trsfsectors); write_word(DS, SI+(Bit16u)&Int13Ext->count, count); @@ -5383,16 +5394,25 @@ int13_harddisk(DS, ES, DI, SI, BP, ELDX, npc = read_word(ebda_seg, &EbdaData->ata.devices[device].pchs.cylinders); nph = read_word(ebda_seg, &EbdaData->ata.devices[device].pchs.heads); npspt = read_word(ebda_seg, &EbdaData->ata.devices[device].pchs.spt); - lba = read_dword(ebda_seg, &EbdaData->ata.devices[device].sectors); + lba_low = read_dword(ebda_seg, &EbdaData->ata.devices[device].sectors_low); + lba_high = read_dword(ebda_seg, &EbdaData->ata.devices[device].sectors_high); blksize = read_word(ebda_seg, &EbdaData->ata.devices[device].blksize); write_word(DS, SI+(Bit16u)&Int13DPT->size, 0x1a); - write_word(DS, SI+(Bit16u)&Int13DPT->infos, 0x02); // geometry is valid - write_dword(DS, SI+(Bit16u)&Int13DPT->cylinders, (Bit32u)npc); + if (lba_high || (lba_low/npspt)/nph > 0x3fff) + { + write_word(DS, SI+(Bit16u)&Int13DPT->infos, 0x00); // geometry is invalid + write_dword(DS, SI+(Bit16u)&Int13DPT->cylinders, 0x3fff); + } + else + { + write_word(DS, SI+(Bit16u)&Int13DPT->infos, 0x02); // geometry is valid + write_dword(DS, SI+(Bit16u)&Int13DPT->cylinders, (Bit32u)npc); + } write_dword(DS, SI+(Bit16u)&Int13DPT->heads, (Bit32u)nph); write_dword(DS, SI+(Bit16u)&Int13DPT->spt, (Bit32u)npspt); - write_dword(DS, SI+(Bit16u)&Int13DPT->sector_count1, lba); // FIXME should be Bit64 - write_dword(DS, SI+(Bit16u)&Int13DPT->sector_count2, 0L); + write_dword(DS, SI+(Bit16u)&Int13DPT->sector_count1, lba_low); + write_dword(DS, SI+(Bit16u)&Int13DPT->sector_count2, lba_high); write_word(DS, SI+(Bit16u)&Int13DPT->blksize, blksize); }
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor