diff options
author | Gleb Natapov <gleb@redhat.com> | 2010-12-23 11:29:35 +0200 |
---|---|---|
committer | Kevin O'Connor <kevin@koconnor.net> | 2010-12-24 10:33:17 -0500 |
commit | f77e1795bce49c4824084b92ffe0a09cf76de795 (patch) | |
tree | a326374547385af15e68ac949758034ee027eb05 /src/disk.c | |
parent | 67863beb71e67433b38a20ba408e490ae173f324 (diff) | |
download | seabios-f77e1795bce49c4824084b92ffe0a09cf76de795.tar.gz |
Provide full EDD 3.0 info for virtio disk
Fill out entire EDD 3.0 structure for virtio disk. Currently only EDD 1.0
part is filled which is missing such important info as device path. Use
SCSI device type since virtio is not defined by EDD spec and virtio disk pci
device uses SCSI class.
Signed-off-by: Gleb Natapov <gleb@redhat.com>
Diffstat (limited to 'src/disk.c')
-rw-r--r-- | src/disk.c | 126 |
1 files changed, 73 insertions, 53 deletions
@@ -544,64 +544,78 @@ disk_1348(struct bregs *regs, struct drive_s *drive_g) } SET_INT13DPT(regs, blksize, blksize); - if (size < 30 || (type != DTYPE_ATA && type != DTYPE_ATAPI)) { + if (size < 30 || + (type != DTYPE_ATA && type != DTYPE_ATAPI && type != DTYPE_VIRTIO)) { disk_ret(regs, DISK_RET_SUCCESS); return; } // EDD 2.x - u16 ebda_seg = get_ebda_seg(); + int bdf; + u16 iobase1; + u64 device_path; SET_INT13DPT(regs, size, 30); + if (type == DTYPE_ATA || type == DTYPE_ATAPI) { + u16 ebda_seg = get_ebda_seg(); - SET_INT13DPT(regs, dpte_segment, ebda_seg); - SET_INT13DPT(regs, dpte_offset - , offsetof(struct extended_bios_data_area_s, dpte)); - - // Fill in dpte - struct atadrive_s *adrive_g = container_of( - drive_g, struct atadrive_s, drive); - struct ata_channel_s *chan_gf = GET_GLOBAL(adrive_g->chan_gf); - u8 slave = GET_GLOBAL(adrive_g->slave); - u16 iobase1 = GET_GLOBALFLAT(chan_gf->iobase1); - u16 iobase2 = GET_GLOBALFLAT(chan_gf->iobase2); - u8 irq = GET_GLOBALFLAT(chan_gf->irq); - - u16 options = 0; - if (type == DTYPE_ATA) { - u8 translation = GET_GLOBAL(drive_g->translation); - if (translation != TRANSLATION_NONE) { - options |= 1<<3; // CHS translation - if (translation == TRANSLATION_LBA) - options |= 1<<9; - if (translation == TRANSLATION_RECHS) - options |= 3<<9; + SET_INT13DPT(regs, dpte_segment, ebda_seg); + SET_INT13DPT(regs, dpte_offset + , offsetof(struct extended_bios_data_area_s, dpte)); + + // Fill in dpte + struct atadrive_s *adrive_g = container_of( + drive_g, struct atadrive_s, drive); + struct ata_channel_s *chan_gf = GET_GLOBAL(adrive_g->chan_gf); + u8 slave = GET_GLOBAL(adrive_g->slave); + u16 iobase2 = GET_GLOBALFLAT(chan_gf->iobase2); + u8 irq = GET_GLOBALFLAT(chan_gf->irq); + iobase1 = GET_GLOBALFLAT(chan_gf->iobase1); + bdf = GET_GLOBALFLAT(chan_gf->pci_bdf); + device_path = slave; + + u16 options = 0; + if (type == DTYPE_ATA) { + u8 translation = GET_GLOBAL(drive_g->translation); + if (translation != TRANSLATION_NONE) { + options |= 1<<3; // CHS translation + if (translation == TRANSLATION_LBA) + options |= 1<<9; + if (translation == TRANSLATION_RECHS) + options |= 3<<9; + } + } else { + // ATAPI + options |= 1<<5; // removable device + options |= 1<<6; // atapi device } + options |= 1<<4; // lba translation + if (CONFIG_ATA_PIO32) + options |= 1<<7; + + SET_EBDA2(ebda_seg, dpte.iobase1, iobase1); + SET_EBDA2(ebda_seg, dpte.iobase2, iobase2 + ATA_CB_DC); + SET_EBDA2(ebda_seg, dpte.prefix, ((slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0) + | ATA_CB_DH_LBA)); + SET_EBDA2(ebda_seg, dpte.unused, 0xcb); + SET_EBDA2(ebda_seg, dpte.irq, irq); + SET_EBDA2(ebda_seg, dpte.blkcount, 1); + SET_EBDA2(ebda_seg, dpte.dma, 0); + SET_EBDA2(ebda_seg, dpte.pio, 0); + SET_EBDA2(ebda_seg, dpte.options, options); + SET_EBDA2(ebda_seg, dpte.reserved, 0); + SET_EBDA2(ebda_seg, dpte.revision, 0x11); + + u8 sum = checksum_far( + ebda_seg, (void*)offsetof(struct extended_bios_data_area_s, dpte), 15); + SET_EBDA2(ebda_seg, dpte.checksum, -sum); } else { - // ATAPI - options |= 1<<5; // removable device - options |= 1<<6; // atapi device + SET_INT13DPT(regs, dpte_segment, 0); + SET_INT13DPT(regs, dpte_offset, 0); + bdf = GET_GLOBAL(drive_g->cntl_id); + device_path = 0; + iobase1 = 0; } - options |= 1<<4; // lba translation - if (CONFIG_ATA_PIO32) - options |= 1<<7; - - SET_EBDA2(ebda_seg, dpte.iobase1, iobase1); - SET_EBDA2(ebda_seg, dpte.iobase2, iobase2 + ATA_CB_DC); - SET_EBDA2(ebda_seg, dpte.prefix, ((slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0) - | ATA_CB_DH_LBA)); - SET_EBDA2(ebda_seg, dpte.unused, 0xcb); - SET_EBDA2(ebda_seg, dpte.irq, irq); - SET_EBDA2(ebda_seg, dpte.blkcount, 1); - SET_EBDA2(ebda_seg, dpte.dma, 0); - SET_EBDA2(ebda_seg, dpte.pio, 0); - SET_EBDA2(ebda_seg, dpte.options, options); - SET_EBDA2(ebda_seg, dpte.reserved, 0); - SET_EBDA2(ebda_seg, dpte.revision, 0x11); - - u8 sum = checksum_far( - ebda_seg, (void*)offsetof(struct extended_bios_data_area_s, dpte), 15); - SET_EBDA2(ebda_seg, dpte.checksum, -sum); if (size < 66) { disk_ret(regs, DISK_RET_SUCCESS); @@ -614,7 +628,6 @@ disk_1348(struct bregs *regs, struct drive_s *drive_g) SET_INT13DPT(regs, reserved1, 0); SET_INT13DPT(regs, reserved2, 0); - int bdf = GET_GLOBALFLAT(chan_gf->pci_bdf); if (bdf != -1) { SET_INT13DPT(regs, host_bus[0], 'P'); SET_INT13DPT(regs, host_bus[1], 'C'); @@ -634,16 +647,23 @@ disk_1348(struct bregs *regs, struct drive_s *drive_g) SET_INT13DPT(regs, iface_path, iobase1); } - SET_INT13DPT(regs, iface_type[0], 'A'); - SET_INT13DPT(regs, iface_type[1], 'T'); - SET_INT13DPT(regs, iface_type[2], 'A'); - SET_INT13DPT(regs, iface_type[3], 0); + if (type != DTYPE_VIRTIO) { + SET_INT13DPT(regs, iface_type[0], 'A'); + SET_INT13DPT(regs, iface_type[1], 'T'); + SET_INT13DPT(regs, iface_type[2], 'A'); + SET_INT13DPT(regs, iface_type[3], 0); + } else { + SET_INT13DPT(regs, iface_type[0], 'S'); + SET_INT13DPT(regs, iface_type[1], 'C'); + SET_INT13DPT(regs, iface_type[2], 'S'); + SET_INT13DPT(regs, iface_type[3], 'I'); + } SET_INT13DPT(regs, iface_type[4], 0); SET_INT13DPT(regs, iface_type[5], 0); SET_INT13DPT(regs, iface_type[6], 0); SET_INT13DPT(regs, iface_type[7], 0); - SET_INT13DPT(regs, device_path, slave); + SET_INT13DPT(regs, device_path, device_path); SET_INT13DPT(regs, checksum , -checksum_far(regs->ds, (void*)(regs->si+30), 35)); |