This is the simplest way to avoid breaking boot on USB sticks that
stall when asked for the MODE SENSE page 4. Some old sticks do
not support the MODE SENSE command at all and just return a
"medium may have changed" unit attention condition when SeaBIOS
sends it!
Reported-by: Dave Frodin <dave(a)camp.se-eng.com>
Signed-off-by: Paolo Bonzini <pbonzini(a)redhat.com>
---
src/blockcmd.c | 36 +++++++++++++++++++++++-------------
1 files changed, 23 insertions(+), 13 deletions(-)
diff --git a/src/blockcmd.c b/src/blockcmd.c
index 2769573..b4a1e37 100644
--- a/src/blockcmd.c
+++ b/src/blockcmd.c
@@ -139,19 +139,29 @@ scsi_init_drive(struct drive_s *drive, const char *s, int prio)
dprintf(1, "%s blksize=%d sectors=%d\n"
, s, drive->blksize, (unsigned)drive->sectors);
- struct cdbres_mode_sense_geom geomdata;
- ret = cdb_mode_sense_geom(&dop, &geomdata);
- if (ret == 0) {
- u32 cylinders;
- cylinders = geomdata.cyl[0] << 16;
- cylinders |= geomdata.cyl[1] << 8;
- cylinders |= geomdata.cyl[2];
- if (cylinders && geomdata.heads &&
- drive->sectors <= 0xFFFFFFFFULL &&
- ((u32)drive->sectors % (geomdata.heads * cylinders) == 0)) {
- drive->pchs.cylinders = cylinders;
- drive->pchs.heads = geomdata.heads;
- drive->pchs.spt = (u32)drive->sectors / (geomdata.heads * cylinders);
+ // We do not recover from USB stalls, so try to be safe and avoid
+ // sending the command if the (obsolete, but still provided by QEMU)
+ // fixed disk geometry page may not be supported.
+ //
+ // We could also send the command only to small disks (e.g. <504MiB)
+ // but some old USB keys only support a very small subset of SCSI which
+ // does not even include the MODE SENSE command!
+ //
+ if (! CONFIG_COREBOOT && memcmp(vendor, "QEMU ", 8) == 0) {
+ struct cdbres_mode_sense_geom geomdata;
+ ret = cdb_mode_sense_geom(&dop, &geomdata);
+ if (ret == 0) {
+ u32 cylinders;
+ cylinders = geomdata.cyl[0] << 16;
+ cylinders |= geomdata.cyl[1] << 8;
+ cylinders |= geomdata.cyl[2];
+ if (cylinders && geomdata.heads &&
+ drive->sectors <= 0xFFFFFFFFULL &&
+ ((u32)drive->sectors % (geomdata.heads * cylinders) == 0)) {
+ drive->pchs.cylinders = cylinders;
+ drive->pchs.heads = geomdata.heads;
+ drive->pchs.spt = (u32)drive->sectors / (geomdata.heads * cylinders);
+ }
}
}
--
1.7.7.6
Hi,
Did some more testing of the vgabios today, two issues popped up:
(1) screen isn't cleared in some cases. Visible with grub1 in text
mode. When it displays the menu a few stray chars are visible.
Even more obvious it becomes when hitting 'c' then to get a
prompt, then alot of the menu is still visible.
(2) The Xorg Server has trouble, the VESA driver doesn't work.
There are also some good news: linux kernel with vesafb active works
fine, likewise winxp guests.
cheers,
Gerd
[ 90.904] (II) Loading sub module "vbe"
[ 90.904] (II) LoadModule: "vbe"
[ 90.904] (II) Loading /usr/lib/xorg/modules/libvbe.so
[ 90.905] (II) Module vbe: vendor="X.Org Foundation"
[ 90.905] compiled for 1.10.4, module version = 1.1.0
[ 90.905] ABI class: X.Org Video Driver, version 10.0
[ 90.905] (II) Loading sub module "int10"
[ 90.905] (II) LoadModule: "int10"
[ 90.906] (II) Loading /usr/lib/xorg/modules/libint10.so
[ 90.909] (II) Module int10: vendor="X.Org Foundation"
[ 90.909] compiled for 1.10.4, module version = 1.0.0
[ 90.909] ABI class: X.Org Video Driver, version 10.0
[ 90.909] (II) VESA(0): initializing int10
[ 90.912] (II) VESA(0): Bad V_BIOS checksum
[ 90.912] (II) VESA(0): Primary V_BIOS segment is: 0xc000
[ 97.832]
Backtrace:
[ 97.833] 0: Xorg (xorg_backtrace+0x3c) [0x80a408c]
[ 97.833] 1: Xorg (0x8048000+0x60496) [0x80a8496]
[ 97.833] 2: (vdso) (__kernel_rt_sigreturn+0x0) [0x2c040c]
[ 97.837] 3: /usr/lib/xorg/modules/libint10.so (0x2ed000+0x47e2)
[0x2f17e2]
[ 97.837] 4: /usr/lib/xorg/modules/libint10.so (0x2ed000+0x343a)
[0x2f043a]
[ 97.837] 5: /usr/lib/xorg/modules/libint10.so (0x2ed000+0xe02e)
[0x2fb02e]
[ 97.837] 6: /usr/lib/xorg/modules/libint10.so (0x2ed000+0x13134)
[0x300134]
[ 97.837] 7: /usr/lib/xorg/modules/libint10.so (0x2ed000+0xdd56)
[0x2fad56]
[ 97.837] 8: /usr/lib/xorg/modules/libint10.so
(xf86ExecX86int10+0x5d) [0x2f135d]
[ 97.837] 9: /usr/lib/xorg/modules/libvbe.so (VBEExtendedInit+0x92)
[0x2cc102]
[ 97.837] 10: /usr/lib/xorg/modules/drivers/vesa_drv.so
(0x2b5000+0x29db) [0x2b79db]
[ 97.837] 11: Xorg (InitOutput+0x84b) [0x80b93cb]
[ 97.837] 12: Xorg (0x8048000+0x1c1e5) [0x80641e5]
[ 97.837] 13: /lib/libc.so.6 (__libc_start_main+0xf3) [0x72a3f3]
[ 97.847] 14: Xorg (0x8048000+0x1c6a1) [0x80646a1]
[ 97.848] Segmentation fault at address 0xb7e55000
[ 97.848]
Fatal server error:
[ 97.848] Caught signal 11 (Segmentation fault). Server aborting
[ 97.850]
[ 97.850]
Hi,
New revision of my 64bit pci patches. This is what I'm using to play
with 64bit PCI bars (ivshmem + qxl devices) and bridge support (patches
from mst).
Changes in v2:
* tried to reduce the stack footprint of 64bit hex number printing.
* changed patch splitting to make them (hopefully) more readable.
* full support for bridges with 64bit memory windows, even nested.
Also availabe from:
git://git.kraxel.org/seabios pci64
enjoy,
Gerd
Gerd Hoffmann (6):
output: add 64bit hex print support
pci: split device discovery into multiple steps
pci: 64bit support.
pci: bridges can have two regions too
pci: fix bridge ressource allocation.
pci: add prefmem64
src/acpi-dsdt.dsl | 7 ++
src/acpi-dsdt.hex | 72 ++++++++++++---
src/config.h | 2 +
src/output.c | 23 ++++-
src/pci.h | 14 ++-
src/pciinit.c | 272 ++++++++++++++++++++++++++++++++++++++---------------
6 files changed, 294 insertions(+), 96 deletions(-)
Hi,
This patch series enables 64bit BAR support in seabios.
It has a bit different approach for resources accounting, We did this
because we wanted:
a) Provide 64bit bar support for PCI BARs and bridges with 64bit memory
window.
b) Allow migration to 64bit bit ranges if we did not fit into 32bit
range
c) Keep implementation simple.
There are still have two main passes to enumerate resources and map
devices, but structures are changed.
We introduced two new structures: pci_region and pci_region_entry.
The pci_region structure includes a list of pci_region_entries. Each
pci_region_entry could be a PCI bar or a downstream PCI region (bridge).
Each entry has a set of attributes: type (IO, MEM, PREFMEM), is64bit (if
address can be over 4GB), size, base address, PCI device owner, and a
pointer to the pci_region it belongs to.
In the first pass we fill the pci_regions with entries and discover
topology.
In the second pass we try assigning memory addresses to pci_regions. If
there is not enough space available the 64bit entries of root regions
will be migrated to 64bit bit ranges and then we try assigning memory
addresses again.
Then each entry of each region will be mapped.
The patch series includes 6 patches.
In the 1st patch we introduce new structures.
In the 2nd patch we introduce support functions for basic hlist
operations, plus modify service functions to support 64bits address
ranges.
Note: I've seen similar hlist operations in post memory manager
and stack location operations, it makes sense to move
them to a header file.
In the 3rd patch a new function to fill pci_region structures with
entries, and discover topology is added.
In the 4th patch we define address range for pci_region structure,
migrate entries to 64bits address range if necessary, and program PCI
BAR addresses and bridge regions.
In the 6th patch we clear old code.
And last patch is proposed by Michael Tsirkin, it contains changes in
acpi-dsdt.dsl file those are necessary to support 64bit BARs in Windows.
src/acpi-dsdt.dsl | 7 +
src/acpi-dsdt.hex | 72 ++++++--
src/config.h | 2 +
src/pci.h | 6 -
src/pciinit.c | 509 +++++++++++++++++++++++++++++-----------------------
5 files changed, 352 insertions(+), 244 deletions(-)
Note:
At the moment there are three issues related to support of 64bit BARs in
qemu (head of master branch). It's very likely they will be fixed in
next qemu release.
The 1st one is described here (this issue causing problems if 64bit BAR
is mapped below 4GB and Linux guest OS version is < 2.6.27):
http://www.mail-archive.com/qemu-devel@nongnu.org/msg94522.html
The 2nd one is just a typo in i440fx init code (this issue is causing
problems if somebody is going to access 64bit PCI memory - memory will
be inaccessible):
http://www.mail-archive.com/qemu-devel@nongnu.org/msg99423.html
The 3nd issue is related to a case of HUGE PCI bars when BAR size is 4GB
and over. Qemu for some reasons reports zero size in this case. New
seabios should handle huge bars well.
I've sent the patches for the first two issues. If they are all applied
problems except the "huge BARs issue" should gone.
On Mon, Mar 05, 2012 at 02:20:45PM +0000, Julian Pidancet wrote:
> Otherwise, checksum_far is getting called with zero as the length
> parameter, and the ROM checksum in the header end up beeing zero
> after vga_post() is called.
Thanks - good catch. I've added this to my queue.
-Kevin
On Mon, Mar 05, 2012 at 04:05:11PM +0000, Julian Pidancet wrote:
> On Mon, Mar 5, 2012 at 3:33 PM, Kevin O'Connor <kevin(a)koconnor.net> wrote:
> >
> > Looking at the current generated code, it would seem that the only
> > problematic instructions actually created by gcc in the current
> > SeaVGABIOS code are "leavel" and "retl". (I don't see "enterl"
> > generated, there are currently no function pointers, and there wont be
> > any 32bit far calls/returns.) I wonder if we could post-process the
> > assembler and replace "retl" with "retw $2" and "leavel" with "movl
> > %ebp, %esp ; popl %ebp". Do you see any issues with that?
> >
>
> Well, it is not a very elegant solution, but it seems to be the best
> plan we have so far.
>
> I can see two problems:
>
> 1) If you look at the patch I tried to submit to xorg-devel. Other
> instructions are concerned, in particular some forms of call (opcode
> 0xFF). Which means that if we decide to write a postprocess tool,
> we'll have to check that the ROM doesn't use those instructions.
Agreed. If it's just "calll *%ereg" then it can probably just be
replaced with "pushw $0 ; callw *%reg".
> 2) Replacing instructions in the binary is simple, as long as the new
> instruction is the same size as the replaced instruction.
>
> 66 c3 retl (2 bytes)
> c2 02 00 ret $0x2 (3 bytes)
>
> 66 c9 leavel (2 bytes)
> 66 89 ec mov %ebp,%esp (3 bytes)
> 66 5d pop %ebp (1 bytes)
>
> Replacing instructions and handling displacement is probably going to
> be a huge pain.
I don't think that will be an issue. One can tell gcc to generate
assembler and then post-process that. The gcc created assembler is
still label based so no positional issues should arise.
-Kevin
On Sun, Mar 04, 2012 at 08:08:12PM +0000, Julian Pidancet wrote:
> On Sun, Mar 4, 2012 at 7:54 PM, Kevin O'Connor <kevin(a)koconnor.net> wrote:
> >
> > The only thing I can think of would be to post-process the assembler
> > and replace "retl" instructions with "retw $2" instructions. I'm not
> > sure if it would work and it would be real ugly.
> >
>
> As I mentionned, ret is not the only instruction causing problems.
> I've identified issues with leave, enter, iret, and even some forms of
> the call instruction, and the list is probaly not complete yet. So it
> could be even more complicated that we think.
>
> It looks like x86emu was never tested with gcc produced code before.
> And it looks like handling of the 0x66 instruction prefix has been
> neglected in a lot of different places in the code.
Looking at the current generated code, it would seem that the only
problematic instructions actually created by gcc in the current
SeaVGABIOS code are "leavel" and "retl". (I don't see "enterl"
generated, there are currently no function pointers, and there wont be
any 32bit far calls/returns.) I wonder if we could post-process the
assembler and replace "retl" with "retw $2" and "leavel" with "movl
%ebp, %esp ; popl %ebp". Do you see any issues with that?
-Kevin