Gleb Natapov wrote:
Some guests (such as Linux) expect BIOS to behave according to T13
"Some software expects BIOS ..." instead? "Guests" sounds misleading since this feature can also be expected by userland software.
EDD3.0 spec. T13 spec is much better then Phoenix since it provides more information about interface and device paths. This patch adds
"T13 spec provides more information about interface and device paths."
support for the spec. If guest provides buffer with enough space for
"If caller provides ...".
T13 EDD info return EDD according to T13 spec otherwise use Phoenix one.
Signed-off-by: Gleb Natapov gleb@redhat.com diff --git a/src/disk.c b/src/disk.c index f7bfe9c..8f7c61f 100644 --- a/src/disk.c +++ b/src/disk.c @@ -503,6 +503,7 @@ static void disk_1348(struct bregs *regs, struct drive_s *drive_g) { u16 size = GET_INT13DPT(regs, size);
u16 t13 = size == 74;
// Buffer is too small if (size < 26) {
@@ -553,8 +554,9 @@ disk_1348(struct bregs *regs, struct drive_s *drive_g) // EDD 2.x
int bdf;
- u16 iobase1;
- u64 device_path;
- u16 iobase1 = 0;
- u64 device_path = 0;
- u8 channel = 0; SET_INT13DPT(regs, size, 30); if (type == DTYPE_ATA || type == DTYPE_ATAPI) { u16 ebda_seg = get_ebda_seg();
@@ -573,6 +575,7 @@ disk_1348(struct bregs *regs, struct drive_s *drive_g) iobase1 = GET_GLOBALFLAT(chan_gf->iobase1); bdf = GET_GLOBALFLAT(chan_gf->pci_bdf); device_path = slave;
channel = GET_GLOBALFLAT(chan_gf->chanid); u16 options = 0; if (type == DTYPE_ATA) {
@@ -613,8 +616,6 @@ disk_1348(struct bregs *regs, struct drive_s *drive_g) SET_INT13DPT(regs, dpte_segment, 0); SET_INT13DPT(regs, dpte_offset, 0); bdf = GET_GLOBAL(drive_g->cntl_id);
device_path = 0;
iobase1 = 0;
}
if (size < 66) {
@@ -624,7 +625,7 @@ disk_1348(struct bregs *regs, struct drive_s *drive_g)
// EDD 3.x SET_INT13DPT(regs, key, 0xbedd);
- SET_INT13DPT(regs, dpi_length, 36);
- SET_INT13DPT(regs, dpi_length, t13 ? 44 : 36); SET_INT13DPT(regs, reserved1, 0); SET_INT13DPT(regs, reserved2, 0);
@@ -632,17 +633,20 @@ disk_1348(struct bregs *regs, struct drive_s *drive_g) SET_INT13DPT(regs, host_bus[0], 'P'); SET_INT13DPT(regs, host_bus[1], 'C'); SET_INT13DPT(regs, host_bus[2], 'I');
SET_INT13DPT(regs, host_bus[3], 0);
SET_INT13DPT(regs, 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_INT13DPT(regs, iface_path, path);
} else { // ISA SET_INT13DPT(regs, host_bus[0], 'I'); SET_INT13DPT(regs, host_bus[1], 'S'); SET_INT13DPT(regs, host_bus[2], 'A');
SET_INT13DPT(regs, host_bus[3], 0);
SET_INT13DPT(regs, host_bus[3], ' '); SET_INT13DPT(regs, iface_path, iobase1);
}
@@ -651,22 +655,30 @@ disk_1348(struct bregs *regs, struct drive_s *drive_g) 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[3], ' ');
- 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, iface_type[4], ' ');
- SET_INT13DPT(regs, iface_type[5], ' ');
- SET_INT13DPT(regs, iface_type[6], ' ');
- SET_INT13DPT(regs, iface_type[7], ' ');
- if (t13) {
SET_INT13DPT(regs, t13.device_path[0], device_path);
SET_INT13DPT(regs, t13.device_path[1], 0);
- SET_INT13DPT(regs, device_path, device_path);
SET_INT13DPT(regs, t13.checksum
, -checksum_far(regs->ds, (void*)(regs->si+30), 43));
- } else {
SET_INT13DPT(regs, phoenix.device_path, device_path);
- SET_INT13DPT(regs, checksum
, -checksum_far(regs->ds, (void*)(regs->si+30), 35));
SET_INT13DPT(regs, phoenix.checksum
, -checksum_far(regs->ds, (void*)(regs->si+30), 35));
- }
Should the 0 to space padding part be a separate commit? Some pre-T13 spec BIOS do space padding too.
Sebastian
disk_ret(regs, DISK_RET_SUCCESS);
} diff --git a/src/disk.h b/src/disk.h index f31de73..10a0051 100644 --- a/src/disk.h +++ b/src/disk.h @@ -63,9 +63,18 @@ struct int13dpt_s { u8 host_bus[4]; u8 iface_type[8]; u64 iface_path;
- u64 device_path;
- u8 reserved3;
- u8 checksum;
- union {
struct {
u64 device_path;
u8 reserved3;
u8 checksum;
} phoenix;
struct {
u64 device_path[2];
u8 reserved3;
u8 checksum;
} t13;
- };
} PACKED;
#define GET_INT13DPT(regs,var) \
Gleb.
SeaBIOS mailing list SeaBIOS@seabios.org http://www.seabios.org/mailman/listinfo/seabios