--- qemu/roms/seabios/src/block.c 2018/04/24 17:36:47 1.1 +++ qemu/roms/seabios/src/block.c 2018/04/24 18:27:25 1.1.1.3 @@ -10,36 +10,20 @@ #include "cmos.h" // inb_cmos #include "util.h" // dprintf #include "ata.h" // process_ata_op +#include "usb-msc.h" // process_usb_op +#include "virtio-blk.h" // process_virtio_op struct drives_s Drives VAR16VISIBLE; struct drive_s * getDrive(u8 exttype, u8 extdriveoffset) { - // basic check : device has to be defined if (extdriveoffset >= ARRAY_SIZE(Drives.idmap[0])) return NULL; - - // Get the ata channel - u8 driveid = GET_GLOBAL(Drives.idmap[exttype][extdriveoffset]); - - // basic check : device has to be valid - if (driveid >= ARRAY_SIZE(Drives.drives)) - return NULL; - - return &Drives.drives[driveid]; -} - -struct drive_s * -allocDrive() -{ - int driveid = Drives.drivecount; - if (driveid >= ARRAY_SIZE(Drives.drives)) + struct drive_s *drive_gf = GET_GLOBAL(Drives.idmap[exttype][extdriveoffset]); + if (!drive_gf) return NULL; - Drives.drivecount++; - struct drive_s *drive_g = &Drives.drives[driveid]; - memset(drive_g, 0, sizeof(*drive_g)); - return drive_g; + return GLOBALFLAT2GLOBAL(drive_gf); } @@ -61,10 +45,15 @@ get_translation(struct drive_s *drive_g) return translation; } - // On COREBOOT, use a heuristic to determine translation type. + // Otherwise use a heuristic to determine translation type. u16 heads = GET_GLOBAL(drive_g->pchs.heads); u16 cylinders = GET_GLOBAL(drive_g->pchs.cylinders); u16 spt = GET_GLOBAL(drive_g->pchs.spt); + u64 sectors = GET_GLOBAL(drive_g->sectors); + u64 psectors = (u64)heads * cylinders * spt; + if (!heads || !cylinders || !spt || psectors > sectors) + // pchs doesn't look valid - use LBA. + return TRANSLATION_LBA; if (cylinders <= 1024 && heads <= 16 && spt <= 63) return TRANSLATION_NONE; @@ -79,9 +68,6 @@ setup_translation(struct drive_s *drive_ u8 translation = get_translation(drive_g); SET_GLOBAL(drive_g->translation, translation); - u8 ataid = GET_GLOBAL(drive_g->cntl_id); - u8 channel = ataid / 2; - u8 slave = ataid % 2; u16 heads = GET_GLOBAL(drive_g->pchs.heads); u16 cylinders = GET_GLOBAL(drive_g->pchs.cylinders); u16 spt = GET_GLOBAL(drive_g->pchs.spt); @@ -141,11 +127,12 @@ setup_translation(struct drive_s *drive_ // clip to 1024 cylinders in lchs if (cylinders > 1024) cylinders = 1024; - dprintf(1, "ata%d-%d: PCHS=%u/%d/%d translation=%s LCHS=%d/%d/%d\n" - , channel, slave + dprintf(1, "drive %p: PCHS=%u/%d/%d translation=%s LCHS=%d/%d/%d s=%d\n" + , drive_g , drive_g->pchs.cylinders, drive_g->pchs.heads, drive_g->pchs.spt , desc - , cylinders, heads, spt); + , cylinders, heads, spt + , (u32)sectors); SET_GLOBAL(drive_g->lchs.heads, heads); SET_GLOBAL(drive_g->lchs.cylinders, cylinders); @@ -180,20 +167,19 @@ fill_fdpt(struct drive_s *drive_g, int h fdpt->heads = nlh; fdpt->sectors = nlspt; - if (nlc == npc && nlh == nph && nlspt == npspt) - // no logical CHS mapping used, just physical CHS - // use Standard Fixed Disk Parameter Table (FDPT) - return; + if (nlc != npc || nlh != nph || nlspt != npspt) { + // Logical mapping present - use extended structure. - // complies with Phoenix style Translated Fixed Disk Parameter - // Table (FDPT) - fdpt->phys_cylinders = npc; - fdpt->phys_heads = nph; - fdpt->phys_sectors = npspt; - fdpt->a0h_signature = 0xa0; + // complies with Phoenix style Translated Fixed Disk Parameter + // Table (FDPT) + fdpt->phys_cylinders = npc; + fdpt->phys_heads = nph; + fdpt->phys_sectors = npspt; + fdpt->a0h_signature = 0xa0; - // Checksum structure. - fdpt->checksum -= checksum(fdpt, sizeof(*fdpt)); + // Checksum structure. + fdpt->checksum -= checksum(fdpt, sizeof(*fdpt)); + } if (hdid == 0) SET_IVT(0x41, SEGOFF(get_ebda_seg(), offsetof( @@ -209,11 +195,12 @@ map_hd_drive(struct drive_s *drive_g) { // fill hdidmap u8 hdcount = GET_BDA(hdcount); - if (hdcount >= ARRAY_SIZE(Drives.idmap[0])) + if (hdcount >= ARRAY_SIZE(Drives.idmap[0])) { + warn_noalloc(); return; + } dprintf(3, "Mapping hd drive %p to %d\n", drive_g, hdcount); - int driveid = drive_g - Drives.drives; - SET_GLOBAL(Drives.idmap[EXTTYPE_HD][hdcount], driveid); + Drives.idmap[EXTTYPE_HD][hdcount] = drive_g; SET_BDA(hdcount, hdcount + 1); // Fill "fdpt" structure. @@ -222,22 +209,22 @@ map_hd_drive(struct drive_s *drive_g) // Find spot to add a drive static void -add_ordered_drive(u8 *idmap, u8 *count, struct drive_s *drive_g) +add_ordered_drive(struct drive_s **idmap, u8 *count, struct drive_s *drive_g) { if (*count >= ARRAY_SIZE(Drives.idmap[0])) { - dprintf(1, "No room to map drive %p\n", drive_g); + warn_noalloc(); return; } - u8 *pos = &idmap[*count]; + struct drive_s **pos = &idmap[*count]; *count = *count + 1; if (CONFIG_THREADS) { // Add to idmap with assured drive order. - u8 *end = pos; + struct drive_s **end = pos; for (;;) { - u8 *prev = pos - 1; + struct drive_s **prev = pos - 1; if (prev < idmap) break; - struct drive_s *prevdrive = &Drives.drives[*prev]; + struct drive_s *prevdrive = *prev; if (prevdrive->type < drive_g->type || (prevdrive->type == drive_g->type && prevdrive->cntl_id < drive_g->cntl_id)) @@ -247,7 +234,7 @@ add_ordered_drive(u8 *idmap, u8 *count, if (pos != end) memmove(pos+1, pos, (void*)end-(void*)pos); } - *pos = drive_g - Drives.drives; + *pos = drive_g; } // Map a cd @@ -279,31 +266,6 @@ map_floppy_drive(struct drive_s *drive_g } } -// Show a one line description (without trailing newline) of a drive. -void -describe_drive(struct drive_s *drive_g) -{ - ASSERT32(); - u8 type = GET_GLOBAL(drive_g->type); - switch (type) { - case DTYPE_FLOPPY: - describe_floppy(drive_g); - break; - case DTYPE_ATA: - describe_ata(drive_g); - break; - case DTYPE_ATAPI: - describe_atapi(drive_g); - break; - case DTYPE_RAMDISK: - describe_ramdisk(drive_g); - break; - default: - printf("Unknown"); - break; - } -} - /**************************************************************** * 16bit calling interface @@ -313,6 +275,7 @@ describe_drive(struct drive_s *drive_g) int process_op(struct disk_op_s *op) { + ASSERT16(); u8 type = GET_GLOBAL(op->drive_g->type); switch (type) { case DTYPE_FLOPPY: @@ -325,6 +288,10 @@ process_op(struct disk_op_s *op) return process_ramdisk_op(op); case DTYPE_CDEMU: return process_cdemu_op(op); + case DTYPE_USB: + return process_usb_op(op); + case DTYPE_VIRTIO: + return process_virtio_op(op); default: op->count = 0; return DISK_RET_EPARAM; @@ -356,11 +323,11 @@ __send_disk_op(struct disk_op_s *op_far, int send_disk_op(struct disk_op_s *op) { + ASSERT16(); if (! CONFIG_DRIVES) return -1; - ASSERT16(); - return stack_hop((u32)op, GET_SEG(SS), 0, __send_disk_op); + return stack_hop((u32)op, GET_SEG(SS), __send_disk_op); } @@ -369,8 +336,7 @@ send_disk_op(struct disk_op_s *op) ****************************************************************/ void -drive_setup() +drive_setup(void) { memset(&Drives, 0, sizeof(Drives)); - memset(&Drives.idmap, 0xff, sizeof(Drives.idmap)); }