aboutsummaryrefslogtreecommitdiff
path: root/src/block.c
diff options
context:
space:
mode:
authorKevin O'Connor <kevin@koconnor.net>2015-08-05 15:02:01 -0400
committerKevin O'Connor <kevin@koconnor.net>2015-08-17 11:38:48 -0400
commitb3f1fad3c4e0f272e34c17b70741a16d1d3d3237 (patch)
tree1f59880a3214ae70ed0ea0ee3924a2e4c581e950 /src/block.c
parent8aad64e22a133101617d9a4f78ebc61199680361 (diff)
downloadseabios-hppa-b3f1fad3c4e0f272e34c17b70741a16d1d3d3237.zip
seabios-hppa-b3f1fad3c4e0f272e34c17b70741a16d1d3d3237.tar.gz
seabios-hppa-b3f1fad3c4e0f272e34c17b70741a16d1d3d3237.tar.bz2
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.c77
1 files changed, 45 insertions, 32 deletions
diff --git a/src/block.c b/src/block.c
index cd732c1..97e05fa 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);
}
}