* [Qemu-devel] [SeaBIOS] [PATCH v4 0/5] Add Qemu to SeaBIOS LCHS interface
@ 2019-06-26 12:38 Sam Eiderman
2019-06-26 12:38 ` [Qemu-devel] [SeaBIOS] [PATCH v4 1/5] geometry: Read LCHS from fw_cfg Sam Eiderman
` (5 more replies)
0 siblings, 6 replies; 7+ messages in thread
From: Sam Eiderman @ 2019-06-26 12:38 UTC (permalink / raw)
To: kwolf, qemu-block, qemu-devel, mreitz, seabios, kraxel, kevin
Cc: liran.alon, shmuel.eiderman, karl.heubaum, arbel.moshe
v1:
Non-standard logical geometries break under QEMU.
A virtual disk which contains an operating system which depends on
logical geometries (consistent values being reported from BIOS INT13
AH=08) will most likely break under QEMU/SeaBIOS if it has non-standard
logical geometries - for example 56 SPT (sectors per track).
No matter what QEMU will guess - SeaBIOS, for large enough disks - will
use LBA translation, which will report 63 SPT instead.
In addition we can not enforce SeaBIOS to rely on phyiscal geometries at
all. A virtio-blk-pci virtual disk with 255 phyiscal heads can not
report more than 16 physical heads when moved to an IDE controller, the
ATA spec allows a maximum of 16 heads - this is an artifact of
virtualization.
By supplying the logical geometies directly we are able to support such
"exotic" disks.
We will use fw_cfg to do just that.
v2:
Rename bootdevices fw_cfg key to bios-geoemtry
v3:
Change fw_cfg interface from mixed binary/textual to textual only
Squash commit "config: Add toggle for bootdevice information"
v4:
* Rename TRANSLATION_MACHINE to TRANSLATION_HOST
* Rename "overriden" translation name to "host-supplied"
* Rename overriden_lchs_supplied() to host_lchs_supplied()
* Move sectors and heads check to host_lchs_supplied()
* Reuse duplicate code in boot.c
Sam Eiderman (5):
geometry: Read LCHS from fw_cfg
boot: Reorder functions in boot.c
boot: Build ata and scsi paths in function
geometry: Add boot_lchs_find_*() utility functions
geometry: Apply LCHS values for boot devices
src/Kconfig | 7 ++
src/block.c | 18 +++-
src/block.h | 1 +
src/boot.c | 273 +++++++++++++++++++++++++++++++++++++++++----------
src/hw/ahci.c | 1 +
src/hw/ata.c | 8 ++
src/hw/esp-scsi.c | 2 +
src/hw/lsi-scsi.c | 2 +
src/hw/megasas.c | 1 +
src/hw/mpt-scsi.c | 2 +
src/hw/pvscsi.c | 1 +
src/hw/virtio-blk.c | 2 +
src/hw/virtio-scsi.c | 2 +
src/util.h | 6 ++
14 files changed, 272 insertions(+), 54 deletions(-)
--
2.13.3
^ permalink raw reply [flat|nested] 7+ messages in thread
* [Qemu-devel] [SeaBIOS] [PATCH v4 1/5] geometry: Read LCHS from fw_cfg
2019-06-26 12:38 [Qemu-devel] [SeaBIOS] [PATCH v4 0/5] Add Qemu to SeaBIOS LCHS interface Sam Eiderman
@ 2019-06-26 12:38 ` Sam Eiderman
2019-06-26 12:38 ` [Qemu-devel] [SeaBIOS] [PATCH v4 2/5] boot: Reorder functions in boot.c Sam Eiderman
` (4 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Sam Eiderman @ 2019-06-26 12:38 UTC (permalink / raw)
To: kwolf, qemu-block, qemu-devel, mreitz, seabios, kraxel, kevin
Cc: liran.alon, shmuel.eiderman, karl.heubaum, arbel.moshe
Read bios geometry for boot devices from fw_cfg.
By receiving LCHS values directly from QEMU through fw_cfg we will be
able to support logical geometries which can not be inferred by SeaBIOS
itself.
(For instance: A 8GB virtio-blk hard drive which was originally created
as an IDE and must report LCHS of */32/63 for its operating system to
function will always break under SeaBIOS since a LARGE/LBA translation
will be used, causing the number of reported logical heads to be > 32.)
The only LCHS paravirtual interface available at the moment is for IDE
disks (rtc_read() in get_translation()) and it's limited to a maximum
of 4 disks (this code existed in SeaBIOS's translation function before
SCSI and VirtIO were even introduced).
This is why we create a new interface which allows passing LCHS
information per hdd.
Boot device information is serialized in the following way:
* device_path lcyls lheads lsecs\n
...
* device_path lcyls lheads lsecs\0
Device path is a null terminated string in the "Open Firmware" device
path format, the same path as used in bootorder.
Reviewed-by: Karl Heubaum <karl.heubaum@oracle.com>
Reviewed-by: Arbel Moshe <arbel.moshe@oracle.com>
Signed-off-by: Sam Eiderman <shmuel.eiderman@oracle.com>
---
src/boot.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 74 insertions(+)
diff --git a/src/boot.c b/src/boot.c
index 5acf94fe..a2cb167c 100644
--- a/src/boot.c
+++ b/src/boot.c
@@ -24,6 +24,79 @@
/****************************************************************
+ * Boot device logical geometry
+ ****************************************************************/
+
+typedef struct BootDeviceLCHS {
+ char *name;
+ u32 lcyls;
+ u32 lheads;
+ u32 lsecs;
+} BootDeviceLCHS;
+
+static BootDeviceLCHS *BiosGeometry VARVERIFY32INIT;
+static int BiosGeometryCount;
+
+static char *
+parse_u32(char *cur, u32 *n)
+{
+ u32 m = 0;
+ if (cur) {
+ while ('0' <= *cur && *cur <= '9') {
+ m = 10 * m + (*cur - '0');
+ cur++;
+ }
+ if (*cur != '\0')
+ cur++;
+ }
+ *n = m;
+ return cur;
+}
+
+static void
+loadBiosGeometry(void)
+{
+ char *f = romfile_loadfile("bios-geometry", NULL);
+ if (!f)
+ return;
+
+ int i = 0;
+ BiosGeometryCount = 1;
+ while (f[i]) {
+ if (f[i] == '\n')
+ BiosGeometryCount++;
+ i++;
+ }
+ BiosGeometry = malloc_tmphigh(BiosGeometryCount * sizeof(BootDeviceLCHS));
+ if (!BiosGeometry) {
+ warn_noalloc();
+ free(f);
+ BiosGeometryCount = 0;
+ return;
+ }
+
+ dprintf(1, "bios geometry:\n");
+ i = 0;
+ do {
+ BootDeviceLCHS *d = &BiosGeometry[i];
+ d->name = f;
+ f = strchr(f, '\n');
+ if (f)
+ *(f++) = '\0';
+ char *chs_values = strchr(d->name, ' ');
+ if (chs_values)
+ *(chs_values++) = '\0';
+ chs_values = parse_u32(chs_values, &d->lcyls);
+ chs_values = parse_u32(chs_values, &d->lheads);
+ chs_values = parse_u32(chs_values, &d->lsecs);
+ dprintf(1, "%s: (%u, %u, %u)\n",
+ d->name, d->lcyls, d->lheads, d->lsecs);
+ i++;
+ } while (f);
+}
+
+
+/****************************************************************
* Boot priority ordering
****************************************************************/
@@ -288,6 +361,7 @@ boot_init(void)
BootRetryTime = romfile_loadint("etc/boot-fail-wait", 60*1000);
loadBootOrder();
+ loadBiosGeometry();
}
--
2.13.3
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [Qemu-devel] [SeaBIOS] [PATCH v4 2/5] boot: Reorder functions in boot.c
2019-06-26 12:38 [Qemu-devel] [SeaBIOS] [PATCH v4 0/5] Add Qemu to SeaBIOS LCHS interface Sam Eiderman
2019-06-26 12:38 ` [Qemu-devel] [SeaBIOS] [PATCH v4 1/5] geometry: Read LCHS from fw_cfg Sam Eiderman
@ 2019-06-26 12:38 ` Sam Eiderman
2019-06-26 12:38 ` [Qemu-devel] [SeaBIOS] [PATCH v4 3/5] boot: Build ata and scsi paths in function Sam Eiderman
` (3 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Sam Eiderman @ 2019-06-26 12:38 UTC (permalink / raw)
To: kwolf, qemu-block, qemu-devel, mreitz, seabios, kraxel, kevin
Cc: liran.alon, shmuel.eiderman, karl.heubaum, arbel.moshe
Currently glob_prefix() and build_pci_path() are under the "Boot
priority ordering" section.
Move them to a new "Helper search functions" section since we will reuse
them in the next commits.
Reviewed-by: Karl Heubaum <karl.heubaum@oracle.com>
Reviewed-by: Arbel Moshe <arbel.moshe@oracle.com>
Signed-off-by: Sam Eiderman <shmuel.eiderman@oracle.com>
---
src/boot.c | 94 ++++++++++++++++++++++++++++++++------------------------------
1 file changed, 49 insertions(+), 45 deletions(-)
diff --git a/src/boot.c b/src/boot.c
index a2cb167c..70f639f4 100644
--- a/src/boot.c
+++ b/src/boot.c
@@ -22,6 +22,55 @@
#include "util.h" // irqtimer_calc
#include "tcgbios.h" // tpm_*
+/****************************************************************
+ * Helper search functions
+ ****************************************************************/
+
+// See if 'str' starts with 'glob' - if glob contains an '*' character
+// it will match any number of characters in str that aren't a '/' or
+// the next glob character.
+static char *
+glob_prefix(const char *glob, const char *str)
+{
+ for (;;) {
+ if (!*glob && (!*str || *str == '/'))
+ return (char*)str;
+ if (*glob == '*') {
+ if (!*str || *str == '/' || *str == glob[1])
+ glob++;
+ else
+ str++;
+ continue;
+ }
+ if (*glob != *str)
+ return NULL;
+ glob++;
+ str++;
+ }
+}
+
+#define FW_PCI_DOMAIN "/pci@i0cf8"
+
+static char *
+build_pci_path(char *buf, int max, const char *devname, struct pci_device *pci)
+{
+ // Build the string path of a bdf - for example: /pci@i0cf8/isa@1,2
+ char *p = buf;
+ if (pci->parent) {
+ p = build_pci_path(p, max, "pci-bridge", pci->parent);
+ } else {
+ p += snprintf(p, buf+max-p, "%s", FW_PCI_DOMAIN);
+ if (pci->rootbus)
+ p += snprintf(p, buf+max-p, ",%x", pci->rootbus);
+ }
+
+ int dev = pci_bdf_to_dev(pci->bdf), fn = pci_bdf_to_fn(pci->bdf);
+ p += snprintf(p, buf+max-p, "/%s@%x", devname, dev);
+ if (fn)
+ p += snprintf(p, buf+max-p, ",%x", fn);
+ return p;
+}
+
/****************************************************************
* Boot device logical geometry
@@ -141,29 +190,6 @@ loadBootOrder(void)
} while (f);
}
-// See if 'str' starts with 'glob' - if glob contains an '*' character
-// it will match any number of characters in str that aren't a '/' or
-// the next glob character.
-static char *
-glob_prefix(const char *glob, const char *str)
-{
- for (;;) {
- if (!*glob && (!*str || *str == '/'))
- return (char*)str;
- if (*glob == '*') {
- if (!*str || *str == '/' || *str == glob[1])
- glob++;
- else
- str++;
- continue;
- }
- if (*glob != *str)
- return NULL;
- glob++;
- str++;
- }
-}
-
// Search the bootorder list for the given glob pattern.
static int
find_prio(const char *glob)
@@ -176,28 +202,6 @@ find_prio(const char *glob)
return -1;
}
-#define FW_PCI_DOMAIN "/pci@i0cf8"
-
-static char *
-build_pci_path(char *buf, int max, const char *devname, struct pci_device *pci)
-{
- // Build the string path of a bdf - for example: /pci@i0cf8/isa@1,2
- char *p = buf;
- if (pci->parent) {
- p = build_pci_path(p, max, "pci-bridge", pci->parent);
- } else {
- p += snprintf(p, buf+max-p, "%s", FW_PCI_DOMAIN);
- if (pci->rootbus)
- p += snprintf(p, buf+max-p, ",%x", pci->rootbus);
- }
-
- int dev = pci_bdf_to_dev(pci->bdf), fn = pci_bdf_to_fn(pci->bdf);
- p += snprintf(p, buf+max-p, "/%s@%x", devname, dev);
- if (fn)
- p += snprintf(p, buf+max-p, ",%x", fn);
- return p;
-}
-
int bootprio_find_pci_device(struct pci_device *pci)
{
if (CONFIG_CSM)
--
2.13.3
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [Qemu-devel] [SeaBIOS] [PATCH v4 3/5] boot: Build ata and scsi paths in function
2019-06-26 12:38 [Qemu-devel] [SeaBIOS] [PATCH v4 0/5] Add Qemu to SeaBIOS LCHS interface Sam Eiderman
2019-06-26 12:38 ` [Qemu-devel] [SeaBIOS] [PATCH v4 1/5] geometry: Read LCHS from fw_cfg Sam Eiderman
2019-06-26 12:38 ` [Qemu-devel] [SeaBIOS] [PATCH v4 2/5] boot: Reorder functions in boot.c Sam Eiderman
@ 2019-06-26 12:38 ` Sam Eiderman
2019-06-26 12:38 ` [Qemu-devel] [SeaBIOS] [PATCH v4 4/5] geometry: Add boot_lchs_find_*() utility functions Sam Eiderman
` (2 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Sam Eiderman @ 2019-06-26 12:38 UTC (permalink / raw)
To: kwolf, qemu-block, qemu-devel, mreitz, seabios, kraxel, kevin
Cc: liran.alon, shmuel.eiderman, karl.heubaum, arbel.moshe
Introduce build_scsi_path() and build_ata_path().
We will reuse these functions in the next commit.
Reviewed-by: Karl Heubaum <karl.heubaum@oracle.com>
Reviewed-by: Arbel Moshe <arbel.moshe@oracle.com>
Signed-off-by: Sam Eiderman <shmuel.eiderman@oracle.com>
---
src/boot.c | 36 ++++++++++++++++++++++++++++--------
1 file changed, 28 insertions(+), 8 deletions(-)
diff --git a/src/boot.c b/src/boot.c
index 70f639f4..52e1c8e6 100644
--- a/src/boot.c
+++ b/src/boot.c
@@ -71,6 +71,30 @@ build_pci_path(char *buf, int max, const char *devname, struct pci_device *pci)
return p;
}
+static char *
+build_scsi_path(char *buf, int max,
+ struct pci_device *pci, int target, int lun)
+{
+ // Build the string path of a scsi drive - for example:
+ // /pci@i0cf8/scsi@5/channel@0/disk@1,0
+ char *p;
+ p = build_pci_path(buf, max, "*", pci);
+ p += snprintf(p, buf+max-p, "/*@0/*@%x,%x", target, lun);
+ return p;
+}
+
+static char *
+build_ata_path(char *buf, int max,
+ struct pci_device *pci, int chanid, int slave)
+{
+ // Build the string path of an ata drive - for example:
+ // /pci@i0cf8/ide@1,1/drive@1/disk@0
+ char *p;
+ p = build_pci_path(buf, max, "*", pci);
+ p += snprintf(p, buf+max-p, "/drive@%x/disk@%x", chanid, slave);
+ return p;
+}
+
/****************************************************************
* Boot device logical geometry
@@ -221,10 +245,8 @@ int bootprio_find_scsi_device(struct pci_device *pci, int target, int lun)
if (!pci)
// support only pci machine for now
return -1;
- // Find scsi drive - for example: /pci@i0cf8/scsi@5/channel@0/disk@1,0
- char desc[256], *p;
- p = build_pci_path(desc, sizeof(desc), "*", pci);
- snprintf(p, desc+sizeof(desc)-p, "/*@0/*@%x,%x", target, lun);
+ char desc[256];
+ build_scsi_path(desc, sizeof(desc), pci, target, lun);
return find_prio(desc);
}
@@ -237,10 +259,8 @@ int bootprio_find_ata_device(struct pci_device *pci, int chanid, int slave)
if (!pci)
// support only pci machine for now
return -1;
- // Find ata drive - for example: /pci@i0cf8/ide@1,1/drive@1/disk@0
- char desc[256], *p;
- p = build_pci_path(desc, sizeof(desc), "*", pci);
- snprintf(p, desc+sizeof(desc)-p, "/drive@%x/disk@%x", chanid, slave);
+ char desc[256];
+ build_ata_path(desc, sizeof(desc), pci, chanid, slave);
return find_prio(desc);
}
--
2.13.3
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [Qemu-devel] [SeaBIOS] [PATCH v4 4/5] geometry: Add boot_lchs_find_*() utility functions
2019-06-26 12:38 [Qemu-devel] [SeaBIOS] [PATCH v4 0/5] Add Qemu to SeaBIOS LCHS interface Sam Eiderman
` (2 preceding siblings ...)
2019-06-26 12:38 ` [Qemu-devel] [SeaBIOS] [PATCH v4 3/5] boot: Build ata and scsi paths in function Sam Eiderman
@ 2019-06-26 12:38 ` Sam Eiderman
2019-06-26 12:38 ` [Qemu-devel] [SeaBIOS] [PATCH v4 5/5] geometry: Apply LCHS values for boot devices Sam Eiderman
2019-07-01 7:44 ` [Qemu-devel] [SeaBIOS] [PATCH v4 0/5] Add Qemu to SeaBIOS LCHS interface Gerd Hoffmann
5 siblings, 0 replies; 7+ messages in thread
From: Sam Eiderman @ 2019-06-26 12:38 UTC (permalink / raw)
To: kwolf, qemu-block, qemu-devel, mreitz, seabios, kraxel, kevin
Cc: liran.alon, shmuel.eiderman, karl.heubaum, arbel.moshe
Adding the following utility functions:
* boot_lchs_find_pci_device
* boot_lchs_find_scsi_device
* boot_lchs_find_ata_device
These will be used to apply LCHS values received through fw_cfg.
Reviewed-by: Karl Heubaum <karl.heubaum@oracle.com>
Reviewed-by: Arbel Moshe <arbel.moshe@oracle.com>
Signed-off-by: Sam Eiderman <shmuel.eiderman@oracle.com>
---
src/Kconfig | 7 +++++++
src/boot.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/util.h | 6 ++++++
3 files changed, 82 insertions(+)
diff --git a/src/Kconfig b/src/Kconfig
index 55a87cb7..6606ce4d 100644
--- a/src/Kconfig
+++ b/src/Kconfig
@@ -72,6 +72,13 @@ endchoice
help
Support controlling of the boot order via the fw_cfg/CBFS
"bootorder" file.
+ config HOST_BIOS_GEOMETRY
+ depends on BOOT
+ bool "Boot device bios geometry override"
+ default y
+ help
+ Support overriding bios (logical) geometry of boot devices via the
+ fw_cfg/CBFS "bios-geometry" file.
config COREBOOT_FLASH
depends on COREBOOT
diff --git a/src/boot.c b/src/boot.c
index 52e1c8e6..ea18194d 100644
--- a/src/boot.c
+++ b/src/boot.c
@@ -129,6 +129,8 @@ parse_u32(char *cur, u32 *n)
static void
loadBiosGeometry(void)
{
+ if (!CONFIG_HOST_BIOS_GEOMETRY)
+ return;
char *f = romfile_loadfile("bios-geometry", NULL);
if (!f)
return;
@@ -168,6 +170,73 @@ loadBiosGeometry(void)
} while (f);
}
+// Search the bios-geometry list for the given glob pattern.
+static BootDeviceLCHS *
+boot_lchs_find(const char *glob)
+{
+ dprintf(1, "Searching bios-geometry for: %s\n", glob);
+ int i;
+ for (i = 0; i < BiosGeometryCount; i++)
+ if (glob_prefix(glob, BiosGeometry[i].name))
+ return &BiosGeometry[i];
+ return NULL;
+}
+
+int boot_lchs_find_pci_device(struct pci_device *pci, struct chs_s *chs)
+{
+ if (!CONFIG_HOST_BIOS_GEOMETRY)
+ return -1;
+ char desc[256];
+ build_pci_path(desc, sizeof(desc), "*", pci);
+ BootDeviceLCHS *b = boot_lchs_find(desc);
+ if (!b)
+ return -1;
+ chs->cylinder = (u16)b->lcyls;
+ chs->head = (u16)b->lheads;
+ chs->sector = (u16)b->lsecs;
+ return 0;
+}
+
+int boot_lchs_find_scsi_device(struct pci_device *pci, int target, int lun,
+ struct chs_s *chs)
+{
+ if (!CONFIG_HOST_BIOS_GEOMETRY)
+ return -1;
+ if (!pci)
+ // support only pci machine for now
+ return -1;
+ // Find scsi drive - for example: /pci@i0cf8/scsi@5/channel@0/disk@1,0
+ char desc[256];
+ build_scsi_path(desc, sizeof(desc), pci, target, lun);
+ BootDeviceLCHS *b = boot_lchs_find(desc);
+ if (!b)
+ return -1;
+ chs->cylinder = (u16)b->lcyls;
+ chs->head = (u16)b->lheads;
+ chs->sector = (u16)b->lsecs;
+ return 0;
+}
+
+int boot_lchs_find_ata_device(struct pci_device *pci, int chanid, int slave,
+ struct chs_s *chs)
+{
+ if (!CONFIG_HOST_BIOS_GEOMETRY)
+ return -1;
+ if (!pci)
+ // support only pci machine for now
+ return -1;
+ // Find ata drive - for example: /pci@i0cf8/ide@1,1/drive@1/disk@0
+ char desc[256];
+ build_ata_path(desc, sizeof(desc), pci, chanid, slave);
+ BootDeviceLCHS *b = boot_lchs_find(desc);
+ if (!b)
+ return -1;
+ chs->cylinder = (u16)b->lcyls;
+ chs->head = (u16)b->lheads;
+ chs->sector = (u16)b->lsecs;
+ return 0;
+}
+
/****************************************************************
* Boot priority ordering
diff --git a/src/util.h b/src/util.h
index e2afc80c..b173fa88 100644
--- a/src/util.h
+++ b/src/util.h
@@ -38,6 +38,12 @@ struct usbdevice_s;
int bootprio_find_usb(struct usbdevice_s *usbdev, int lun);
int get_keystroke_full(int msec);
int get_keystroke(int msec);
+struct chs_s;
+int boot_lchs_find_pci_device(struct pci_device *pci, struct chs_s *chs);
+int boot_lchs_find_scsi_device(struct pci_device *pci, int target, int lun,
+ struct chs_s *chs);
+int boot_lchs_find_ata_device(struct pci_device *pci, int chanid, int slave,
+ struct chs_s *chs);
// bootsplash.c
void enable_vga_console(void);
--
2.13.3
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [Qemu-devel] [SeaBIOS] [PATCH v4 5/5] geometry: Apply LCHS values for boot devices
2019-06-26 12:38 [Qemu-devel] [SeaBIOS] [PATCH v4 0/5] Add Qemu to SeaBIOS LCHS interface Sam Eiderman
` (3 preceding siblings ...)
2019-06-26 12:38 ` [Qemu-devel] [SeaBIOS] [PATCH v4 4/5] geometry: Add boot_lchs_find_*() utility functions Sam Eiderman
@ 2019-06-26 12:38 ` Sam Eiderman
2019-07-01 7:44 ` [Qemu-devel] [SeaBIOS] [PATCH v4 0/5] Add Qemu to SeaBIOS LCHS interface Gerd Hoffmann
5 siblings, 0 replies; 7+ messages in thread
From: Sam Eiderman @ 2019-06-26 12:38 UTC (permalink / raw)
To: kwolf, qemu-block, qemu-devel, mreitz, seabios, kraxel, kevin
Cc: liran.alon, shmuel.eiderman, karl.heubaum, arbel.moshe
Boot devices which use overriden LCHS values are:
* ata
* ahci
* scsi
* esp
* lsi
* megasas
* mpt
* pvscsi
* virtio
* virtio-blk
We use these values in get_translation() and setup_translation() by
introducing a new translation type: "TRANSLATION_HOST".
We treat this translation as TRANSLATION_NONE in fill_ata_edd(),
although this does not really matter since now the translation between
physical and logical geometry does not exist.
Reviewed-by: Karl Heubaum <karl.heubaum@oracle.com>
Reviewed-by: Arbel Moshe <arbel.moshe@oracle.com>
Signed-off-by: Sam Eiderman <shmuel.eiderman@oracle.com>
---
src/block.c | 18 +++++++++++++++++-
src/block.h | 1 +
src/hw/ahci.c | 1 +
src/hw/ata.c | 8 ++++++++
src/hw/esp-scsi.c | 2 ++
src/hw/lsi-scsi.c | 2 ++
src/hw/megasas.c | 1 +
src/hw/mpt-scsi.c | 2 ++
src/hw/pvscsi.c | 1 +
src/hw/virtio-blk.c | 2 ++
src/hw/virtio-scsi.c | 2 ++
11 files changed, 39 insertions(+), 1 deletion(-)
diff --git a/src/block.c b/src/block.c
index f73ec18c..1f600b85 100644
--- a/src/block.c
+++ b/src/block.c
@@ -69,9 +69,18 @@ int create_bounce_buf(void)
* Disk geometry translation
****************************************************************/
+static int
+host_lchs_supplied(struct drive_s *drive)
+{
+ return (drive->lchs.head <= 255 &&
+ drive->lchs.sector > 0 && drive->lchs.sector <= 63);
+}
+
static u8
get_translation(struct drive_s *drive)
{
+ if (host_lchs_supplied(drive))
+ return TRANSLATION_HOST;
u8 type = drive->type;
if (CONFIG_QEMU && type == DTYPE_ATA) {
// Emulators pass in the translation info via nvram.
@@ -159,6 +168,12 @@ setup_translation(struct drive_s *drive)
break;
}
break;
+ case TRANSLATION_HOST:
+ desc = "host-supplied";
+ cylinders = drive->lchs.cylinder;
+ heads = drive->lchs.head;
+ spt = drive->lchs.sector;
+ break;
}
// clip to 1024 cylinders in lchs
if (cylinders > 1024)
@@ -423,7 +438,8 @@ fill_ata_edd(struct segoff_s edd, struct drive_s *drive_gf)
u16 options = 0;
if (GET_GLOBALFLAT(drive_gf->type) == DTYPE_ATA) {
u8 translation = GET_GLOBALFLAT(drive_gf->translation);
- if (translation != TRANSLATION_NONE) {
+ if ((translation != TRANSLATION_NONE) &&
+ (translation != TRANSLATION_HOST)) {
options |= 1<<3; // CHS translation
if (translation == TRANSLATION_LBA)
options |= 1<<9;
diff --git a/src/block.h b/src/block.h
index f64e8807..c1b8d734 100644
--- a/src/block.h
+++ b/src/block.h
@@ -90,6 +90,7 @@ struct drive_s {
#define TRANSLATION_LBA 1
#define TRANSLATION_LARGE 2
#define TRANSLATION_RECHS 3
+#define TRANSLATION_HOST 4
#define EXTTYPE_FLOPPY 0
#define EXTTYPE_HD 1
diff --git a/src/hw/ahci.c b/src/hw/ahci.c
index 1746e7a1..97a072a1 100644
--- a/src/hw/ahci.c
+++ b/src/hw/ahci.c
@@ -593,6 +593,7 @@ static int ahci_port_setup(struct ahci_port_s *port)
, ata_extract_version(buffer));
port->prio = bootprio_find_ata_device(ctrl->pci_tmp, pnr, 0);
}
+ boot_lchs_find_ata_device(ctrl->pci_tmp, pnr, 0, &(port->drive.lchs));
return 0;
}
diff --git a/src/hw/ata.c b/src/hw/ata.c
index b6e073cf..f788ce71 100644
--- a/src/hw/ata.c
+++ b/src/hw/ata.c
@@ -755,6 +755,10 @@ init_drive_atapi(struct atadrive_s *dummy, u16 *buffer)
int prio = bootprio_find_ata_device(adrive->chan_gf->pci_tmp,
adrive->chan_gf->chanid,
adrive->slave);
+ boot_lchs_find_ata_device(adrive->chan_gf->pci_tmp,
+ adrive->chan_gf->chanid,
+ adrive->slave,
+ &(adrive->drive.lchs));
boot_add_cd(&adrive->drive, desc, prio);
}
@@ -805,6 +809,10 @@ init_drive_ata(struct atadrive_s *dummy, u16 *buffer)
int prio = bootprio_find_ata_device(adrive->chan_gf->pci_tmp,
adrive->chan_gf->chanid,
adrive->slave);
+ boot_lchs_find_ata_device(adrive->chan_gf->pci_tmp,
+ adrive->chan_gf->chanid,
+ adrive->slave,
+ &(adrive->drive.lchs));
// Register with bcv system.
boot_add_hd(&adrive->drive, desc, prio);
diff --git a/src/hw/esp-scsi.c b/src/hw/esp-scsi.c
index ffd86d0f..cc25f227 100644
--- a/src/hw/esp-scsi.c
+++ b/src/hw/esp-scsi.c
@@ -181,6 +181,8 @@ esp_scsi_add_lun(u32 lun, struct drive_s *tmpl_drv)
char *name = znprintf(MAXDESCSIZE, "esp %pP %d:%d",
llun->pci, llun->target, llun->lun);
+ boot_lchs_find_scsi_device(llun->pci, llun->target, llun->lun,
+ &(llun->drive.lchs));
int prio = bootprio_find_scsi_device(llun->pci, llun->target, llun->lun);
int ret = scsi_drive_setup(&llun->drive, name, prio);
free(name);
diff --git a/src/hw/lsi-scsi.c b/src/hw/lsi-scsi.c
index d5fc3e45..cbaa2acd 100644
--- a/src/hw/lsi-scsi.c
+++ b/src/hw/lsi-scsi.c
@@ -158,6 +158,8 @@ lsi_scsi_add_lun(u32 lun, struct drive_s *tmpl_drv)
lsi_scsi_init_lun(llun, tmpl_llun->pci, tmpl_llun->iobase,
tmpl_llun->target, lun);
+ boot_lchs_find_scsi_device(llun->pci, llun->target, llun->lun,
+ &(llun->drive.lchs));
char *name = znprintf(MAXDESCSIZE, "lsi %pP %d:%d",
llun->pci, llun->target, llun->lun);
int prio = bootprio_find_scsi_device(llun->pci, llun->target, llun->lun);
diff --git a/src/hw/megasas.c b/src/hw/megasas.c
index d2675804..87b8beec 100644
--- a/src/hw/megasas.c
+++ b/src/hw/megasas.c
@@ -225,6 +225,7 @@ megasas_add_lun(struct pci_device *pci, u32 iobase, u8 target, u8 lun)
free(mlun);
return -1;
}
+ boot_lchs_find_scsi_device(pci, target, lun, &(mlun->drive.lchs));
name = znprintf(MAXDESCSIZE, "MegaRAID SAS (PCI %pP) LD %d:%d"
, pci, target, lun);
prio = bootprio_find_scsi_device(pci, target, lun);
diff --git a/src/hw/mpt-scsi.c b/src/hw/mpt-scsi.c
index 1faede6a..570b2126 100644
--- a/src/hw/mpt-scsi.c
+++ b/src/hw/mpt-scsi.c
@@ -221,6 +221,8 @@ mpt_scsi_add_lun(u32 lun, struct drive_s *tmpl_drv)
mpt_scsi_init_lun(llun, tmpl_llun->pci, tmpl_llun->iobase,
tmpl_llun->target, lun);
+ boot_lchs_find_scsi_device(llun->pci, llun->target, llun->lun,
+ &(llun->drive.lchs));
char *name = znprintf(MAXDESCSIZE, "mpt %pP %d:%d",
llun->pci, llun->target, llun->lun);
int prio = bootprio_find_scsi_device(llun->pci, llun->target, llun->lun);
diff --git a/src/hw/pvscsi.c b/src/hw/pvscsi.c
index 9d7d68d8..3e5171ad 100644
--- a/src/hw/pvscsi.c
+++ b/src/hw/pvscsi.c
@@ -273,6 +273,7 @@ pvscsi_add_lun(struct pci_device *pci, void *iobase,
plun->iobase = iobase;
plun->ring_dsc = ring_dsc;
+ boot_lchs_find_scsi_device(pci, target, lun, &(plun->drive.lchs));
char *name = znprintf(MAXDESCSIZE, "pvscsi %pP %d:%d", pci, target, lun);
int prio = bootprio_find_scsi_device(pci, target, lun);
int ret = scsi_drive_setup(&plun->drive, name, prio);
diff --git a/src/hw/virtio-blk.c b/src/hw/virtio-blk.c
index 88d7e54a..3e615b26 100644
--- a/src/hw/virtio-blk.c
+++ b/src/hw/virtio-blk.c
@@ -183,6 +183,8 @@ init_virtio_blk(void *data)
status |= VIRTIO_CONFIG_S_DRIVER_OK;
vp_set_status(&vdrive->vp, status);
+
+ boot_lchs_find_pci_device(pci, &vdrive->drive.lchs);
return;
fail:
diff --git a/src/hw/virtio-scsi.c b/src/hw/virtio-scsi.c
index a87cad88..e1e2f5d4 100644
--- a/src/hw/virtio-scsi.c
+++ b/src/hw/virtio-scsi.c
@@ -121,6 +121,8 @@ virtio_scsi_add_lun(u32 lun, struct drive_s *tmpl_drv)
virtio_scsi_init_lun(vlun, tmpl_vlun->pci, tmpl_vlun->vp, tmpl_vlun->vq,
tmpl_vlun->target, lun);
+ boot_lchs_find_scsi_device(vlun->pci, vlun->target, vlun->lun,
+ &(vlun->drive.lchs));
int prio = bootprio_find_scsi_device(vlun->pci, vlun->target, vlun->lun);
int ret = scsi_drive_setup(&vlun->drive, "virtio-scsi", prio);
if (ret)
--
2.13.3
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [Qemu-devel] [SeaBIOS] [PATCH v4 0/5] Add Qemu to SeaBIOS LCHS interface
2019-06-26 12:38 [Qemu-devel] [SeaBIOS] [PATCH v4 0/5] Add Qemu to SeaBIOS LCHS interface Sam Eiderman
` (4 preceding siblings ...)
2019-06-26 12:38 ` [Qemu-devel] [SeaBIOS] [PATCH v4 5/5] geometry: Apply LCHS values for boot devices Sam Eiderman
@ 2019-07-01 7:44 ` Gerd Hoffmann
5 siblings, 0 replies; 7+ messages in thread
From: Gerd Hoffmann @ 2019-07-01 7:44 UTC (permalink / raw)
To: Sam Eiderman
Cc: kwolf, qemu-block, arbel.moshe, seabios, qemu-devel, mreitz,
kevin, liran.alon, karl.heubaum
On Wed, Jun 26, 2019 at 03:38:11PM +0300, Sam Eiderman wrote:
> v1:
>
> Non-standard logical geometries break under QEMU.
>
> A virtual disk which contains an operating system which depends on
> logical geometries (consistent values being reported from BIOS INT13
> AH=08) will most likely break under QEMU/SeaBIOS if it has non-standard
> logical geometries - for example 56 SPT (sectors per track).
> No matter what QEMU will guess - SeaBIOS, for large enough disks - will
> use LBA translation, which will report 63 SPT instead.
>
> In addition we can not enforce SeaBIOS to rely on phyiscal geometries at
> all. A virtio-blk-pci virtual disk with 255 phyiscal heads can not
> report more than 16 physical heads when moved to an IDE controller, the
> ATA spec allows a maximum of 16 heads - this is an artifact of
> virtualization.
>
> By supplying the logical geometies directly we are able to support such
> "exotic" disks.
>
> We will use fw_cfg to do just that.
>
> v2:
>
> Rename bootdevices fw_cfg key to bios-geoemtry
>
> v3:
>
> Change fw_cfg interface from mixed binary/textual to textual only
> Squash commit "config: Add toggle for bootdevice information"
>
> v4:
>
> * Rename TRANSLATION_MACHINE to TRANSLATION_HOST
> * Rename "overriden" translation name to "host-supplied"
> * Rename overriden_lchs_supplied() to host_lchs_supplied()
> * Move sectors and heads check to host_lchs_supplied()
> * Reuse duplicate code in boot.c
Looks all sane to me.
Usual workflow is to have to qemu bits merged first, so we'll go wait
for that.
cheers,
Gerd
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2019-07-01 7:46 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-06-26 12:38 [Qemu-devel] [SeaBIOS] [PATCH v4 0/5] Add Qemu to SeaBIOS LCHS interface Sam Eiderman
2019-06-26 12:38 ` [Qemu-devel] [SeaBIOS] [PATCH v4 1/5] geometry: Read LCHS from fw_cfg Sam Eiderman
2019-06-26 12:38 ` [Qemu-devel] [SeaBIOS] [PATCH v4 2/5] boot: Reorder functions in boot.c Sam Eiderman
2019-06-26 12:38 ` [Qemu-devel] [SeaBIOS] [PATCH v4 3/5] boot: Build ata and scsi paths in function Sam Eiderman
2019-06-26 12:38 ` [Qemu-devel] [SeaBIOS] [PATCH v4 4/5] geometry: Add boot_lchs_find_*() utility functions Sam Eiderman
2019-06-26 12:38 ` [Qemu-devel] [SeaBIOS] [PATCH v4 5/5] geometry: Apply LCHS values for boot devices Sam Eiderman
2019-07-01 7:44 ` [Qemu-devel] [SeaBIOS] [PATCH v4 0/5] Add Qemu to SeaBIOS LCHS interface Gerd Hoffmann
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).