diff options
author | Kevin O'Connor <kevin@koconnor.net> | 2015-08-05 15:02:01 -0400 |
---|---|---|
committer | Kevin O'Connor <kevin@koconnor.net> | 2015-08-17 11:38:48 -0400 |
commit | b3f1fad3c4e0f272e34c17b70741a16d1d3d3237 (patch) | |
tree | 1f59880a3214ae70ed0ea0ee3924a2e4c581e950 /src/block.c | |
parent | 8aad64e22a133101617d9a4f78ebc61199680361 (diff) | |
download | seabios-b3f1fad3c4e0f272e34c17b70741a16d1d3d3237.tar.gz |
edd: Reduce parameters to fill_generic_edd()
Have callers of fill_generic_edd() calculate the edd iface_path
field. Have callers determine if the bus type is PCI vs ISA.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Diffstat (limited to 'src/block.c')
-rw-r--r-- | src/block.c | 77 |
1 files changed, 45 insertions, 32 deletions
diff --git a/src/block.c b/src/block.c index cd732c19..97e05fa6 100644 --- a/src/block.c +++ b/src/block.c @@ -287,10 +287,18 @@ map_floppy_drive(struct drive_s *drive) * Extended Disk Drive (EDD) get drive parameters ****************************************************************/ +// flags for bus_iface field in fill_generic_edd() +#define EDD_ISA 0x01 +#define EDD_PCI 0x02 +#define EDD_BUS_MASK 0x0f +#define EDD_ATA 0x10 +#define EDD_SCSI 0x20 +#define EDD_IFACE_MASK 0xf0 + +// Fill in EDD info static int fill_generic_edd(struct segoff_s edd, struct drive_s *drive_gf - , u32 dpte_so, char *iface_type - , int bdf, u8 channel, u16 iobase, u64 device_path) + , u32 dpte_so, u8 bus_iface, u32 iface_path, u32 device_path) { u16 seg = edd.seg; struct int13dpt_s *param_far = (void*)(edd.offset+0); @@ -342,7 +350,7 @@ fill_generic_edd(struct segoff_s edd, struct drive_s *drive_gf SET_FARVAR(seg, param_far->size, 30); SET_FARVAR(seg, param_far->dpte.segoff, dpte_so); - if (size < 66 || !iface_type) + if (size < 66 || !bus_iface) return DISK_RET_SUCCESS; // EDD 3.x @@ -351,32 +359,22 @@ fill_generic_edd(struct segoff_s edd, struct drive_s *drive_gf SET_FARVAR(seg, param_far->reserved1, 0); SET_FARVAR(seg, param_far->reserved2, 0); - int i; - for (i=0; i<sizeof(param_far->iface_type); i++) - SET_FARVAR(seg, param_far->iface_type[i], GET_GLOBAL(iface_type[i])); - - if (bdf != -1) { - SET_FARVAR(seg, param_far->host_bus[0], 'P'); - SET_FARVAR(seg, param_far->host_bus[1], 'C'); - SET_FARVAR(seg, param_far->host_bus[2], 'I'); - SET_FARVAR(seg, param_far->host_bus[3], ' '); - - u32 path = (pci_bdf_to_bus(bdf) | (pci_bdf_to_dev(bdf) << 8) - | (pci_bdf_to_fn(bdf) << 16)); - if (t13) - path |= channel << 24; - - SET_FARVAR(seg, param_far->iface_path, path); - } else { - // ISA - SET_FARVAR(seg, param_far->host_bus[0], 'I'); - SET_FARVAR(seg, param_far->host_bus[1], 'S'); - SET_FARVAR(seg, param_far->host_bus[2], 'A'); - SET_FARVAR(seg, param_far->host_bus[3], ' '); - - SET_FARVAR(seg, param_far->iface_path, iobase); + const char *host_bus = "ISA "; + if ((bus_iface & EDD_BUS_MASK) == EDD_PCI) { + host_bus = "PCI "; + if (!t13) + // Phoenix v3 spec (pre t13) did not define the PCI channel field + iface_path &= 0x00ffffff; } - + memcpy_far(seg, param_far->host_bus, SEG_BIOS, host_bus + , sizeof(param_far->host_bus)); + SET_FARVAR(seg, param_far->iface_path, iface_path); + + const char *iface_type = "ATA "; + if ((bus_iface & EDD_IFACE_MASK) == EDD_SCSI) + iface_type = "SCSI "; + memcpy_far(seg, param_far->iface_type, SEG_BIOS, iface_type + , sizeof(param_far->iface_type)); if (t13) { SET_FARVAR(seg, param_far->t13.device_path[0], device_path); SET_FARVAR(seg, param_far->t13.device_path[1], 0); @@ -393,8 +391,17 @@ fill_generic_edd(struct segoff_s edd, struct drive_s *drive_gf return DISK_RET_SUCCESS; } +// Build an EDD "iface_path" field for a PCI device +static u32 +edd_pci_path(u16 bdf, u8 channel) +{ + return (pci_bdf_to_bus(bdf) | (pci_bdf_to_dev(bdf) << 8) + | (pci_bdf_to_fn(bdf) << 16) | ((u32)channel << 24)); +} + struct dpte_s DefaultDPTE VARLOW; +// EDD info for ATA and ATAPI drives static int fill_ata_edd(struct segoff_s edd, struct drive_s *drive_gf) { @@ -447,11 +454,17 @@ fill_ata_edd(struct segoff_s edd, struct drive_s *drive_gf) u8 sum = checksum_far(SEG_LOW, &DefaultDPTE, 15); SET_LOW(DefaultDPTE.checksum, -sum); + u32 bustype = EDD_ISA, ifpath = iobase1; + if (bdf >= 0) { + bustype = EDD_PCI; + ifpath = edd_pci_path(bdf, channel); + } return fill_generic_edd( edd, drive_gf, SEGOFF(SEG_LOW, (u32)&DefaultDPTE).segoff - , "ATA ", bdf, channel, iobase1, slave); + , bustype | EDD_ATA, ifpath, slave); } +// Fill Extended Disk Drive (EDD) "Get drive parameters" info for a drive int noinline fill_edd(struct segoff_s edd, struct drive_s *drive_gf) { @@ -462,10 +475,10 @@ fill_edd(struct segoff_s edd, struct drive_s *drive_gf) case DTYPE_VIRTIO_BLK: case DTYPE_VIRTIO_SCSI: return fill_generic_edd( - edd, drive_gf, 0xffffffff - , "SCSI ", GET_GLOBALFLAT(drive_gf->cntl_id), 0, 0, 0); + edd, drive_gf, 0xffffffff, EDD_PCI | EDD_SCSI + , edd_pci_path(GET_GLOBALFLAT(drive_gf->cntl_id), 0), 0); default: - return fill_generic_edd(edd, drive_gf, 0, NULL, 0, 0, 0, 0); + return fill_generic_edd(edd, drive_gf, 0, 0, 0, 0); } } |