pci: fix bridge IO/BASE
PATCH 1/1 pci: fix bridge IO/BASE
commit 5caef97a16010f818ea8b950e2ee24ba876643ad introduced
a regression: we do not make IO base/limit upper 16
bit registers writeable, so we should report a 16 bit
IO range type, not a 32 bit one.
Note that PCI_PREF_RANGE_TYPE_32 is 0x0, but PCI_IO_RANGE_TYPE_32 is 0x1.
In particular, this broke sparc64.
Note: this just reverts to behaviour prior to the patch. Making PCI_IO_BASE_UPPER16 and PCI_IO_LIMIT_UPPER16 registers writeable should, and seems to, work just as well, but as no system seems to actually be interested in 32 bit IO, let's not make unnecessary changes.
Mark, can you confirm that this fixes the bug for you?
--- hw/pci.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-)
hw/pci.c +2 -2
@@ -633,8 +633,8 @@ static void pci_init_mask_bridge(PCIDevice *d)memset (d->wmask +PCI_PREF_BASE_UPPER32 ,0xff ,8 );/* Supported memory and i/o types */ - d->config[PCI_IO_BASE ] |=PCI_IO_RANGE_TYPE_32 ; - d->config[PCI_IO_LIMIT ] |=PCI_IO_RANGE_TYPE_32 ; + d->config[PCI_IO_BASE ] |=PCI_IO_RANGE_TYPE_16 ; + d->config[PCI_IO_LIMIT ] |=PCI_IO_RANGE_TYPE_16 ;pci_word_test_and_set_mask (d->config +PCI_PREF_MEMORY_BASE ,PCI_PREF_RANGE_TYPE_64 ); pci_word_test_and_set_mask(d->config + PCI_PREF_MEMORY_LIMIT,
Signature · 1 line
1.7.9.111.gf3fb0
Quoted 14 lines · Michael S. Tsirkin
commit
5caef97a16010f818ea8b950e2ee24ba876643adintroduced
a regression: we do not make IO base/limit upper 16
bit registers writeable, so we should report a 16 bit
IO range type, not a 32 bit one.
Note thatPCI_PREF_RANGE_TYPE_32is0x0, butPCI_IO_RANGE_TYPE_32is0x1.In particular, this broke sparc64.
Note: this just reverts to behaviour prior to the patch. Making
PCI_IO_BASE_UPPER16andPCI_IO_LIMIT_UPPER16registers writeable should, and seems to, work just as well, but as no system seems to actually be interested in 32 bit IO, let's not make unnecessary changes.
Quoted 4 lines
Reported-by Mark Cave-Ayland <[email protected]>Signed-off-by Michael S. Tsirkin <[email protected]>Mark, can you confirm that this fixes the bug for you?
No, running
qemu-system-sparc64 -serial stdio
still shows black screen and the following on console:
OpenBIOS for Sparc64
Unhandled Exception 0x0000000000000032
PC = 0x00000000ffd19e18 NPC = 0x00000000ffd19e1c Stopping execution
This unassigned memory exception is triggered because CMD646 IDE I/O registers are not accessible:
(qemu) info pci
Bus 0, device 0, function 0:
Host bridge: PCI device 108e:a000
id ""
Bus 0, device 1, function 0:
PCI bridge: PCI device 108e:5000
BUS 0.
secondary bus 1.
subordinate bus 1.
IO range [0x0000, 0x0fff]
memory range [0x00000000, 0x000fffff]
prefetchable memory range [0x00000000, 0x000fffff]
id ""
Bus 0, device 1, function 1:
PCI bridge: PCI device 108e:5000
BUS 0.
secondary bus 2.
subordinate bus 2.
IO range [0x0000, 0x0fff]
memory range [0x00000000, 0x000fffff]
prefetchable memory range [0x00000000, 0x000fffff]
id ""
Bus 0, device 2, function 0:
VGA controller: PCI device 1234:1111
BAR0: 32 bit prefetchable memory at 0x00800000 [0x00ffffff].
BAR6: 32 bit memory at 0x01000000 [0x0100ffff].
id ""
Bus 0, device 3, function 0:
Bridge: PCI device 108e:1000
BAR0: 32 bit memory at 0x02000000 [0x02ffffff].
BAR1: 32 bit memory at 0x03000000 [0x037fffff].
id ""
Bus 0, device 4, function 0:
Ethernet controller: PCI device 10ec:8029
IRQ 0.
BAR0: I/O at 0xffffffffffffffff [0x00fe].
BAR6: 32 bit memory at 0x03800000 [0x0380ffff].
id ""
Bus 0, device 5, function 0:
IDE controller: PCI device 1095:0646
IRQ 1.
BAR0: I/O at 0xffffffffffffffff [0x0006].
BAR1: I/O at 0xffffffffffffffff [0x0002].
BAR2: I/O at 0xffffffffffffffff [0x0006].
BAR3: I/O at 0xffffffffffffffff [0x0002].
BAR4: I/O at 0xffffffffffffffff [0x000e].
id ""(qemu) info mtree
memory
0000000000000000-7ffffffffffffffe (prio 0, RW): system
0000000000000000-0000000007ffffff (prio 0, RW): sun4u.ram 000001fe00000000-000001fe0000ffff (prio 0, RW): apb-config 000001fe01000000-000001fe01ffffff (prio 0, RW): apb-pci-config 000001fe02000000-000001fe0200ffff (prio 0, RW): apb-pci-ioport 000001ff00000000-000001ffffffffff (prio 0, RW): pci-mmio
000001ff00000000-000001ff000fffff (prio 1, RW): alias
pci_bridge_mem @pci_bridge_pci 0000000000000000-00000000000fffff
000001ff00000000-000001ff000fffff (prio 1, RW): alias
pci_bridge_pref_mem @pci_bridge_pci 0000000000000000-00000000000fffff
000001ff00000000-000001ff000fffff (prio 1, RW): alias
pci_bridge_mem @pci_bridge_pci 0000000000000000-00000000000fffff
000001ff00000000-000001ff000fffff (prio 1, RW): alias
pci_bridge_pref_mem @pci_bridge_pci 0000000000000000-00000000000fffff
000001ff000a0000-000001ff000affff (prio 2, RW): alias vga.chain4
@vga.vram 0000000000000000-000000000000ffff
000001ff000a0000-000001ff000bffff (prio 1, RW): vga-lowmem
000001ff00800000-000001ff00ffffff (prio 1, RW): vga.vram
000001ff01000000-000001ff0100ffff (prio 1, RW): vga.rom
000001ff02000000-000001ff02ffffff (prio 1, RW): isa-mmio
000001ff03000000-000001ff037fffff (prio 1, RW): isa-mmio
000001ff03800000-000001ff0380ffff (prio 1, RW): ne2000.rom 000001fff0000000-000001fff03fffff (prio 0, R-): sun4u.prompci_bridge_pci
0000000000000000-7ffffffffffffffe (prio 0, RW): pci_bridge_pci pci_bridge_pci
0000000000000000-7ffffffffffffffe (prio 0, RW): pci_bridge_pci vga.vram
0000000000800000-0000000000ffffff (prio 1, RW): vga.vram I/O
0000000000000000-000000000000ffff (prio 0, RW): io
0000000000000000-0000000000000fff (prio 1, RW): alias pci_bridge_io
@pci_bridge_io 0000000000000000-0000000000000fff
0000000000000000-0000000000000fff (prio 1, RW): alias pci_bridge_io
@pci_bridge_io 0000000000000000-0000000000000fff
0000000000000060-0000000000000060 (prio 0, RW): i8042-data 0000000000000064-0000000000000064 (prio 0, RW): i8042-cmd 0000000000000074-0000000000000077 (prio 0, RW): m48t59 00000000000001ce-00000000000001ce (prio 0, RW): alias vbe @vbe
00000000000001ce-00000000000001ce
00000000000001d0-00000000000001d0 (prio 0, RW): alias vbe @vbe
00000000000001d0-00000000000001d0
0000000000000378-000000000000037f (prio 0, RW): alias parallel
@parallel 0000000000000378-000000000000037f
00000000000003b4-00000000000003b5 (prio 0, RW): alias vga @vga
00000000000003b4-00000000000003b5
00000000000003ba-00000000000003ba (prio 0, RW): alias vga @vga
00000000000003ba-00000000000003ba
00000000000003c0-00000000000003cf (prio 0, RW): alias vga @vga
00000000000003c0-00000000000003cf
00000000000003d4-00000000000003d5 (prio 0, RW): alias vga @vga
00000000000003d4-00000000000003d5
00000000000003da-00000000000003da (prio 0, RW): alias vga @vga
00000000000003da-00000000000003da
00000000000003f1-00000000000003f5 (prio 0, RW): alias fdc @fdc
00000000000003f1-00000000000003f5
00000000000003f7-00000000000003f7 (prio 0, RW): alias fdc @fdc
00000000000003f7-00000000000003f7
00000000000003f8-00000000000003ff (prio 0, RW): serial 0000000000000510-0000000000000511 (prio 0, RW): fwcfg
Quoted 21 lines
---
hw/pci.c | 4 ++--1 files changed, 2 insertions(+), 2 deletions(-)hw/pci.c +2
-3@@ -633,8 +633,8 @@ static void pci_init_mask_bridge(PCIDevice *d) memset(d->wmask + PCI_PREF_BASE_UPPER32, 0xff, 8); /* Supported memory and i/o types */ - d->config[PCI_IO_BASE] |= PCI_IO_RANGE_TYPE_32; - d->config[PCI_IO_LIMIT] |= PCI_IO_RANGE_TYPE_32; + d->config[PCI_IO_BASE] |= PCI_IO_RANGE_TYPE_16; + d->config[PCI_IO_LIMIT] |= PCI_IO_RANGE_TYPE_16; pci_word_test_and_set_mask(d->config + PCI_PREF_MEMORY_BASE, PCI_PREF_RANGE_TYPE_64); pci_word_test_and_set_mask(d->config + PCI_PREF_MEMORY_LIMIT, --1.7.9.111.gf3fb0
Quoted 20 lines · Blue Swirl
Quoted 14 lines · Michael S. Tsirkin
commit
5caef97a16010f818ea8b950e2ee24ba876643adintroduced
a regression: we do not make IO base/limit upper 16
bit registers writeable, so we should report a 16 bit
IO range type, not a 32 bit one.
Note thatPCI_PREF_RANGE_TYPE_32is0x0, butPCI_IO_RANGE_TYPE_32is0x1.In particular, this broke sparc64.
Note: this just reverts to behaviour prior to the patch. Making
PCI_IO_BASE_UPPER16andPCI_IO_LIMIT_UPPER16registers writeable should, and seems to, work just as well, but as no system seems to actually be interested in 32 bit IO, let's not make unnecessary changes.Quoted 4 lines
Reported-by Mark Cave-Ayland <[email protected]>Signed-off-by Michael S. Tsirkin <[email protected]>Mark, can you confirm that this fixes the bug for you?
Quoted 7 lines
No, running
qemu-system-sparc64 -serial stdio
still shows black screen and the following on console:
OpenBIOS for Sparc64
Unhandled Exception0x0000000000000032
PC =0x00000000ffd19e18NPC =0x00000000ffd19e1cStopping execution
The weird thing is the range type does not seem to be accessed at all. So I guessed there's some memory corruption here. Running valgrind shows this:
--11114-- WARNING: unhandled syscall: 340
--11114-- You may be able to write your own handler. --11114-- Read the file README_MISSING_SYSCALL_OR_IOCTL. --11114-- Nevertheless we consider this a bug. Please report --11114-- it at http://valgrind.org/support/bug_reports.html.
==11114== Invalid read of size 4
==11114== at 0x2A68C0: pci_apb_init (apb_pci.c:350) ==11114== by 0x2F7A84: sun4uv_init (sun4u.c:779) ==11114== by 0x13D716: main (vl.c:3397) ==11114== Address 0x156c7d30 is 0 bytes after a block of size 64 alloc'd ==11114== at 0x557DD69: malloc (vg_replace_malloc.c:236) ==11114== by 0x225F56: malloc_and_trace (vl.c:2156) ==11114== by 0x584AFEC: ??? (in /lib/libglib-2.0.so.0.2800.8) ==11114== by 0x584B528: g_malloc0 (in /lib/libglib-2.0.so.0.2800.8) ==11114== by 0x19C50C: qemu_allocate_irqs (irq.c:47) ==11114== by 0x2F7A4C: sun4uv_init (sun4u.c:778) ==11114== by 0x13D716: main (vl.c:3397)
==11114==
apb: here
==11114== Warning: client switching stacks? SP change: 0xfec42cbc --> 0x16894008
==11114== to suppress, use: --max-stackframe=398791500 or
greater
==11114== Warning: client switching stacks? SP change: 0x16893fa0 --> 0xfec42cc0
==11114== to suppress, use: --max-stackframe=398791392 or
greater
==11114== Warning: client switching stacks? SP change: 0xfec42fe0 --> 0x16893fd0
==11114== to suppress, use: --max-stackframe=398790640 or
greater
==11114== further instances of this message will not be shown.
QEMU 1.0.50 monitor - type 'help' for more information (qemu) ==11114== Thread 2:
==11114== Conditional jump or move depends on uninitialised value(s)
==11114== at 0x2A8351: compute_all_sub (cc_helper.c:37) ==11114== by 0x2A8782: helper_compute_psr (cc_helper.c:470) ==11114== by 0x9AD9A19: ??? ==11114== ==11114== Conditional jump or move depends on uninitialised value(s) ==11114== at 0x2A827C: compute_all_sub_xcc (cc_helper.c:60) ==11114== by 0x2A8795: helper_compute_psr (cc_helper.c:473) ==11114== by 0x9AD9A19: ??? ==11114== ==11114== Conditional jump or move depends on uninitialised value(s) ==11114== at 0x2A8296: compute_all_sub_xcc (cc_helper.c:295) ==11114== by 0x2A8795: helper_compute_psr (cc_helper.c:473) ==11114== by 0x9AD9A19: ???
==11114==
Is the above a problem?
Quoted 104 lines
This unassigned memory exception is triggered because CMD646 IDE I/O registers are not accessible:
(qemu) info pci
Bus 0, device 0, function 0:
Host bridge: PCI device 108e:a000
id ""
Bus 0, device 1, function 0:PCI bridge: PCI device 108e:5000 BUS 0. secondary bus 1. subordinate bus 1. IO range [0x0000, 0x0fff] memory range [0x00000000, 0x000fffff] prefetchable memory range [0x00000000, 0x000fffff] id "" Bus 0, device 1, function 1: PCI bridge: PCI device 108e:5000 BUS 0. secondary bus 2. subordinate bus 2. IO range [0x0000, 0x0fff] memory range [0x00000000, 0x000fffff] prefetchable memory range [0x00000000, 0x000fffff] id "" Bus 0, device 2, function 0: VGA controller: PCI device 1234:1111 BAR0: 32 bit prefetchable memory at 0x00800000 [0x00ffffff]. BAR6: 32 bit memory at 0x01000000 [0x0100ffff]. id "" Bus 0, device 3, function 0: Bridge: PCI device 108e:1000 BAR0: 32 bit memory at 0x02000000 [0x02ffffff]. BAR1: 32 bit memory at 0x03000000 [0x037fffff]. id "" Bus 0, device 4, function 0: Ethernet controller: PCI device 10ec:8029 IRQ 0. BAR0: I/O at 0xffffffffffffffff [0x00fe]. BAR6: 32 bit memory at 0x03800000 [0x0380ffff]. id "" Bus 0, device 5, function 0: IDE controller: PCI device 1095:0646 IRQ 1. BAR0: I/O at 0xffffffffffffffff [0x0006]. BAR1: I/O at 0xffffffffffffffff [0x0002]. BAR2: I/O at 0xffffffffffffffff [0x0006]. BAR3: I/O at 0xffffffffffffffff [0x0002]. BAR4: I/O at 0xffffffffffffffff [0x000e]. id ""(qemu) info mtree
memory
0000000000000000-7ffffffffffffffe (prio 0, RW): system
0000000000000000-0000000007ffffff (prio 0, RW): sun4u.ram 000001fe00000000-000001fe0000ffff (prio 0, RW): apb-config 000001fe01000000-000001fe01ffffff (prio 0, RW): apb-pci-config 000001fe02000000-000001fe0200ffff (prio 0, RW): apb-pci-ioport 000001ff00000000-000001ffffffffff (prio 0, RW): pci-mmio000001ff00000000-000001ff000fffff (prio 1, RW): alias pci_bridge_mem @pci_bridge_pci 0000000000000000-00000000000fffff 000001ff00000000-000001ff000fffff (prio 1, RW): alias pci_bridge_pref_mem @pci_bridge_pci 0000000000000000-00000000000fffff 000001ff00000000-000001ff000fffff (prio 1, RW): alias pci_bridge_mem @pci_bridge_pci 0000000000000000-00000000000fffff 000001ff00000000-000001ff000fffff (prio 1, RW): alias pci_bridge_pref_mem @pci_bridge_pci 0000000000000000-00000000000fffff 000001ff000a0000-000001ff000affff (prio 2, RW): alias vga.chain4 @vga.vram 0000000000000000-000000000000ffff 000001ff000a0000-000001ff000bffff (prio 1, RW): vga-lowmem 000001ff00800000-000001ff00ffffff (prio 1, RW): vga.vram 000001ff01000000-000001ff0100ffff (prio 1, RW): vga.rom 000001ff02000000-000001ff02ffffff (prio 1, RW): isa-mmio 000001ff03000000-000001ff037fffff (prio 1, RW): isa-mmio 000001ff03800000-000001ff0380ffff (prio 1, RW): ne2000.rom000001fff0000000-000001fff03fffff (prio 0, R-): sun4u.prom
pci_bridge_pci
0000000000000000-7ffffffffffffffe (prio 0, RW):pci_bridge_pcipci_bridge_pci
0000000000000000-7ffffffffffffffe (prio 0, RW):pci_bridge_pcivga.vram
0000000000800000-0000000000ffffff (prio 1, RW): vga.vram I/O
0000000000000000-000000000000ffff (prio 0, RW): io
0000000000000000-0000000000000fff (prio 1, RW): aliaspci_bridge_io
@pci_bridge_io 0000000000000000-0000000000000fff
0000000000000000-0000000000000fff (prio 1, RW): aliaspci_bridge_io
@pci_bridge_io 0000000000000000-0000000000000fff
0000000000000060-0000000000000060 (prio 0, RW): i8042-data 0000000000000064-0000000000000064 (prio 0, RW): i8042-cmd 0000000000000074-0000000000000077 (prio 0, RW): m48t59 00000000000001ce-00000000000001ce (prio 0, RW): alias vbe @vbe
00000000000001ce-00000000000001ce
00000000000001d0-00000000000001d0 (prio 0, RW): alias vbe @vbe
00000000000001d0-00000000000001d0
0000000000000378-000000000000037f (prio 0, RW): alias parallel
@parallel 0000000000000378-000000000000037f
00000000000003b4-00000000000003b5 (prio 0, RW): alias vga @vga
00000000000003b4-00000000000003b5
00000000000003ba-00000000000003ba (prio 0, RW): alias vga @vga
00000000000003ba-00000000000003ba
00000000000003c0-00000000000003cf (prio 0, RW): alias vga @vga
00000000000003c0-00000000000003cf
00000000000003d4-00000000000003d5 (prio 0, RW): alias vga @vga
00000000000003d4-00000000000003d5
Quoted 8 lines
00000000000003da-00000000000003da (prio 0, RW): alias vga @vga
00000000000003da-00000000000003da
00000000000003f1-00000000000003f5 (prio 0, RW): alias fdc @fdc
00000000000003f1-00000000000003f5
00000000000003f7-00000000000003f7 (prio 0, RW): alias fdc @fdc
00000000000003f7-00000000000003f7
00000000000003f8-00000000000003ff (prio 0, RW): serial 0000000000000510-0000000000000511 (prio 0, RW): fwcfg
And with type 32 range it looks like this:
0000000000000000-7ffffffffffffffe (prio 0, RW): system
0000000000000000-0000000007ffffff (prio 0, RW): sun4u.ram 000001fe00000000-000001fe0000ffff (prio 0, RW): apb-config 000001fe01000000-000001fe01ffffff (prio 0, RW): apb-pci-config 000001fe02000000-000001fe0200ffff (prio 0, RW): apb-pci-ioport 000001ff00000000-000001ffffffffff (prio 0, RW): pci-mmio
000001ff00000000-000001ff000fffff (prio 1, RW): alias pci_bridge_mem
@pci_bridge_pci 0000000000000000-00000000000fffff
000001ff00000000-000001ff000fffff (prio 1, RW): alias
pci_bridge_pref_mem @pci_bridge_pci 0000000000000000-00000000000fffff
000001ff00000000-000001ff000fffff (prio 1, RW): alias pci_bridge_mem
@pci_bridge_pci 0000000000000000-00000000000fffff
000001ff00000000-000001ff000fffff (prio 1, RW): alias
pci_bridge_pref_mem @pci_bridge_pci 0000000000000000-00000000000fffff
000001ff000a0000-000001ff000affff (prio 2, RW): alias vga.chain4
@vga.vram 0000000000000000-000000000000ffff
000001ff000a0000-000001ff000bffff (prio 1, RW): vga-lowmem
000001ff00800000-000001ff00ffffff (prio 1, RW): vga.vram
000001ff01000000-000001ff0100ffff (prio 1, RW): vga.rom
000001ff02000000-000001ff02ffffff (prio 1, RW): isa-mmio
000001ff03000000-000001ff037fffff (prio 1, RW): isa-mmio 000001fff0000000-000001fff03fffff (prio 0, R-): sun4u.prompci_bridge_pci
0000000000000000-7ffffffffffffffe (prio 0, RW): pci_bridge_pci pci_bridge_pci
0000000000000000-7ffffffffffffffe (prio 0, RW): pci_bridge_pci vga.vram
0000000000800000-0000000000ffffff (prio 1, RW): vga.vram I/O
0000000000000000-000000000000ffff (prio 0, RW): io
0000000000000000-0000000000000fff (prio 1, RW): alias pci_bridge_io
@pci_bridge_io 0000000000000000-0000000000000fff
0000000000000000-0000000000000fff (prio 1, RW): alias pci_bridge_io
@pci_bridge_io 0000000000000000-0000000000000fff
0000000000000060-0000000000000060 (prio 0, RW): i8042-data 0000000000000064-0000000000000064 (prio 0, RW): i8042-cmd 0000000000000074-0000000000000077 (prio 0, RW): m48t59 00000000000001ce-00000000000001ce (prio 0, RW): vbe 00000000000001d0-00000000000001d0 (prio 0, RW): vbe 0000000000000378-000000000000037f (prio 0, RW): parallel 00000000000003b4-00000000000003b5 (prio 0, RW): vga 00000000000003ba-00000000000003ba (prio 0, RW): vga 00000000000003c0-00000000000003cf (prio 0, RW): vga 00000000000003d4-00000000000003d5 (prio 0, RW): vga 00000000000003da-00000000000003da (prio 0, RW): vga 00000000000003f1-00000000000003f5 (prio 0, RW): fdc 00000000000003f7-00000000000003f7 (prio 0, RW): fdc 00000000000003f8-00000000000003ff (prio 0, RW): serial 0000000000000400-00000000000004ff (prio 1, RW): ne2000 0000000000000500-0000000000000507 (prio 1, RW): cmd646-data 0000000000000510-0000000000000511 (prio 0, RW): fwcfg 0000000000000580-0000000000000583 (prio 1, RW): cmd646-cmd 0000000000000600-0000000000000607 (prio 1, RW): cmd646-data 0000000000000680-0000000000000683 (prio 1, RW): cmd646-cmd 0000000000000700-000000000000070f (prio 1, RW): cmd646-bmdma
0000000000000700-0000000000000703 (prio 0, RW): cmd646-bmdma-bus
0000000000000704-0000000000000707 (prio 0, RW): cmd646-bmdma-ioport
0000000000000708-000000000000070b (prio 0, RW): cmd646-bmdma-bus
000000000000070c-000000000000070f (prio 0, RW): cmd646-bmdma-ioportSill trying to understand what all this means.
Quoted 20 lines
Quoted 20 lines
hw/pci.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)hw/pci.c +2
-3@@ -633,8 +633,8 @@ static void pci_init_mask_bridge(PCIDevice *d) memset(d->wmask + PCI_PREF_BASE_UPPER32, 0xff, 8); /* Supported memory and i/o types */ - d->config[PCI_IO_BASE] |= PCI_IO_RANGE_TYPE_32; - d->config[PCI_IO_LIMIT] |= PCI_IO_RANGE_TYPE_32; + d->config[PCI_IO_BASE] |= PCI_IO_RANGE_TYPE_16; + d->config[PCI_IO_LIMIT] |= PCI_IO_RANGE_TYPE_16; pci_word_test_and_set_mask(d->config + PCI_PREF_MEMORY_BASE, PCI_PREF_RANGE_TYPE_64); pci_word_test_and_set_mask(d->config + PCI_PREF_MEMORY_LIMIT, --1.7.9.111.gf3fb0
Quoted 84 lines · Michael S. Tsirkin
Quoted 20 lines · Blue Swirl
Quoted 14 lines · Michael S. Tsirkin
commit
5caef97a16010f818ea8b950e2ee24ba876643adintroduced
a regression: we do not make IO base/limit upper 16
bit registers writeable, so we should report a 16 bit
IO range type, not a 32 bit one.
Note thatPCI_PREF_RANGE_TYPE_32is0x0, butPCI_IO_RANGE_TYPE_32is0x1.In particular, this broke sparc64.
Note: this just reverts to behaviour prior to the patch. Making
PCI_IO_BASE_UPPER16andPCI_IO_LIMIT_UPPER16registers writeable should, and seems to, work just as well, but as no system seems to actually be interested in 32 bit IO, let's not make unnecessary changes.Quoted 4 lines
Reported-by Mark Cave-Ayland <[email protected]>Signed-off-by Michael S. Tsirkin <[email protected]>Mark, can you confirm that this fixes the bug for you?
Quoted 7 lines
No, running
qemu-system-sparc64 -serial stdio
still shows black screen and the following on console:
OpenBIOS for Sparc64
Unhandled Exception0x0000000000000032
PC =0x00000000ffd19e18NPC =0x00000000ffd19e1cStopping executionThe weird thing is the range type does not seem to be accessed at all. So I guessed there's some memory corruption here. Running valgrind shows this:
--11114-- WARNING: unhandled syscall: 340
--11114-- You may be able to write your own handler. --11114-- Read the fileREADME_MISSING_SYSCALL_OR_IOCTL. --11114-- Nevertheless we consider this a bug. Please report --11114-- it at http://valgrind.org/support/bug_reports.html.
==11114== Invalid read of size 4
==11114== at0x2A68C0:pci_apb_init(apb_pci.c:350) ==11114== by0x2F7A84:sun4uv_init(sun4u.c:779) ==11114== by0x13D716: main (vl.c:3397)
==11114== Address0x156c7d30is 0 bytes after a block of size 64 alloc'd
==11114== at0x557DD69: malloc (vg_replace_malloc.c:236) ==11114== by0x225F56:malloc_and_trace(vl.c:2156) ==11114== by0x584AFEC: ??? (in/lib/libglib-2.0.so.0.2800.8) ==11114== by0x584B528:g_malloc0(in/lib/libglib-2.0.so.0.2800.8) ==11114== by0x19C50C:qemu_allocate_irqs(irq.c:47) ==11114== by0x2F7A4C:sun4uv_init(sun4u.c:778) ==11114== by0x13D716: main (vl.c:3397)
==11114==
apb: here
==11114== Warning: client switching stacks? SP change:0xfec42cbc-->0x16894008
==11114== to suppress, use: --max-stackframe=398791500 or greater
==11114== Warning: client switching stacks? SP change:0x16893fa0-->0xfec42cc0
==11114== to suppress, use: --max-stackframe=398791392 or greater
==11114== Warning: client switching stacks? SP change:0xfec42fe0-->0x16893fd0
==11114== to suppress, use: --max-stackframe=398790640 or greater
==11114== further instances of this message will not be shown. QEMU 1.0.50 monitor - type 'help' for more information (qemu) ==11114== Thread 2:
==11114== Conditional jump or move depends on uninitialised value(s) ==11114== at0x2A8351:compute_all_sub(cc_helper.c:37) ==11114== by0x2A8782:helper_compute_psr(cc_helper.c:470) ==11114== by0x9AD9A19: ???
==11114==
==11114== Conditional jump or move depends on uninitialised value(s) ==11114== at0x2A827C:compute_all_sub_xcc(cc_helper.c:60) ==11114== by0x2A8795:helper_compute_psr(cc_helper.c:473) ==11114== by0x9AD9A19: ???
==11114==
==11114== Conditional jump or move depends on uninitialised value(s) ==11114== at0x2A8296:compute_all_sub_xcc(cc_helper.c:295) ==11114== by0x2A8795:helper_compute_psr(cc_helper.c:473) ==11114== by0x9AD9A19: ???
==11114==
Quoted 1 line
Is the above a problem?
It looks like Sparc does not reset registers at CPU reset. Nice catch.
Quoted 166 lines
Quoted 104 lines
This unassigned memory exception is triggered because CMD646 IDE I/O registers are not accessible:
(qemu) info pci
Bus 0, device 0, function 0:
Host bridge: PCI device 108e:a000
id ""
Bus 0, device 1, function 0:
PCI bridge: PCI device 108e:5000
BUS 0.
secondary bus 1.
subordinate bus 1.
IO range [0x0000,0x0fff]
memory range [0x00000000,0x000fffff]
prefetchable memory range [0x00000000,0x000fffff] id ""
Bus 0, device 1, function 1:
PCI bridge: PCI device 108e:5000
BUS 0.
secondary bus 2.
subordinate bus 2.
IO range [0x0000,0x0fff]
memory range [0x00000000,0x000fffff]
prefetchable memory range [0x00000000,0x000fffff] id ""
Bus 0, device 2, function 0:
VGA controller: PCI device 1234:1111
BAR0: 32 bit prefetchable memory at0x00800000[0x00ffffff].
BAR6: 32 bit memory at0x01000000[0x0100ffff].
id ""
Bus 0, device 3, function 0:
Bridge: PCI device 108e:1000
BAR0: 32 bit memory at0x02000000[0x02ffffff].
BAR1: 32 bit memory at0x03000000[0x037fffff].
id ""
Bus 0, device 4, function 0:
Ethernet controller: PCI device 10ec:8029
IRQ 0.
BAR0: I/O at0xffffffffffffffff[0x00fe].
BAR6: 32 bit memory at0x03800000[0x0380ffff].
id ""
Bus 0, device 5, function 0:
IDE controller: PCI device 1095:0646
IRQ 1.
BAR0: I/O at0xffffffffffffffff[0x0006].
BAR1: I/O at0xffffffffffffffff[0x0002].
BAR2: I/O at0xffffffffffffffff[0x0006].
BAR3: I/O at0xffffffffffffffff[0x0002].
BAR4: I/O at0xffffffffffffffff[0x000e].
id ""
(qemu) info mtree
memory
0000000000000000-7ffffffffffffffe (prio 0, RW): system 0000000000000000-0000000007ffffff (prio 0, RW): sun4u.ram 000001fe00000000-000001fe0000ffff (prio 0, RW): apb-config 000001fe01000000-000001fe01ffffff (prio 0, RW): apb-pci-config 000001fe02000000-000001fe0200ffff (prio 0, RW): apb-pci-ioport 000001ff00000000-000001ffffffffff (prio 0, RW): pci-mmio 000001ff00000000-000001ff000fffff (prio 1, RW): aliaspci_bridge_mem@pci_bridge_pci 0000000000000000-00000000000fffff 000001ff00000000-000001ff000fffff (prio 1, RW): aliaspci_bridge_pref_mem@pci_bridge_pci 0000000000000000-00000000000fffff 000001ff00000000-000001ff000fffff (prio 1, RW): aliaspci_bridge_mem@pci_bridge_pci 0000000000000000-00000000000fffff 000001ff00000000-000001ff000fffff (prio 1, RW): aliaspci_bridge_pref_mem@pci_bridge_pci 0000000000000000-00000000000fffff 000001ff000a0000-000001ff000affff (prio 2, RW): alias vga.chain4 @vga.vram 0000000000000000-000000000000ffff 000001ff000a0000-000001ff000bffff (prio 1, RW): vga-lowmem 000001ff00800000-000001ff00ffffff (prio 1, RW): vga.vram 000001ff01000000-000001ff0100ffff (prio 1, RW): vga.rom 000001ff02000000-000001ff02ffffff (prio 1, RW): isa-mmio 000001ff03000000-000001ff037fffff (prio 1, RW): isa-mmio 000001ff03800000-000001ff0380ffff (prio 1, RW): ne2000.rom 000001fff0000000-000001fff03fffff (prio 0, R-): sun4u.prompci_bridge_pci
0000000000000000-7ffffffffffffffe (prio 0, RW):pci_bridge_pcipci_bridge_pci
0000000000000000-7ffffffffffffffe (prio 0, RW):pci_bridge_pcivga.vram
0000000000800000-0000000000ffffff (prio 1, RW): vga.vram I/O
0000000000000000-000000000000ffff (prio 0, RW): io 0000000000000000-0000000000000fff (prio 1, RW): aliaspci_bridge_io@pci_bridge_io 0000000000000000-0000000000000fff 0000000000000000-0000000000000fff (prio 1, RW): aliaspci_bridge_io@pci_bridge_io 0000000000000000-0000000000000fff 0000000000000060-0000000000000060 (prio 0, RW): i8042-data 0000000000000064-0000000000000064 (prio 0, RW): i8042-cmd 0000000000000074-0000000000000077 (prio 0, RW): m48t59 00000000000001ce-00000000000001ce (prio 0, RW): alias vbe @vbe 00000000000001ce-00000000000001ce 00000000000001d0-00000000000001d0 (prio 0, RW): alias vbe @vbe 00000000000001d0-00000000000001d0 0000000000000378-000000000000037f (prio 0, RW): alias parallel @parallel 0000000000000378-000000000000037f 00000000000003b4-00000000000003b5 (prio 0, RW): alias vga @vga 00000000000003b4-00000000000003b5 00000000000003ba-00000000000003ba (prio 0, RW): alias vga @vga 00000000000003ba-00000000000003ba 00000000000003c0-00000000000003cf (prio 0, RW): alias vga @vga 00000000000003c0-00000000000003cf 00000000000003d4-00000000000003d5 (prio 0, RW): alias vga @vga 00000000000003d4-00000000000003d5Quoted 8 lines
00000000000003da-00000000000003da (prio 0, RW): alias vga @vga 00000000000003da-00000000000003da 00000000000003f1-00000000000003f5 (prio 0, RW): alias fdc @fdc 00000000000003f1-00000000000003f5 00000000000003f7-00000000000003f7 (prio 0, RW): alias fdc @fdc 00000000000003f7-00000000000003f7 00000000000003f8-00000000000003ff (prio 0, RW): serial 0000000000000510-0000000000000511 (prio 0, RW): fwcfg
And with type 32 range it looks like this:
0000000000000000-7ffffffffffffffe (prio 0, RW): system 0000000000000000-0000000007ffffff (prio 0, RW): sun4u.ram 000001fe00000000-000001fe0000ffff (prio 0, RW): apb-config 000001fe01000000-000001fe01ffffff (prio 0, RW): apb-pci-config 000001fe02000000-000001fe0200ffff (prio 0, RW): apb-pci-ioport 000001ff00000000-000001ffffffffff (prio 0, RW): pci-mmio 000001ff00000000-000001ff000fffff (prio 1, RW): alias
pci_bridge_mem@pci_bridge_pci 0000000000000000-00000000000fffff 000001ff00000000-000001ff000fffff (prio 1, RW): aliaspci_bridge_pref_mem@pci_bridge_pci 0000000000000000-00000000000fffff 000001ff00000000-000001ff000fffff (prio 1, RW): aliaspci_bridge_mem@pci_bridge_pci 0000000000000000-00000000000fffff 000001ff00000000-000001ff000fffff (prio 1, RW): aliaspci_bridge_pref_mem@pci_bridge_pci 0000000000000000-00000000000fffff 000001ff000a0000-000001ff000affff (prio 2, RW): alias vga.chain4 @vga.vram 0000000000000000-000000000000ffff 000001ff000a0000-000001ff000bffff (prio 1, RW): vga-lowmem 000001ff00800000-000001ff00ffffff (prio 1, RW): vga.vram 000001ff01000000-000001ff0100ffff (prio 1, RW): vga.rom 000001ff02000000-000001ff02ffffff (prio 1, RW): isa-mmio 000001ff03000000-000001ff037fffff (prio 1, RW): isa-mmio 000001fff0000000-000001fff03fffff (prio 0, R-): sun4u.prompci_bridge_pci
0000000000000000-7ffffffffffffffe (prio 0, RW):pci_bridge_pcipci_bridge_pci
0000000000000000-7ffffffffffffffe (prio 0, RW):pci_bridge_pcivga.vram
0000000000800000-0000000000ffffff (prio 1, RW): vga.vram
I/O
0000000000000000-000000000000ffff (prio 0, RW): io 0000000000000000-0000000000000fff (prio 1, RW): aliaspci_bridge_io@pci_bridge_io 0000000000000000-0000000000000fff 0000000000000000-0000000000000fff (prio 1, RW): aliaspci_bridge_io@pci_bridge_io 0000000000000000-0000000000000fff 0000000000000060-0000000000000060 (prio 0, RW): i8042-data 0000000000000064-0000000000000064 (prio 0, RW): i8042-cmd 0000000000000074-0000000000000077 (prio 0, RW): m48t59 00000000000001ce-00000000000001ce (prio 0, RW): vbe 00000000000001d0-00000000000001d0 (prio 0, RW): vbe 0000000000000378-000000000000037f (prio 0, RW): parallel 00000000000003b4-00000000000003b5 (prio 0, RW): vga 00000000000003ba-00000000000003ba (prio 0, RW): vga 00000000000003c0-00000000000003cf (prio 0, RW): vga 00000000000003d4-00000000000003d5 (prio 0, RW): vga 00000000000003da-00000000000003da (prio 0, RW): vga 00000000000003f1-00000000000003f5 (prio 0, RW): fdc 00000000000003f7-00000000000003f7 (prio 0, RW): fdc 00000000000003f8-00000000000003ff (prio 0, RW): serial 0000000000000400-00000000000004ff (prio 1, RW): ne2000 0000000000000500-0000000000000507 (prio 1, RW): cmd646-data 0000000000000510-0000000000000511 (prio 0, RW): fwcfg
Quoted 8 lines
0000000000000580-0000000000000583 (prio 1, RW): cmd646-cmd 0000000000000600-0000000000000607 (prio 1, RW): cmd646-data 0000000000000680-0000000000000683 (prio 1, RW): cmd646-cmd 0000000000000700-000000000000070f (prio 1, RW): cmd646-bmdma 0000000000000700-0000000000000703 (prio 0, RW): cmd646-bmdma-bus 0000000000000704-0000000000000707 (prio 0, RW): cmd646-bmdma-ioport 0000000000000708-000000000000070b (prio 0, RW): cmd646-bmdma-bus 000000000000070c-000000000000070f (prio 0, RW): cmd646-bmdma-ioport
This looks better.
Quoted 24 lines
Sill trying to understand what all this means.
Quoted 20 lines
Quoted 20 lines
hw/pci.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)hw/pci.c +2
-3@@ -633,8 +633,8 @@ static void pci_init_mask_bridge(PCIDevice *d) memset(d->wmask + PCI_PREF_BASE_UPPER32, 0xff, 8); /* Supported memory and i/o types */ - d->config[PCI_IO_BASE] |= PCI_IO_RANGE_TYPE_32; - d->config[PCI_IO_LIMIT] |= PCI_IO_RANGE_TYPE_32; + d->config[PCI_IO_BASE] |= PCI_IO_RANGE_TYPE_16; + d->config[PCI_IO_LIMIT] |= PCI_IO_RANGE_TYPE_16; pci_word_test_and_set_mask(d->config + PCI_PREF_MEMORY_BASE, PCI_PREF_RANGE_TYPE_64); pci_word_test_and_set_mask(d->config + PCI_PREF_MEMORY_LIMIT, --1.7.9.111.gf3fb0
Quoted 85 lines · Blue Swirl
Quoted 84 lines · Michael S. Tsirkin
Quoted 20 lines · Blue Swirl
Quoted 14 lines · Michael S. Tsirkin
commit
5caef97a16010f818ea8b950e2ee24ba876643adintroduced
a regression: we do not make IO base/limit upper 16
bit registers writeable, so we should report a 16 bit
IO range type, not a 32 bit one.
Note thatPCI_PREF_RANGE_TYPE_32is0x0, butPCI_IO_RANGE_TYPE_32is0x1.In particular, this broke sparc64.
Note: this just reverts to behaviour prior to the patch. Making
PCI_IO_BASE_UPPER16andPCI_IO_LIMIT_UPPER16registers writeable should, and seems to, work just as well, but as no system seems to actually be interested in 32 bit IO, let's not make unnecessary changes.Quoted 4 lines
Reported-by Mark Cave-Ayland <[email protected]>Signed-off-by Michael S. Tsirkin <[email protected]>Mark, can you confirm that this fixes the bug for you?
Quoted 7 lines
No, running
qemu-system-sparc64 -serial stdio
still shows black screen and the following on console:
OpenBIOS for Sparc64
Unhandled Exception0x0000000000000032
PC =0x00000000ffd19e18NPC =0x00000000ffd19e1cStopping executionThe weird thing is the range type does not seem to be accessed at all. So I guessed there's some memory corruption here. Running valgrind shows this:
--11114-- WARNING: unhandled syscall: 340
--11114-- You may be able to write your own handler. --11114-- Read the fileREADME_MISSING_SYSCALL_OR_IOCTL. --11114-- Nevertheless we consider this a bug. Please report --11114-- it at http://valgrind.org/support/bug_reports.html.
==11114== Invalid read of size 4
==11114== at0x2A68C0:pci_apb_init(apb_pci.c:350) ==11114== by0x2F7A84:sun4uv_init(sun4u.c:779) ==11114== by0x13D716: main (vl.c:3397)
==11114== Address0x156c7d30is 0 bytes after a block of size 64 alloc'd
==11114== at0x557DD69: malloc (vg_replace_malloc.c:236) ==11114== by0x225F56:malloc_and_trace(vl.c:2156) ==11114== by0x584AFEC: ??? (in/lib/libglib-2.0.so.0.2800.8) ==11114== by0x584B528:g_malloc0(in/lib/libglib-2.0.so.0.2800.8) ==11114== by0x19C50C:qemu_allocate_irqs(irq.c:47) ==11114== by0x2F7A4C:sun4uv_init(sun4u.c:778) ==11114== by0x13D716: main (vl.c:3397)
==11114==
apb: here
==11114== Warning: client switching stacks? SP change:0xfec42cbc-->0x16894008
==11114== to suppress, use: --max-stackframe=398791500 or greater
==11114== Warning: client switching stacks? SP change:0x16893fa0-->0xfec42cc0
==11114== to suppress, use: --max-stackframe=398791392 or greater
==11114== Warning: client switching stacks? SP change:0xfec42fe0-->0x16893fd0
==11114== to suppress, use: --max-stackframe=398790640 or greater
==11114== further instances of this message will not be shown. QEMU 1.0.50 monitor - type 'help' for more information (qemu) ==11114== Thread 2:
==11114== Conditional jump or move depends on uninitialised value(s) ==11114== at0x2A8351:compute_all_sub(cc_helper.c:37) ==11114== by0x2A8782:helper_compute_psr(cc_helper.c:470) ==11114== by0x9AD9A19: ???
==11114==
==11114== Conditional jump or move depends on uninitialised value(s) ==11114== at0x2A827C:compute_all_sub_xcc(cc_helper.c:60) ==11114== by0x2A8795:helper_compute_psr(cc_helper.c:473) ==11114== by0x9AD9A19: ???
==11114==
==11114== Conditional jump or move depends on uninitialised value(s) ==11114== at0x2A8296:compute_all_sub_xcc(cc_helper.c:295) ==11114== by0x2A8795:helper_compute_psr(cc_helper.c:473) ==11114== by0x9AD9A19: ???
==11114==
Quoted 3 lines
Quoted 1 line
Is the above a problem?
It looks like Sparc does not reset registers at CPU reset. Nice catch.
Invalid read and address after block are also worrying.
irqs are allocated with
#define MAX_PILS 16
irq = qemu_allocate_irqs(cpu_set_irq, env, MAX_PILS);
then passed to apb:
pci_bus = pci_apb_init(APB_SPECIAL_BASE, APB_MEM_BASE, irq, &pci_bus2,
&pci_bus3);
which does:
PCIBus *pci_apb_init(target_phys_addr_t special_base,
target_phys_addr_t mem_base, qemu_irq *pic, PCIBus **bus2, PCIBus **bus3)
and
for (i = 0; i < 32; i++) {
sysbus_connect_irq(s, i, pic[i]);
}Quoted 201 lines
Quoted 166 lines
Quoted 104 lines
This unassigned memory exception is triggered because CMD646 IDE I/O registers are not accessible:
(qemu) info pci
Bus 0, device 0, function 0:
Host bridge: PCI device 108e:a000
id ""
Bus 0, device 1, function 0:
PCI bridge: PCI device 108e:5000
BUS 0.
secondary bus 1.
subordinate bus 1.
IO range [0x0000,0x0fff]
memory range [0x00000000,0x000fffff]
prefetchable memory range [0x00000000,0x000fffff] id ""
Bus 0, device 1, function 1:
PCI bridge: PCI device 108e:5000
BUS 0.
secondary bus 2.
subordinate bus 2.
IO range [0x0000,0x0fff]
memory range [0x00000000,0x000fffff]
prefetchable memory range [0x00000000,0x000fffff] id ""
Bus 0, device 2, function 0:
VGA controller: PCI device 1234:1111
BAR0: 32 bit prefetchable memory at0x00800000[0x00ffffff].
BAR6: 32 bit memory at0x01000000[0x0100ffff].
id ""
Bus 0, device 3, function 0:
Bridge: PCI device 108e:1000
BAR0: 32 bit memory at0x02000000[0x02ffffff].
BAR1: 32 bit memory at0x03000000[0x037fffff].
id ""
Bus 0, device 4, function 0:
Ethernet controller: PCI device 10ec:8029
IRQ 0.
BAR0: I/O at0xffffffffffffffff[0x00fe].
BAR6: 32 bit memory at0x03800000[0x0380ffff].
id ""
Bus 0, device 5, function 0:
IDE controller: PCI device 1095:0646
IRQ 1.
BAR0: I/O at0xffffffffffffffff[0x0006].
BAR1: I/O at0xffffffffffffffff[0x0002].
BAR2: I/O at0xffffffffffffffff[0x0006].
BAR3: I/O at0xffffffffffffffff[0x0002].
BAR4: I/O at0xffffffffffffffff[0x000e].
id ""
(qemu) info mtree
memory
0000000000000000-7ffffffffffffffe (prio 0, RW): system 0000000000000000-0000000007ffffff (prio 0, RW): sun4u.ram 000001fe00000000-000001fe0000ffff (prio 0, RW): apb-config 000001fe01000000-000001fe01ffffff (prio 0, RW): apb-pci-config 000001fe02000000-000001fe0200ffff (prio 0, RW): apb-pci-ioport 000001ff00000000-000001ffffffffff (prio 0, RW): pci-mmio 000001ff00000000-000001ff000fffff (prio 1, RW): aliaspci_bridge_mem@pci_bridge_pci 0000000000000000-00000000000fffff 000001ff00000000-000001ff000fffff (prio 1, RW): aliaspci_bridge_pref_mem@pci_bridge_pci 0000000000000000-00000000000fffff 000001ff00000000-000001ff000fffff (prio 1, RW): aliaspci_bridge_mem@pci_bridge_pci 0000000000000000-00000000000fffff 000001ff00000000-000001ff000fffff (prio 1, RW): aliaspci_bridge_pref_mem@pci_bridge_pci 0000000000000000-00000000000fffff 000001ff000a0000-000001ff000affff (prio 2, RW): alias vga.chain4 @vga.vram 0000000000000000-000000000000ffff 000001ff000a0000-000001ff000bffff (prio 1, RW): vga-lowmem 000001ff00800000-000001ff00ffffff (prio 1, RW): vga.vram 000001ff01000000-000001ff0100ffff (prio 1, RW): vga.rom 000001ff02000000-000001ff02ffffff (prio 1, RW): isa-mmio 000001ff03000000-000001ff037fffff (prio 1, RW): isa-mmio 000001ff03800000-000001ff0380ffff (prio 1, RW): ne2000.rom 000001fff0000000-000001fff03fffff (prio 0, R-): sun4u.prompci_bridge_pci
0000000000000000-7ffffffffffffffe (prio 0, RW):pci_bridge_pcipci_bridge_pci
0000000000000000-7ffffffffffffffe (prio 0, RW):pci_bridge_pcivga.vram
0000000000800000-0000000000ffffff (prio 1, RW): vga.vram I/O
0000000000000000-000000000000ffff (prio 0, RW): io 0000000000000000-0000000000000fff (prio 1, RW): aliaspci_bridge_io@pci_bridge_io 0000000000000000-0000000000000fff 0000000000000000-0000000000000fff (prio 1, RW): aliaspci_bridge_io@pci_bridge_io 0000000000000000-0000000000000fff 0000000000000060-0000000000000060 (prio 0, RW): i8042-data 0000000000000064-0000000000000064 (prio 0, RW): i8042-cmd 0000000000000074-0000000000000077 (prio 0, RW): m48t59 00000000000001ce-00000000000001ce (prio 0, RW): alias vbe @vbe 00000000000001ce-00000000000001ce 00000000000001d0-00000000000001d0 (prio 0, RW): alias vbe @vbe 00000000000001d0-00000000000001d0 0000000000000378-000000000000037f (prio 0, RW): alias parallel @parallel 0000000000000378-000000000000037f 00000000000003b4-00000000000003b5 (prio 0, RW): alias vga @vga 00000000000003b4-00000000000003b5 00000000000003ba-00000000000003ba (prio 0, RW): alias vga @vga 00000000000003ba-00000000000003ba 00000000000003c0-00000000000003cf (prio 0, RW): alias vga @vga 00000000000003c0-00000000000003cf 00000000000003d4-00000000000003d5 (prio 0, RW): alias vga @vga 00000000000003d4-00000000000003d5Quoted 8 lines
00000000000003da-00000000000003da (prio 0, RW): alias vga @vga 00000000000003da-00000000000003da 00000000000003f1-00000000000003f5 (prio 0, RW): alias fdc @fdc 00000000000003f1-00000000000003f5 00000000000003f7-00000000000003f7 (prio 0, RW): alias fdc @fdc 00000000000003f7-00000000000003f7 00000000000003f8-00000000000003ff (prio 0, RW): serial 0000000000000510-0000000000000511 (prio 0, RW): fwcfg
And with type 32 range it looks like this:
0000000000000000-7ffffffffffffffe (prio 0, RW): system 0000000000000000-0000000007ffffff (prio 0, RW): sun4u.ram 000001fe00000000-000001fe0000ffff (prio 0, RW): apb-config 000001fe01000000-000001fe01ffffff (prio 0, RW): apb-pci-config 000001fe02000000-000001fe0200ffff (prio 0, RW): apb-pci-ioport 000001ff00000000-000001ffffffffff (prio 0, RW): pci-mmio 000001ff00000000-000001ff000fffff (prio 1, RW): alias
pci_bridge_mem@pci_bridge_pci 0000000000000000-00000000000fffff 000001ff00000000-000001ff000fffff (prio 1, RW): aliaspci_bridge_pref_mem@pci_bridge_pci 0000000000000000-00000000000fffff 000001ff00000000-000001ff000fffff (prio 1, RW): aliaspci_bridge_mem@pci_bridge_pci 0000000000000000-00000000000fffff 000001ff00000000-000001ff000fffff (prio 1, RW): aliaspci_bridge_pref_mem@pci_bridge_pci 0000000000000000-00000000000fffff 000001ff000a0000-000001ff000affff (prio 2, RW): alias vga.chain4 @vga.vram 0000000000000000-000000000000ffff 000001ff000a0000-000001ff000bffff (prio 1, RW): vga-lowmem 000001ff00800000-000001ff00ffffff (prio 1, RW): vga.vram 000001ff01000000-000001ff0100ffff (prio 1, RW): vga.rom 000001ff02000000-000001ff02ffffff (prio 1, RW): isa-mmio 000001ff03000000-000001ff037fffff (prio 1, RW): isa-mmio 000001fff0000000-000001fff03fffff (prio 0, R-): sun4u.prompci_bridge_pci
0000000000000000-7ffffffffffffffe (prio 0, RW):pci_bridge_pcipci_bridge_pci
0000000000000000-7ffffffffffffffe (prio 0, RW):pci_bridge_pcivga.vram
0000000000800000-0000000000ffffff (prio 1, RW): vga.vram
I/O
0000000000000000-000000000000ffff (prio 0, RW): io 0000000000000000-0000000000000fff (prio 1, RW): aliaspci_bridge_io@pci_bridge_io 0000000000000000-0000000000000fff 0000000000000000-0000000000000fff (prio 1, RW): aliaspci_bridge_io@pci_bridge_io 0000000000000000-0000000000000fff 0000000000000060-0000000000000060 (prio 0, RW): i8042-data 0000000000000064-0000000000000064 (prio 0, RW): i8042-cmd 0000000000000074-0000000000000077 (prio 0, RW): m48t59 00000000000001ce-00000000000001ce (prio 0, RW): vbe 00000000000001d0-00000000000001d0 (prio 0, RW): vbe 0000000000000378-000000000000037f (prio 0, RW): parallel 00000000000003b4-00000000000003b5 (prio 0, RW): vga 00000000000003ba-00000000000003ba (prio 0, RW): vga 00000000000003c0-00000000000003cf (prio 0, RW): vga 00000000000003d4-00000000000003d5 (prio 0, RW): vga 00000000000003da-00000000000003da (prio 0, RW): vga 00000000000003f1-00000000000003f5 (prio 0, RW): fdc 00000000000003f7-00000000000003f7 (prio 0, RW): fdc 00000000000003f8-00000000000003ff (prio 0, RW): serial 0000000000000400-00000000000004ff (prio 1, RW): ne2000 0000000000000500-0000000000000507 (prio 1, RW): cmd646-data 0000000000000510-0000000000000511 (prio 0, RW): fwcfgQuoted 8 lines
0000000000000580-0000000000000583 (prio 1, RW): cmd646-cmd 0000000000000600-0000000000000607 (prio 1, RW): cmd646-data 0000000000000680-0000000000000683 (prio 1, RW): cmd646-cmd 0000000000000700-000000000000070f (prio 1, RW): cmd646-bmdma 0000000000000700-0000000000000703 (prio 0, RW): cmd646-bmdma-bus 0000000000000704-0000000000000707 (prio 0, RW): cmd646-bmdma-ioport 0000000000000708-000000000000070b (prio 0, RW): cmd646-bmdma-bus 000000000000070c-000000000000070f (prio 0, RW): cmd646-bmdma-ioport
This looks better.
Quoted 24 lines
Sill trying to understand what all this means.
Quoted 20 lines
Quoted 20 lines
hw/pci.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)hw/pci.c +2
-3@@ -633,8 +633,8 @@ static void pci_init_mask_bridge(PCIDevice *d) memset(d->wmask + PCI_PREF_BASE_UPPER32, 0xff, 8); /* Supported memory and i/o types */ - d->config[PCI_IO_BASE] |= PCI_IO_RANGE_TYPE_32; - d->config[PCI_IO_LIMIT] |= PCI_IO_RANGE_TYPE_32; + d->config[PCI_IO_BASE] |= PCI_IO_RANGE_TYPE_16; + d->config[PCI_IO_LIMIT] |= PCI_IO_RANGE_TYPE_16; pci_word_test_and_set_mask(d->config + PCI_PREF_MEMORY_BASE, PCI_PREF_RANGE_TYPE_64); pci_word_test_and_set_mask(d->config + PCI_PREF_MEMORY_LIMIT, --1.7.9.111.gf3fb0
Quoted 107 lines · Michael S. Tsirkin
Quoted 85 lines · Blue Swirl
Quoted 84 lines · Michael S. Tsirkin
Quoted 20 lines · Blue Swirl
Quoted 14 lines · Michael S. Tsirkin
commit
5caef97a16010f818ea8b950e2ee24ba876643adintroduced
a regression: we do not make IO base/limit upper 16
bit registers writeable, so we should report a 16 bit
IO range type, not a 32 bit one.
Note thatPCI_PREF_RANGE_TYPE_32is0x0, butPCI_IO_RANGE_TYPE_32is0x1.In particular, this broke sparc64.
Note: this just reverts to behaviour prior to the patch. Making
PCI_IO_BASE_UPPER16andPCI_IO_LIMIT_UPPER16registers writeable should, and seems to, work just as well, but as no system seems to actually be interested in 32 bit IO, let's not make unnecessary changes.Quoted 4 lines
Reported-by Mark Cave-Ayland <[email protected]>Signed-off-by Michael S. Tsirkin <[email protected]>Mark, can you confirm that this fixes the bug for you?
Quoted 7 lines
No, running
qemu-system-sparc64 -serial stdio
still shows black screen and the following on console:
OpenBIOS for Sparc64
Unhandled Exception0x0000000000000032
PC =0x00000000ffd19e18NPC =0x00000000ffd19e1cStopping executionThe weird thing is the range type does not seem to be accessed at all. So I guessed there's some memory corruption here. Running valgrind shows this:
--11114-- WARNING: unhandled syscall: 340
--11114-- You may be able to write your own handler. --11114-- Read the fileREADME_MISSING_SYSCALL_OR_IOCTL. --11114-- Nevertheless we consider this a bug. Please report --11114-- it at http://valgrind.org/support/bug_reports.html.
==11114== Invalid read of size 4
==11114== at0x2A68C0:pci_apb_init(apb_pci.c:350) ==11114== by0x2F7A84:sun4uv_init(sun4u.c:779) ==11114== by0x13D716: main (vl.c:3397)
==11114== Address0x156c7d30is 0 bytes after a block of size 64 alloc'd
==11114== at0x557DD69: malloc (vg_replace_malloc.c:236) ==11114== by0x225F56:malloc_and_trace(vl.c:2156) ==11114== by0x584AFEC: ??? (in/lib/libglib-2.0.so.0.2800.8) ==11114== by0x584B528:g_malloc0(in/lib/libglib-2.0.so.0.2800.8) ==11114== by0x19C50C:qemu_allocate_irqs(irq.c:47) ==11114== by0x2F7A4C:sun4uv_init(sun4u.c:778) ==11114== by0x13D716: main (vl.c:3397)
==11114==
apb: here
==11114== Warning: client switching stacks? SP change:0xfec42cbc-->0x16894008
==11114== to suppress, use: --max-stackframe=398791500 or greater
==11114== Warning: client switching stacks? SP change:0x16893fa0-->0xfec42cc0
==11114== to suppress, use: --max-stackframe=398791392 or greater
==11114== Warning: client switching stacks? SP change:0xfec42fe0-->0x16893fd0
==11114== to suppress, use: --max-stackframe=398790640 or greater
==11114== further instances of this message will not be shown. QEMU 1.0.50 monitor - type 'help' for more information (qemu) ==11114== Thread 2:
==11114== Conditional jump or move depends on uninitialised value(s) ==11114== at0x2A8351:compute_all_sub(cc_helper.c:37) ==11114== by0x2A8782:helper_compute_psr(cc_helper.c:470) ==11114== by0x9AD9A19: ???
==11114==
==11114== Conditional jump or move depends on uninitialised value(s) ==11114== at0x2A827C:compute_all_sub_xcc(cc_helper.c:60) ==11114== by0x2A8795:helper_compute_psr(cc_helper.c:473) ==11114== by0x9AD9A19: ???
==11114==
==11114== Conditional jump or move depends on uninitialised value(s) ==11114== at0x2A8296:compute_all_sub_xcc(cc_helper.c:295) ==11114== by0x2A8795:helper_compute_psr(cc_helper.c:473) ==11114== by0x9AD9A19: ???
==11114==Quoted 3 lines
Quoted 1 line
Is the above a problem?
It looks like Sparc does not reset registers at CPU reset. Nice catch.
Invalid read and address after block are also worrying.
irqs are allocated with
#defineMAX_PILS16irq =
qemu_allocate_irqs(cpu_set_irq, env, MAX_PILS);then passed to apb:
pci_bus =
pci_apb_init(APB_SPECIAL_BASE, APB_MEM_BASE, irq, &pci_bus2, &pci_bus3);which does:
PCIBus *pci_apb_init(target_phys_addr_tspecial_base,target_phys_addr_tmem_base,qemu_irq*pic, PCIBus **bus2, PCIBus **bus3)
Quoted 5 lines
and
for (i = 0; i < 32; i++) {
sysbus_connect_irq(s, i, pic[i]);
}
Awful. But using 32 for MAX_PILS does not help either.
I get this with a modified OpenBIOS and no secondary bridges:
OpenBIOS for Sparc64
Initializing PCI host bridge...pci_host_set_reg reg 000001FE 00000000 00000000 02000000
=== CHANGED === package path old=/pci new=/pci@1fe,0 0:0.0 - 108e:a000 - host bridge found - /pci@1fe,0 - pci_host_set_reg reg 000001FE 00000000 00000000 02000000 scanning new pci bus 0 under bridge /pci@1fe,0
Scanning bus 0 at /pci@1fe,0...
0:0.0 - 108e:a000 - host bridge found - /pci@1fe,0 - host bridge already configured
0:1.0 - 1234:1111 - /pci@1fe,0/QEMU,VGA - ob_pci_encode_unit space=0 dev=1 fn=0 buf=1
=== CHANGED === package path old=/pci@1fe,0/QEMU,VGA new=/pci@1fe,0/QEMU,VGA@1 pci_set_reg reg 00000800 00000000 00000000 00000000 00000000 42000810 00000000 00000000 00000000 00800000ob_pci_decode_unit idx=00000000ffe8be08ob_pci_decode_unit idx=00000000ffe8be08 addr=0000000000000000 0000000000000000 0000000000000800
0:2.0 - 108e:1000 - /pci@1fe,0/ebus -ob_pci_encode_unit space=0 dev=2 fn=0 buf=2
=== CHANGED === package path old=/pci@1fe,0/ebus new=/pci@1fe,0/ebus@2 pci_set_reg reg 00001000 00000000 00000000 00000000 00000000 02001010 00000000 00000000 00000000 01000000 02001014 00000000 00000000 00000000 00800000ob_pci_decode_unit idx=00000000ffe29248ob_pci_decode_unit idx=00000000ffe29248 addr=0000000000000000 0000000000000000 0000000000001000ob_pci_decode_unit idx=00000000ffe29248ob_pci_decode_unit idx=00000000ffe29248 addr=0000000000000000 0000000000000000 0000000000001000ob_pci_decode_unit idx=00000000ffe29248ob_pci_decode_unit idx=00000000ffe29248 addr=0000000000000000 0000000000000000 0000000000001000ob_pci_decode_unit idx=00000000ffe29248ob_pci_decode_unit idx=00000000ffe29248 addr=0000000000000000 0000000000000000 0000000000001000ob_pci_decode_unit idx=00000000ffe29248ob_pci_decode_unit idx=00000000ffe29248 addr=0000000000000000 0000000000000000 0000000000001000ob_pci_decode_unit idx=00000000ffe29248ob_pci_decode_unit idx=00000000ffe29248 addr=0000000000000000 0000000000000000 0000000000001000ob_pci_decode_unit idx=00000000ffe8bf38ob_pci_decode_unit idx=00000000ffe8bf38 addr=0000000000000000 0000000000000000 0000000000001000
0:3.0 - 10ec:8029 - /pci@1fe,0/NE2000 -ob_pci_encode_unit space=0 dev=3 fn=0 buf=3
=== CHANGED === package path old=/pci@1fe,0/NE2000 new=/pci@1fe,0/NE2000@3 pci_set_reg reg 00001800 00000000 00000000 00000000 00000000 01001810 00000000 00000000 00000000 00000100
0:4.0 - 1095:646 - /pci@1fe,0/pci-ata -ob_pci_encode_unit space=0 dev=4 fn=0 buf=4
=== CHANGED === package path old=/pci@1fe,0/pci-ata new=/pci@1fe,0/pci-ata@4 pci_set_reg reg 00002000 00000000 00000000 00000000 00000000 01002010 00000000 00000000 00000000 00000008 01002014 00000000 00000000 00000000 00000004 01002018 00000000 00000000 00000000 00000008 0100201C 00000000 00000000 00000000 00000004 01002020 00000000 00000000 00000000 00000010
Unhandled Exception 0x0000000000000032
PC = 0x00000000ffd1a1e4 NPC = 0x00000000ffd1a1e8
Stopping execution
QEMU 1.0.50 monitor - type 'help' for more information
Quoted 203 lines
Quoted 203 lines
Quoted 168 lines
Quoted 106 lines
This unassigned memory exception is triggered because CMD646 IDE I/O registers are not accessible:
(qemu) info pci
Bus 0, device 0, function 0:
Host bridge: PCI device 108e:a000
id ""
Bus 0, device 1, function 0:
PCI bridge: PCI device 108e:5000
BUS 0.
secondary bus 1.
subordinate bus 1.
IO range [0x0000,0x0fff]
memory range [0x00000000,0x000fffff]
prefetchable memory range [0x00000000,0x000fffff] id ""
Bus 0, device 1, function 1:
PCI bridge: PCI device 108e:5000
BUS 0.
secondary bus 2.
subordinate bus 2.
IO range [0x0000,0x0fff]
memory range [0x00000000,0x000fffff]
prefetchable memory range [0x00000000,0x000fffff] id ""
Bus 0, device 2, function 0:
VGA controller: PCI device 1234:1111
BAR0: 32 bit prefetchable memory at0x00800000[0x00ffffff].
BAR6: 32 bit memory at0x01000000[0x0100ffff].
id ""
Bus 0, device 3, function 0:
Bridge: PCI device 108e:1000
BAR0: 32 bit memory at0x02000000[0x02ffffff].
BAR1: 32 bit memory at0x03000000[0x037fffff].
id ""
Bus 0, device 4, function 0:
Ethernet controller: PCI device 10ec:8029
IRQ 0.
BAR0: I/O at0xffffffffffffffff[0x00fe].
BAR6: 32 bit memory at0x03800000[0x0380ffff].
id ""
Bus 0, device 5, function 0:
IDE controller: PCI device 1095:0646
IRQ 1.
BAR0: I/O at0xffffffffffffffff[0x0006].
BAR1: I/O at0xffffffffffffffff[0x0002].
BAR2: I/O at0xffffffffffffffff[0x0006].
BAR3: I/O at0xffffffffffffffff[0x0002].
BAR4: I/O at0xffffffffffffffff[0x000e].
id ""
(qemu) info mtree
memory
0000000000000000-7ffffffffffffffe (prio 0, RW): system 0000000000000000-0000000007ffffff (prio 0, RW): sun4u.ram 000001fe00000000-000001fe0000ffff (prio 0, RW): apb-config 000001fe01000000-000001fe01ffffff (prio 0, RW): apb-pci-config 000001fe02000000-000001fe0200ffff (prio 0, RW): apb-pci-ioport 000001ff00000000-000001ffffffffff (prio 0, RW): pci-mmio 000001ff00000000-000001ff000fffff (prio 1, RW): aliaspci_bridge_mem@pci_bridge_pci 0000000000000000-00000000000fffff 000001ff00000000-000001ff000fffff (prio 1, RW): aliaspci_bridge_pref_mem@pci_bridge_pci 0000000000000000-00000000000fffff 000001ff00000000-000001ff000fffff (prio 1, RW): aliaspci_bridge_mem@pci_bridge_pci 0000000000000000-00000000000fffff 000001ff00000000-000001ff000fffff (prio 1, RW): aliaspci_bridge_pref_mem@pci_bridge_pci 0000000000000000-00000000000fffff 000001ff000a0000-000001ff000affff (prio 2, RW): alias vga.chain4 @vga.vram 0000000000000000-000000000000ffff 000001ff000a0000-000001ff000bffff (prio 1, RW): vga-lowmem 000001ff00800000-000001ff00ffffff (prio 1, RW): vga.vram 000001ff01000000-000001ff0100ffff (prio 1, RW): vga.rom 000001ff02000000-000001ff02ffffff (prio 1, RW): isa-mmio 000001ff03000000-000001ff037fffff (prio 1, RW): isa-mmio 000001ff03800000-000001ff0380ffff (prio 1, RW): ne2000.rom 000001fff0000000-000001fff03fffff (prio 0, R-): sun4u.prompci_bridge_pci
0000000000000000-7ffffffffffffffe (prio 0, RW):pci_bridge_pcipci_bridge_pci
0000000000000000-7ffffffffffffffe (prio 0, RW):pci_bridge_pcivga.vram
0000000000800000-0000000000ffffff (prio 1, RW): vga.vram I/O
0000000000000000-000000000000ffff (prio 0, RW): io 0000000000000000-0000000000000fff (prio 1, RW): aliaspci_bridge_io@pci_bridge_io 0000000000000000-0000000000000fff 0000000000000000-0000000000000fff (prio 1, RW): aliaspci_bridge_io@pci_bridge_io 0000000000000000-0000000000000fff 0000000000000060-0000000000000060 (prio 0, RW): i8042-data 0000000000000064-0000000000000064 (prio 0, RW): i8042-cmd 0000000000000074-0000000000000077 (prio 0, RW): m48t59 00000000000001ce-00000000000001ce (prio 0, RW): alias vbe @vbe 00000000000001ce-00000000000001ce 00000000000001d0-00000000000001d0 (prio 0, RW): alias vbe @vbe 00000000000001d0-00000000000001d0 0000000000000378-000000000000037f (prio 0, RW): alias parallel @parallel 0000000000000378-000000000000037f 00000000000003b4-00000000000003b5 (prio 0, RW): alias vga @vga 00000000000003b4-00000000000003b5 00000000000003ba-00000000000003ba (prio 0, RW): alias vga @vga 00000000000003ba-00000000000003ba 00000000000003c0-00000000000003cf (prio 0, RW): alias vga @vga 00000000000003c0-00000000000003cf 00000000000003d4-00000000000003d5 (prio 0, RW): alias vga @vga 00000000000003d4-00000000000003d5Quoted 8 lines
00000000000003da-00000000000003da (prio 0, RW): alias vga @vga 00000000000003da-00000000000003da 00000000000003f1-00000000000003f5 (prio 0, RW): alias fdc @fdc 00000000000003f1-00000000000003f5 00000000000003f7-00000000000003f7 (prio 0, RW): alias fdc @fdc 00000000000003f7-00000000000003f7 00000000000003f8-00000000000003ff (prio 0, RW): serial 0000000000000510-0000000000000511 (prio 0, RW): fwcfg
And with type 32 range it looks like this:
0000000000000000-7ffffffffffffffe (prio 0, RW): system 0000000000000000-0000000007ffffff (prio 0, RW): sun4u.ram 000001fe00000000-000001fe0000ffff (prio 0, RW): apb-config 000001fe01000000-000001fe01ffffff (prio 0, RW): apb-pci-config 000001fe02000000-000001fe0200ffff (prio 0, RW): apb-pci-ioport 000001ff00000000-000001ffffffffff (prio 0, RW): pci-mmio 000001ff00000000-000001ff000fffff (prio 1, RW): alias
pci_bridge_mem@pci_bridge_pci 0000000000000000-00000000000fffff 000001ff00000000-000001ff000fffff (prio 1, RW): aliaspci_bridge_pref_mem@pci_bridge_pci 0000000000000000-00000000000fffff 000001ff00000000-000001ff000fffff (prio 1, RW): aliaspci_bridge_mem@pci_bridge_pci 0000000000000000-00000000000fffff 000001ff00000000-000001ff000fffff (prio 1, RW): aliaspci_bridge_pref_mem@pci_bridge_pci 0000000000000000-00000000000fffff 000001ff000a0000-000001ff000affff (prio 2, RW): alias vga.chain4 @vga.vram 0000000000000000-000000000000ffff 000001ff000a0000-000001ff000bffff (prio 1, RW): vga-lowmem 000001ff00800000-000001ff00ffffff (prio 1, RW): vga.vram 000001ff01000000-000001ff0100ffff (prio 1, RW): vga.rom 000001ff02000000-000001ff02ffffff (prio 1, RW): isa-mmio 000001ff03000000-000001ff037fffff (prio 1, RW): isa-mmio 000001fff0000000-000001fff03fffff (prio 0, R-): sun4u.prompci_bridge_pci
0000000000000000-7ffffffffffffffe (prio 0, RW):pci_bridge_pcipci_bridge_pci
0000000000000000-7ffffffffffffffe (prio 0, RW):pci_bridge_pcivga.vram
0000000000800000-0000000000ffffff (prio 1, RW): vga.vram
I/O
0000000000000000-000000000000ffff (prio 0, RW): io 0000000000000000-0000000000000fff (prio 1, RW): aliaspci_bridge_io@pci_bridge_io 0000000000000000-0000000000000fff 0000000000000000-0000000000000fff (prio 1, RW): aliaspci_bridge_io@pci_bridge_io 0000000000000000-0000000000000fff 0000000000000060-0000000000000060 (prio 0, RW): i8042-data 0000000000000064-0000000000000064 (prio 0, RW): i8042-cmd 0000000000000074-0000000000000077 (prio 0, RW): m48t59 00000000000001ce-00000000000001ce (prio 0, RW): vbe 00000000000001d0-00000000000001d0 (prio 0, RW): vbe 0000000000000378-000000000000037f (prio 0, RW): parallel 00000000000003b4-00000000000003b5 (prio 0, RW): vga 00000000000003ba-00000000000003ba (prio 0, RW): vga 00000000000003c0-00000000000003cf (prio 0, RW): vga 00000000000003d4-00000000000003d5 (prio 0, RW): vga 00000000000003da-00000000000003da (prio 0, RW): vga 00000000000003f1-00000000000003f5 (prio 0, RW): fdc 00000000000003f7-00000000000003f7 (prio 0, RW): fdc 00000000000003f8-00000000000003ff (prio 0, RW): serial 0000000000000400-00000000000004ff (prio 1, RW): ne2000 0000000000000500-0000000000000507 (prio 1, RW): cmd646-data 0000000000000510-0000000000000511 (prio 0, RW): fwcfgQuoted 8 lines
0000000000000580-0000000000000583 (prio 1, RW): cmd646-cmd 0000000000000600-0000000000000607 (prio 1, RW): cmd646-data 0000000000000680-0000000000000683 (prio 1, RW): cmd646-cmd 0000000000000700-000000000000070f (prio 1, RW): cmd646-bmdma 0000000000000700-0000000000000703 (prio 0, RW): cmd646-bmdma-bus 0000000000000704-0000000000000707 (prio 0, RW): cmd646-bmdma-ioport 0000000000000708-000000000000070b (prio 0, RW): cmd646-bmdma-bus 000000000000070c-000000000000070f (prio 0, RW): cmd646-bmdma-ioport
This looks better.
Quoted 24 lines
Sill trying to understand what all this means.
Quoted 20 lines
Quoted 20 lines
hw/pci.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)hw/pci.c +2
-3@@ -633,8 +633,8 @@ static void pci_init_mask_bridge(PCIDevice *d) memset(d->wmask + PCI_PREF_BASE_UPPER32, 0xff, 8); /* Supported memory and i/o types */ - d->config[PCI_IO_BASE] |= PCI_IO_RANGE_TYPE_32; - d->config[PCI_IO_LIMIT] |= PCI_IO_RANGE_TYPE_32; + d->config[PCI_IO_BASE] |= PCI_IO_RANGE_TYPE_16; + d->config[PCI_IO_LIMIT] |= PCI_IO_RANGE_TYPE_16; pci_word_test_and_set_mask(d->config + PCI_PREF_MEMORY_BASE, PCI_PREF_RANGE_TYPE_64); pci_word_test_and_set_mask(d->config + PCI_PREF_MEMORY_LIMIT, --1.7.9.111.gf3fb0
Quoted 108 lines · Blue Swirl
Quoted 107 lines · Michael S. Tsirkin
Quoted 85 lines · Blue Swirl
Quoted 84 lines · Michael S. Tsirkin
Quoted 20 lines · Blue Swirl
Quoted 14 lines · Michael S. Tsirkin
commit
5caef97a16010f818ea8b950e2ee24ba876643adintroduced
a regression: we do not make IO base/limit upper 16
bit registers writeable, so we should report a 16 bit
IO range type, not a 32 bit one.
Note thatPCI_PREF_RANGE_TYPE_32is0x0, butPCI_IO_RANGE_TYPE_32is0x1.In particular, this broke sparc64.
Note: this just reverts to behaviour prior to the patch. Making
PCI_IO_BASE_UPPER16andPCI_IO_LIMIT_UPPER16registers writeable should, and seems to, work just as well, but as no system seems to actually be interested in 32 bit IO, let's not make unnecessary changes.Quoted 4 lines
Reported-by Mark Cave-Ayland <[email protected]>Signed-off-by Michael S. Tsirkin <[email protected]>Mark, can you confirm that this fixes the bug for you?
Quoted 7 lines
No, running
qemu-system-sparc64 -serial stdio
still shows black screen and the following on console:
OpenBIOS for Sparc64
Unhandled Exception0x0000000000000032
PC =0x00000000ffd19e18NPC =0x00000000ffd19e1cStopping executionThe weird thing is the range type does not seem to be accessed at all. So I guessed there's some memory corruption here. Running valgrind shows this:
--11114-- WARNING: unhandled syscall: 340
--11114-- You may be able to write your own handler. --11114-- Read the fileREADME_MISSING_SYSCALL_OR_IOCTL. --11114-- Nevertheless we consider this a bug. Please report --11114-- it at http://valgrind.org/support/bug_reports.html.
==11114== Invalid read of size 4
==11114== at0x2A68C0:pci_apb_init(apb_pci.c:350) ==11114== by0x2F7A84:sun4uv_init(sun4u.c:779) ==11114== by0x13D716: main (vl.c:3397)
==11114== Address0x156c7d30is 0 bytes after a block of size 64 alloc'd
==11114== at0x557DD69: malloc (vg_replace_malloc.c:236) ==11114== by0x225F56:malloc_and_trace(vl.c:2156) ==11114== by0x584AFEC: ??? (in/lib/libglib-2.0.so.0.2800.8) ==11114== by0x584B528:g_malloc0(in/lib/libglib-2.0.so.0.2800.8) ==11114== by0x19C50C:qemu_allocate_irqs(irq.c:47) ==11114== by0x2F7A4C:sun4uv_init(sun4u.c:778) ==11114== by0x13D716: main (vl.c:3397)
==11114==
apb: here
==11114== Warning: client switching stacks? SP change:0xfec42cbc-->0x16894008
==11114== to suppress, use: --max-stackframe=398791500 or greater
==11114== Warning: client switching stacks? SP change:0x16893fa0-->0xfec42cc0
==11114== to suppress, use: --max-stackframe=398791392 or greater
==11114== Warning: client switching stacks? SP change:0xfec42fe0-->0x16893fd0
==11114== to suppress, use: --max-stackframe=398790640 or greater
==11114== further instances of this message will not be shown. QEMU 1.0.50 monitor - type 'help' for more information (qemu) ==11114== Thread 2:
==11114== Conditional jump or move depends on uninitialised value(s) ==11114== at0x2A8351:compute_all_sub(cc_helper.c:37) ==11114== by0x2A8782:helper_compute_psr(cc_helper.c:470) ==11114== by0x9AD9A19: ???
==11114==
==11114== Conditional jump or move depends on uninitialised value(s) ==11114== at0x2A827C:compute_all_sub_xcc(cc_helper.c:60) ==11114== by0x2A8795:helper_compute_psr(cc_helper.c:473) ==11114== by0x9AD9A19: ???
==11114==
==11114== Conditional jump or move depends on uninitialised value(s) ==11114== at0x2A8296:compute_all_sub_xcc(cc_helper.c:295) ==11114== by0x2A8795:helper_compute_psr(cc_helper.c:473) ==11114== by0x9AD9A19: ???
==11114==Quoted 3 lines
Quoted 1 line
Is the above a problem?
It looks like Sparc does not reset registers at CPU reset. Nice catch.
Invalid read and address after block are also worrying.
irqs are allocated with
#defineMAX_PILS16irq =
qemu_allocate_irqs(cpu_set_irq, env, MAX_PILS);then passed to apb:
pci_bus =
pci_apb_init(APB_SPECIAL_BASE, APB_MEM_BASE, irq, &pci_bus2, &pci_bus3);which does:
PCIBus *pci_apb_init(target_phys_addr_tspecial_base,target_phys_addr_tmem_base,qemu_irq*pic, PCIBus **bus2, PCIBus **bus3)
Quoted 7 lines
Quoted 5 lines
and
for (i = 0; i < 32; i++) {
sysbus_connect_irq(s, i, pic[i]);
}Awful. But using 32 for
MAX_PILSdoes not help either.
Could you please clarify what is the SABRE device? Is it, in fact, a bridge device? Or not?
Signature · 1 line
MST
Quoted 115 lines · Michael S. Tsirkin
Quoted 114 lines · Blue Swirl
Quoted 112 lines · Michael S. Tsirkin
Quoted 85 lines · Blue Swirl
Quoted 84 lines · Michael S. Tsirkin
Quoted 20 lines · Blue Swirl
Quoted 14 lines · Michael S. Tsirkin
commit
5caef97a16010f818ea8b950e2ee24ba876643adintroduced
a regression: we do not make IO base/limit upper 16
bit registers writeable, so we should report a 16 bit
IO range type, not a 32 bit one.
Note thatPCI_PREF_RANGE_TYPE_32is0x0, butPCI_IO_RANGE_TYPE_32is0x1.In particular, this broke sparc64.
Note: this just reverts to behaviour prior to the patch. Making
PCI_IO_BASE_UPPER16andPCI_IO_LIMIT_UPPER16registers writeable should, and seems to, work just as well, but as no system seems to actually be interested in 32 bit IO, let's not make unnecessary changes.Quoted 4 lines
Reported-by Mark Cave-Ayland <[email protected]>Signed-off-by Michael S. Tsirkin <[email protected]>Mark, can you confirm that this fixes the bug for you?
Quoted 7 lines
No, running
qemu-system-sparc64 -serial stdio
still shows black screen and the following on console:
OpenBIOS for Sparc64
Unhandled Exception0x0000000000000032
PC =0x00000000ffd19e18NPC =0x00000000ffd19e1cStopping executionThe weird thing is the range type does not seem to be accessed at all. So I guessed there's some memory corruption here. Running valgrind shows this:
--11114-- WARNING: unhandled syscall: 340
--11114-- You may be able to write your own handler. --11114-- Read the fileREADME_MISSING_SYSCALL_OR_IOCTL. --11114-- Nevertheless we consider this a bug. Please report --11114-- it at http://valgrind.org/support/bug_reports.html.
==11114== Invalid read of size 4
==11114== at0x2A68C0:pci_apb_init(apb_pci.c:350) ==11114== by0x2F7A84:sun4uv_init(sun4u.c:779) ==11114== by0x13D716: main (vl.c:3397)
==11114== Address0x156c7d30is 0 bytes after a block of size 64 alloc'd
==11114== at0x557DD69: malloc (vg_replace_malloc.c:236) ==11114== by0x225F56:malloc_and_trace(vl.c:2156) ==11114== by0x584AFEC: ??? (in/lib/libglib-2.0.so.0.2800.8) ==11114== by0x584B528:g_malloc0(in/lib/libglib-2.0.so.0.2800.8) ==11114== by0x19C50C:qemu_allocate_irqs(irq.c:47) ==11114== by0x2F7A4C:sun4uv_init(sun4u.c:778) ==11114== by0x13D716: main (vl.c:3397)
==11114==
apb: here
==11114== Warning: client switching stacks? SP change:0xfec42cbc-->0x16894008
==11114== to suppress, use: --max-stackframe=398791500 or greater
==11114== Warning: client switching stacks? SP change:0x16893fa0-->0xfec42cc0
==11114== to suppress, use: --max-stackframe=398791392 or greater
==11114== Warning: client switching stacks? SP change:0xfec42fe0-->0x16893fd0
==11114== to suppress, use: --max-stackframe=398790640 or greater
==11114== further instances of this message will not be shown. QEMU 1.0.50 monitor - type 'help' for more information (qemu) ==11114== Thread 2:
==11114== Conditional jump or move depends on uninitialised value(s) ==11114== at0x2A8351:compute_all_sub(cc_helper.c:37) ==11114== by0x2A8782:helper_compute_psr(cc_helper.c:470) ==11114== by0x9AD9A19: ???
==11114==
==11114== Conditional jump or move depends on uninitialised value(s) ==11114== at0x2A827C:compute_all_sub_xcc(cc_helper.c:60) ==11114== by0x2A8795:helper_compute_psr(cc_helper.c:473) ==11114== by0x9AD9A19: ???
==11114==
==11114== Conditional jump or move depends on uninitialised value(s) ==11114== at0x2A8296:compute_all_sub_xcc(cc_helper.c:295) ==11114== by0x2A8795:helper_compute_psr(cc_helper.c:473) ==11114== by0x9AD9A19: ???
==11114==Quoted 3 lines
Quoted 1 line
Is the above a problem?
It looks like Sparc does not reset registers at CPU reset. Nice catch.
Invalid read and address after block are also worrying.
irqs are allocated with
#defineMAX_PILS16irq =
qemu_allocate_irqs(cpu_set_irq, env, MAX_PILS);then passed to apb:
pci_bus =
pci_apb_init(APB_SPECIAL_BASE, APB_MEM_BASE, irq, &pci_bus2, &pci_bus3);which does:
PCIBus *pci_apb_init(target_phys_addr_tspecial_base,target_phys_addr_tmem_base,qemu_irq*pic, PCIBus **bus2, PCIBus **bus3)and
for (i = 0; i < 32; i++) {
sysbus_connect_irq(s, i, pic[i]);
}
Quoted 5 lines
Quoted 1 line
Awful. But using 32 for
MAX_PILSdoes not help either.Could you please clarify what is the SABRE device? Is it, in fact, a bridge device? Or not?
Yes, it's the host bridge, also known as PBM. It's documented in UltraSPARC IIi User's Manual and there it says that the device is found in the configuration space.
The secondary bridges are Simbas and should be called APBs.
Quoted 4 lines
--
MST
Quoted 116 lines · Blue Swirl
Quoted 115 lines · Michael S. Tsirkin
Quoted 114 lines · Blue Swirl
Quoted 112 lines · Michael S. Tsirkin
Quoted 85 lines · Blue Swirl
Quoted 84 lines · Michael S. Tsirkin
Quoted 20 lines · Blue Swirl
Quoted 14 lines · Michael S. Tsirkin
commit
5caef97a16010f818ea8b950e2ee24ba876643adintroduced
a regression: we do not make IO base/limit upper 16
bit registers writeable, so we should report a 16 bit
IO range type, not a 32 bit one.
Note thatPCI_PREF_RANGE_TYPE_32is0x0, butPCI_IO_RANGE_TYPE_32is0x1.In particular, this broke sparc64.
Note: this just reverts to behaviour prior to the patch. Making
PCI_IO_BASE_UPPER16andPCI_IO_LIMIT_UPPER16registers writeable should, and seems to, work just as well, but as no system seems to actually be interested in 32 bit IO, let's not make unnecessary changes.Quoted 4 lines
Reported-by Mark Cave-Ayland <[email protected]>Signed-off-by Michael S. Tsirkin <[email protected]>Mark, can you confirm that this fixes the bug for you?
Quoted 7 lines
No, running
qemu-system-sparc64 -serial stdio
still shows black screen and the following on console:
OpenBIOS for Sparc64
Unhandled Exception0x0000000000000032
PC =0x00000000ffd19e18NPC =0x00000000ffd19e1cStopping executionThe weird thing is the range type does not seem to be accessed at all. So I guessed there's some memory corruption here. Running valgrind shows this:
--11114-- WARNING: unhandled syscall: 340
--11114-- You may be able to write your own handler. --11114-- Read the fileREADME_MISSING_SYSCALL_OR_IOCTL. --11114-- Nevertheless we consider this a bug. Please report --11114-- it at http://valgrind.org/support/bug_reports.html.
==11114== Invalid read of size 4
==11114== at0x2A68C0:pci_apb_init(apb_pci.c:350) ==11114== by0x2F7A84:sun4uv_init(sun4u.c:779) ==11114== by0x13D716: main (vl.c:3397)
==11114== Address0x156c7d30is 0 bytes after a block of size 64 alloc'd
==11114== at0x557DD69: malloc (vg_replace_malloc.c:236) ==11114== by0x225F56:malloc_and_trace(vl.c:2156) ==11114== by0x584AFEC: ??? (in/lib/libglib-2.0.so.0.2800.8) ==11114== by0x584B528:g_malloc0(in/lib/libglib-2.0.so.0.2800.8) ==11114== by0x19C50C:qemu_allocate_irqs(irq.c:47) ==11114== by0x2F7A4C:sun4uv_init(sun4u.c:778) ==11114== by0x13D716: main (vl.c:3397)
==11114==
apb: here
==11114== Warning: client switching stacks? SP change:0xfec42cbc-->0x16894008
==11114== to suppress, use: --max-stackframe=398791500 or greater
==11114== Warning: client switching stacks? SP change:0x16893fa0-->0xfec42cc0
==11114== to suppress, use: --max-stackframe=398791392 or greater
==11114== Warning: client switching stacks? SP change:0xfec42fe0-->0x16893fd0
==11114== to suppress, use: --max-stackframe=398790640 or greater
==11114== further instances of this message will not be shown. QEMU 1.0.50 monitor - type 'help' for more information (qemu) ==11114== Thread 2:
==11114== Conditional jump or move depends on uninitialised value(s) ==11114== at0x2A8351:compute_all_sub(cc_helper.c:37) ==11114== by0x2A8782:helper_compute_psr(cc_helper.c:470) ==11114== by0x9AD9A19: ???
==11114==
==11114== Conditional jump or move depends on uninitialised value(s) ==11114== at0x2A827C:compute_all_sub_xcc(cc_helper.c:60) ==11114== by0x2A8795:helper_compute_psr(cc_helper.c:473) ==11114== by0x9AD9A19: ???
==11114==
==11114== Conditional jump or move depends on uninitialised value(s) ==11114== at0x2A8296:compute_all_sub_xcc(cc_helper.c:295) ==11114== by0x2A8795:helper_compute_psr(cc_helper.c:473) ==11114== by0x9AD9A19: ???
==11114==Quoted 3 lines
Quoted 1 line
Is the above a problem?
It looks like Sparc does not reset registers at CPU reset. Nice catch.
Invalid read and address after block are also worrying.
irqs are allocated with
#defineMAX_PILS16irq =
qemu_allocate_irqs(cpu_set_irq, env, MAX_PILS);then passed to apb:
pci_bus =
pci_apb_init(APB_SPECIAL_BASE, APB_MEM_BASE, irq, &pci_bus2, &pci_bus3);which does:
PCIBus *pci_apb_init(target_phys_addr_tspecial_base,target_phys_addr_tmem_base,qemu_irq*pic, PCIBus **bus2, PCIBus **bus3)and
for (i = 0; i < 32; i++) {
sysbus_connect_irq(s, i, pic[i]);
}
Quoted 8 lines
Quoted 5 lines
Quoted 1 line
Awful. But using 32 for
MAX_PILSdoes not help either.Could you please clarify what is the SABRE device? Is it, in fact, a bridge device? Or not?
Yes, it's the host bridge, also known as PBM. It's documented in UltraSPARC IIi User's Manual
Btw would be nice to host the manuals at qemu.org our code points at sun.com URLs :(
I am looking at 19.3.1 PCI Configuration Space and it appears to show that this is a regular device with a couple of custom registers at pffsets 0x40 and 0x41.
Why do we want to pretend it is a bridge?
Quoted 4 lines
and there it says that the device is
found in the configuration space.The secondary bridges are Simbas and should be called APBs.
As far as I can see from the code, it has header type NORMAL but sets is_bridge.
This was done by this commit:776e1bbb6cf4fe66a93c1a5dd814bbb650deca00
Quoted 4 lines
Quoted 4 lines
--
MST
Quoted 120 lines · Michael S. Tsirkin
Quoted 119 lines · Blue Swirl
Quoted 118 lines · Michael S. Tsirkin
Quoted 115 lines · Blue Swirl
Quoted 107 lines · Michael S. Tsirkin
Quoted 85 lines · Blue Swirl
Quoted 84 lines · Michael S. Tsirkin
Quoted 20 lines · Blue Swirl
Quoted 14 lines · Michael S. Tsirkin
commit
5caef97a16010f818ea8b950e2ee24ba876643adintroduced
a regression: we do not make IO base/limit upper 16
bit registers writeable, so we should report a 16 bit
IO range type, not a 32 bit one.
Note thatPCI_PREF_RANGE_TYPE_32is0x0, butPCI_IO_RANGE_TYPE_32is0x1.In particular, this broke sparc64.
Note: this just reverts to behaviour prior to the patch. Making
PCI_IO_BASE_UPPER16andPCI_IO_LIMIT_UPPER16registers writeable should, and seems to, work just as well, but as no system seems to actually be interested in 32 bit IO, let's not make unnecessary changes.Quoted 4 lines
Reported-by Mark Cave-Ayland <[email protected]>Signed-off-by Michael S. Tsirkin <[email protected]>Mark, can you confirm that this fixes the bug for you?
Quoted 7 lines
No, running
qemu-system-sparc64 -serial stdio
still shows black screen and the following on console:
OpenBIOS for Sparc64
Unhandled Exception0x0000000000000032
PC =0x00000000ffd19e18NPC =0x00000000ffd19e1cStopping executionThe weird thing is the range type does not seem to be accessed at all. So I guessed there's some memory corruption here. Running valgrind shows this:
--11114-- WARNING: unhandled syscall: 340
--11114-- You may be able to write your own handler. --11114-- Read the fileREADME_MISSING_SYSCALL_OR_IOCTL. --11114-- Nevertheless we consider this a bug. Please report --11114-- it at http://valgrind.org/support/bug_reports.html.
==11114== Invalid read of size 4
==11114== at0x2A68C0:pci_apb_init(apb_pci.c:350) ==11114== by0x2F7A84:sun4uv_init(sun4u.c:779) ==11114== by0x13D716: main (vl.c:3397)
==11114== Address0x156c7d30is 0 bytes after a block of size 64 alloc'd
==11114== at0x557DD69: malloc (vg_replace_malloc.c:236) ==11114== by0x225F56:malloc_and_trace(vl.c:2156) ==11114== by0x584AFEC: ??? (in/lib/libglib-2.0.so.0.2800.8) ==11114== by0x584B528:g_malloc0(in/lib/libglib-2.0.so.0.2800.8) ==11114== by0x19C50C:qemu_allocate_irqs(irq.c:47) ==11114== by0x2F7A4C:sun4uv_init(sun4u.c:778) ==11114== by0x13D716: main (vl.c:3397)
==11114==
apb: here
==11114== Warning: client switching stacks? SP change:0xfec42cbc-->0x16894008
==11114== to suppress, use: --max-stackframe=398791500 or greater
==11114== Warning: client switching stacks? SP change:0x16893fa0-->0xfec42cc0
==11114== to suppress, use: --max-stackframe=398791392 or greater
==11114== Warning: client switching stacks? SP change:0xfec42fe0-->0x16893fd0
==11114== to suppress, use: --max-stackframe=398790640 or greater
==11114== further instances of this message will not be shown. QEMU 1.0.50 monitor - type 'help' for more information (qemu) ==11114== Thread 2:
==11114== Conditional jump or move depends on uninitialised value(s) ==11114== at0x2A8351:compute_all_sub(cc_helper.c:37) ==11114== by0x2A8782:helper_compute_psr(cc_helper.c:470) ==11114== by0x9AD9A19: ???
==11114==
==11114== Conditional jump or move depends on uninitialised value(s) ==11114== at0x2A827C:compute_all_sub_xcc(cc_helper.c:60) ==11114== by0x2A8795:helper_compute_psr(cc_helper.c:473) ==11114== by0x9AD9A19: ???
==11114==
==11114== Conditional jump or move depends on uninitialised value(s) ==11114== at0x2A8296:compute_all_sub_xcc(cc_helper.c:295) ==11114== by0x2A8795:helper_compute_psr(cc_helper.c:473) ==11114== by0x9AD9A19: ???
==11114==Quoted 3 lines
Quoted 1 line
Is the above a problem?
It looks like Sparc does not reset registers at CPU reset. Nice catch.
Invalid read and address after block are also worrying.
irqs are allocated with
#defineMAX_PILS16irq =
qemu_allocate_irqs(cpu_set_irq, env, MAX_PILS);then passed to apb:
pci_bus =
pci_apb_init(APB_SPECIAL_BASE, APB_MEM_BASE, irq, &pci_bus2, &pci_bus3);which does:
PCIBus *pci_apb_init(target_phys_addr_tspecial_base,target_phys_addr_tmem_base,qemu_irq*pic, PCIBus **bus2, PCIBus **bus3)Quoted 5 lines
and
for (i = 0; i < 32; i++) {
sysbus_connect_irq(s, i, pic[i]);
}Awful. But using 32 for
MAX_PILSdoes not help either.
Quoted 8 lines
Quoted 5 lines
Quoted 2 lines
Could you please clarify what is the SABRE device? Is it, in fact, a bridge device? Or not?
Yes, it's the host bridge, also known as PBM. It's documented in UltraSPARC IIi User's Manual
Btw would be nice to host the manuals at qemu.org our code points at sun.com URLs :(
I have most if not all manuals, downloaded from sun.com, but I'm not sure if they can be redistributed.
Quoted 6 lines
I am looking at 19.3.1 PCI Configuration Space and it appears to show that this is a regular device with a couple of custom registers at pffsets
0x40and0x41.Why do we want to pretend it is a bridge?
It's the host bridge and the device class is PCI_CLASS_BRIDGE_HOST.
Quoted 10 lines
Quoted 5 lines
and there it says that the device is
found in the configuration space.The secondary bridges are Simbas and should be called APBs.
As far as I can see from the code, it has header type NORMAL but sets
is_bridge.
This was done by this commit:776e1bbb6cf4fe66a93c1a5dd814bbb650deca00
IIRC otherwise some registers are not writable.
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
--
MST
Quoted 124 lines · Blue Swirl
Quoted 123 lines · Michael S. Tsirkin
Quoted 122 lines · Blue Swirl
Quoted 120 lines · Michael S. Tsirkin
Quoted 108 lines · Blue Swirl
Quoted 107 lines · Michael S. Tsirkin
Quoted 85 lines · Blue Swirl
Quoted 84 lines · Michael S. Tsirkin
Quoted 20 lines · Blue Swirl
Quoted 14 lines · Michael S. Tsirkin
commit
5caef97a16010f818ea8b950e2ee24ba876643adintroduced
a regression: we do not make IO base/limit upper 16
bit registers writeable, so we should report a 16 bit
IO range type, not a 32 bit one.
Note thatPCI_PREF_RANGE_TYPE_32is0x0, butPCI_IO_RANGE_TYPE_32is0x1.In particular, this broke sparc64.
Note: this just reverts to behaviour prior to the patch. Making
PCI_IO_BASE_UPPER16andPCI_IO_LIMIT_UPPER16registers writeable should, and seems to, work just as well, but as no system seems to actually be interested in 32 bit IO, let's not make unnecessary changes.Quoted 4 lines
Reported-by Mark Cave-Ayland <[email protected]>Signed-off-by Michael S. Tsirkin <[email protected]>Mark, can you confirm that this fixes the bug for you?
Quoted 7 lines
No, running
qemu-system-sparc64 -serial stdio
still shows black screen and the following on console:
OpenBIOS for Sparc64
Unhandled Exception0x0000000000000032
PC =0x00000000ffd19e18NPC =0x00000000ffd19e1cStopping executionThe weird thing is the range type does not seem to be accessed at all. So I guessed there's some memory corruption here. Running valgrind shows this:
--11114-- WARNING: unhandled syscall: 340
--11114-- You may be able to write your own handler. --11114-- Read the fileREADME_MISSING_SYSCALL_OR_IOCTL. --11114-- Nevertheless we consider this a bug. Please report --11114-- it at http://valgrind.org/support/bug_reports.html.
==11114== Invalid read of size 4
==11114== at0x2A68C0:pci_apb_init(apb_pci.c:350) ==11114== by0x2F7A84:sun4uv_init(sun4u.c:779) ==11114== by0x13D716: main (vl.c:3397)
==11114== Address0x156c7d30is 0 bytes after a block of size 64 alloc'd
==11114== at0x557DD69: malloc (vg_replace_malloc.c:236) ==11114== by0x225F56:malloc_and_trace(vl.c:2156) ==11114== by0x584AFEC: ??? (in/lib/libglib-2.0.so.0.2800.8) ==11114== by0x584B528:g_malloc0(in/lib/libglib-2.0.so.0.2800.8) ==11114== by0x19C50C:qemu_allocate_irqs(irq.c:47) ==11114== by0x2F7A4C:sun4uv_init(sun4u.c:778) ==11114== by0x13D716: main (vl.c:3397)
==11114==
apb: here
==11114== Warning: client switching stacks? SP change:0xfec42cbc-->0x16894008
==11114== to suppress, use: --max-stackframe=398791500 or greater
==11114== Warning: client switching stacks? SP change:0x16893fa0-->0xfec42cc0
==11114== to suppress, use: --max-stackframe=398791392 or greater
==11114== Warning: client switching stacks? SP change:0xfec42fe0-->0x16893fd0
==11114== to suppress, use: --max-stackframe=398790640 or greater
==11114== further instances of this message will not be shown. QEMU 1.0.50 monitor - type 'help' for more information (qemu) ==11114== Thread 2:
==11114== Conditional jump or move depends on uninitialised value(s) ==11114== at0x2A8351:compute_all_sub(cc_helper.c:37) ==11114== by0x2A8782:helper_compute_psr(cc_helper.c:470) ==11114== by0x9AD9A19: ???
==11114==
==11114== Conditional jump or move depends on uninitialised value(s) ==11114== at0x2A827C:compute_all_sub_xcc(cc_helper.c:60) ==11114== by0x2A8795:helper_compute_psr(cc_helper.c:473) ==11114== by0x9AD9A19: ???
==11114==
==11114== Conditional jump or move depends on uninitialised value(s) ==11114== at0x2A8296:compute_all_sub_xcc(cc_helper.c:295) ==11114== by0x2A8795:helper_compute_psr(cc_helper.c:473) ==11114== by0x9AD9A19: ???
==11114==Quoted 3 lines
Quoted 1 line
Is the above a problem?
It looks like Sparc does not reset registers at CPU reset. Nice catch.
Invalid read and address after block are also worrying.
irqs are allocated with
#defineMAX_PILS16irq =
qemu_allocate_irqs(cpu_set_irq, env, MAX_PILS);then passed to apb:
pci_bus =
pci_apb_init(APB_SPECIAL_BASE, APB_MEM_BASE, irq, &pci_bus2, &pci_bus3);which does:
PCIBus *pci_apb_init(target_phys_addr_tspecial_base,target_phys_addr_tmem_base,qemu_irq*pic, PCIBus **bus2, PCIBus **bus3)Quoted 7 lines
Quoted 5 lines
and
for (i = 0; i < 32; i++) {
sysbus_connect_irq(s, i, pic[i]);
}Awful. But using 32 for
MAX_PILSdoes not help either.Could you please clarify what is the SABRE device? Is it, in fact, a bridge device? Or not?
Quoted 8 lines
Quoted 5 lines
Quoted 2 lines
Yes, it's the host bridge, also known as PBM. It's documented in UltraSPARC IIi User's Manual
Btw would be nice to host the manuals at qemu.org our code points at sun.com URLs :(
I have most if not all manuals, downloaded from sun.com, but I'm not sure if they can be redistributed.
Okay ...
Let's change the link to point to some other place which has them?
Quoted 8 lines
Quoted 6 lines
I am looking at 19.3.1 PCI Configuration Space and it appears to show that this is a regular device with a couple of custom registers at pffsets
0x40and0x41.Why do we want to pretend it is a bridge?
It's the host bridge and the device class is
PCI_CLASS_BRIDGE_HOST.
Yes. But the *header* type is 0 (NORMAL) while the code in pci_init_mask_bridge which is the only user of the is_bridge register initializes a type 1 (BRIDGE) header.
So it just happens to do a vaguely correct thing.
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
and there it says that the device is
found in the configuration space.
Quoted 8 lines
Quoted 6 lines
Quoted 1 line
The secondary bridges are Simbas and should be called APBs.
As far as I can see from the code, it has header type NORMAL but sets
is_bridge.
This was done by this commit:776e1bbb6cf4fe66a93c1a5dd814bbb650deca00IIRC otherwise some registers are not writable.
Yes but which ones? I looked at the manual and it does not list any registers. Playing with code, it looks like we just need to make *some*
BAR writeable. I tried with pci_set_long(d->wmask + PCI_BASE_ADDRESS_0, 0xfffffff0); topci_set_long(d->wmask + PCI_BASE_ADDRESS_5, 0xfffffff0);
and any one of these makes bios get at least to the prompt.
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
--
MST
Quoted 144 lines · Michael S. Tsirkin
Quoted 124 lines · Blue Swirl
Quoted 123 lines · Michael S. Tsirkin
Quoted 122 lines · Blue Swirl
Quoted 120 lines · Michael S. Tsirkin
Quoted 108 lines · Blue Swirl
Quoted 107 lines · Michael S. Tsirkin
Quoted 85 lines · Blue Swirl
Quoted 84 lines · Michael S. Tsirkin
Quoted 20 lines · Blue Swirl
Quoted 14 lines · Michael S. Tsirkin
commit
5caef97a16010f818ea8b950e2ee24ba876643adintroduced
a regression: we do not make IO base/limit upper 16
bit registers writeable, so we should report a 16 bit
IO range type, not a 32 bit one.
Note thatPCI_PREF_RANGE_TYPE_32is0x0, butPCI_IO_RANGE_TYPE_32is0x1.In particular, this broke sparc64.
Note: this just reverts to behaviour prior to the patch. Making
PCI_IO_BASE_UPPER16andPCI_IO_LIMIT_UPPER16registers writeable should, and seems to, work just as well, but as no system seems to actually be interested in 32 bit IO, let's not make unnecessary changes.Quoted 4 lines
Reported-by Mark Cave-Ayland <[email protected]>Signed-off-by Michael S. Tsirkin <[email protected]>Mark, can you confirm that this fixes the bug for you?
Quoted 7 lines
No, running
qemu-system-sparc64 -serial stdio
still shows black screen and the following on console:
OpenBIOS for Sparc64
Unhandled Exception0x0000000000000032
PC =0x00000000ffd19e18NPC =0x00000000ffd19e1cStopping executionThe weird thing is the range type does not seem to be accessed at all. So I guessed there's some memory corruption here. Running valgrind shows this:
--11114-- WARNING: unhandled syscall: 340
--11114-- You may be able to write your own handler. --11114-- Read the fileREADME_MISSING_SYSCALL_OR_IOCTL. --11114-- Nevertheless we consider this a bug. Please report --11114-- it at http://valgrind.org/support/bug_reports.html.
==11114== Invalid read of size 4
==11114== at0x2A68C0:pci_apb_init(apb_pci.c:350) ==11114== by0x2F7A84:sun4uv_init(sun4u.c:779) ==11114== by0x13D716: main (vl.c:3397)
==11114== Address0x156c7d30is 0 bytes after a block of size 64 alloc'd
==11114== at0x557DD69: malloc (vg_replace_malloc.c:236) ==11114== by0x225F56:malloc_and_trace(vl.c:2156) ==11114== by0x584AFEC: ??? (in/lib/libglib-2.0.so.0.2800.8) ==11114== by0x584B528:g_malloc0(in/lib/libglib-2.0.so.0.2800.8) ==11114== by0x19C50C:qemu_allocate_irqs(irq.c:47) ==11114== by0x2F7A4C:sun4uv_init(sun4u.c:778) ==11114== by0x13D716: main (vl.c:3397)
==11114==
apb: here
==11114== Warning: client switching stacks? SP change:0xfec42cbc-->0x16894008
==11114== to suppress, use: --max-stackframe=398791500 or greater
==11114== Warning: client switching stacks? SP change:0x16893fa0-->0xfec42cc0
==11114== to suppress, use: --max-stackframe=398791392 or greater
==11114== Warning: client switching stacks? SP change:0xfec42fe0-->0x16893fd0
==11114== to suppress, use: --max-stackframe=398790640 or greater
==11114== further instances of this message will not be shown. QEMU 1.0.50 monitor - type 'help' for more information (qemu) ==11114== Thread 2:
==11114== Conditional jump or move depends on uninitialised value(s) ==11114== at0x2A8351:compute_all_sub(cc_helper.c:37) ==11114== by0x2A8782:helper_compute_psr(cc_helper.c:470) ==11114== by0x9AD9A19: ???
==11114==
==11114== Conditional jump or move depends on uninitialised value(s) ==11114== at0x2A827C:compute_all_sub_xcc(cc_helper.c:60) ==11114== by0x2A8795:helper_compute_psr(cc_helper.c:473) ==11114== by0x9AD9A19: ???
==11114==
==11114== Conditional jump or move depends on uninitialised value(s) ==11114== at0x2A8296:compute_all_sub_xcc(cc_helper.c:295) ==11114== by0x2A8795:helper_compute_psr(cc_helper.c:473) ==11114== by0x9AD9A19: ???
==11114==Quoted 3 lines
Quoted 1 line
Is the above a problem?
It looks like Sparc does not reset registers at CPU reset. Nice catch.
Invalid read and address after block are also worrying.
irqs are allocated with
#defineMAX_PILS16irq =
qemu_allocate_irqs(cpu_set_irq, env, MAX_PILS);then passed to apb:
pci_bus =
pci_apb_init(APB_SPECIAL_BASE, APB_MEM_BASE, irq, &pci_bus2, &pci_bus3);which does:
PCIBus *pci_apb_init(target_phys_addr_tspecial_base,target_phys_addr_tmem_base,qemu_irq*pic, PCIBus **bus2, PCIBus **bus3)Quoted 7 lines
Quoted 5 lines
and
for (i = 0; i < 32; i++) {
sysbus_connect_irq(s, i, pic[i]);
}Awful. But using 32 for
MAX_PILSdoes not help either.Could you please clarify what is the SABRE device? Is it, in fact, a bridge device? Or not?
Quoted 8 lines
Quoted 5 lines
Quoted 2 lines
Yes, it's the host bridge, also known as PBM. It's documented in UltraSPARC IIi User's Manual
Btw would be nice to host the manuals at qemu.org our code points at sun.com URLs :(
I have most if not all manuals, downloaded from sun.com, but I'm not sure if they can be redistributed.
Okay ...
Let's change the link to point to some other place which has them?Quoted 7 lines
Quoted 6 lines
I am looking at 19.3.1 PCI Configuration Space and it appears to show that this is a regular device with a couple of custom registers at pffsets
0x40and0x41.Why do we want to pretend it is a bridge?
Quoted 8 lines
Quoted 1 line
It's the host bridge and the device class is
PCI_CLASS_BRIDGE_HOST.Yes. But the *header* type is 0 (NORMAL) while the code in
pci_init_mask_bridgewhich is the only user of theis_bridgeregister initializes a type 1 (BRIDGE) header.So it just happens to do a vaguely correct thing.
Well, that is still according to device spec.
Quoted 21 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
and there it says that the device is
found in the configuration space.Quoted 8 lines
Quoted 6 lines
Quoted 1 line
The secondary bridges are Simbas and should be called APBs.
As far as I can see from the code, it has header type NORMAL but sets
is_bridge.
This was done by this commit:776e1bbb6cf4fe66a93c1a5dd814bbb650deca00IIRC otherwise some registers are not writable.
Yes but which ones? I looked at the manual and it does not list any registers. Playing with code, it looks like we just need to make *some*
BAR writeable. I tried withpci_set_long(d->wmask + PCI_BASE_ADDRESS_0, 0xfffffff0); topci_set_long(d->wmask + PCI_BASE_ADDRESS_5, 0xfffffff0);
Quoted 2 lines
and any one of these makes bios get at least to the prompt.
I now know the root cause of the problem. OpenBIOS programs the BARs somewhat correctly just by accident. The initial io_base and mem_base for BARs are not correct, but because the host bridge BARs (and also 6 of which 4 are not even BARs!) are programmed first, the bases happened to settle to values that happen to work. The commit revealed the problem since the settling didn't happen. The mask changes just let the host bridge setup continue to do the magic.
By just changing OpenBIOS (see attached patch), I can get the devices to work (assuming that VGA is a separate problem). There's no need to change QEMU.
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
--
MST
From 3f957e2dc8477f00f6d3a9491d81399ee750c725 Mon Sep 17 00:00:00 2001
Message-Id: <3f957e2dc8477f00f6d3a9491d81399ee750c725.1330890410.git.blauwirbel@gmail.com>
From: Blue Swirl <[email protected]>
Date: Sun, 4 Mar 2012 19:46:38 +0000
Subject: [PATCH] pci: fix BAR setup
A change in QEMU on how PCI bridges are setup revealed a bug in OpenBIOS PCI setup. On Sparc64, the BARs just happened to get somewhat correct values by accident before the commit but not after the change.
Avoid to set up BARs for host bridge. Fix bridge check, this lead to setting up 6 BARs instead of more correct 2. If a bridge doesn't have any devices behind it, disable it entirely. Fix Sparc64 PCI memory base.
--- arch/sparc64/openbios.c | 2 +- drivers/pci.c | 67 ++++++++++++++++++++++++++++++++++------------ drivers/pci.h | 7 +++++ 3 files changed, 57 insertions(+), 19 deletions(-)
arch/sparc64/openbios.c +1 -1
@@ -64,7 +64,7 @@ static const struct hwdef hwdefs[] = { .cfg_base = APB_SPECIAL_BASE, .cfg_len = 0x2000000, .host_mem_base = APB_MEM_BASE, - .pci_mem_base = 0, + .pci_mem_base = 0x10000000, .mem_len = 0x10000000, .io_base = APB_SPECIAL_BASE + 0x2000000ULL, // PCI Bus I/O space .io_len = 0x10000,
drivers/pci.c +49 -18
144 lines not on this page · raw message
drivers/pci.h +7 -0
@@ -7,6 +7,8 @@#define PCI_COMMAND 0x04#define PCI_COMMAND_IO 0x01#define PCI_COMMAND_MEMORY 0x02 +#define PCI_COMMAND_MASTER 0x4/* Enable bus mastering */ +#define PCI_COMMAND_VGA_PALETTE 0x20/* Enable palette snooping */ #define PCI_STATUS 0x06/* 16 bits */ #define PCI_STATUS_CAP_LIST 0x10/* Support Capability List */
@@ -44,6 +46,11 @@#define PCI_BASE_ADDR_4 0x20#define PCI_BASE_ADDR_5 0x24 +#define PCI_IO_BASE 0x1c/* I/O range behind the bridge */ +#define PCI_IO_LIMIT 0x1d +#define PCI_MEMORY_BASE 0x20/* Memory range behind */ +#define PCI_MEMORY_LIMIT 0x22 +#define PCI_SUBSYSTEM_VENDOR_ID 0x2c#define PCI_SUBSYSTEM_ID 0x2e
Signature · 1 line
1.7.2.5
Quoted 147 lines · Blue Swirl
Quoted 146 lines · Michael S. Tsirkin
Quoted 124 lines · Blue Swirl
Quoted 123 lines · Michael S. Tsirkin
Quoted 122 lines · Blue Swirl
Quoted 120 lines · Michael S. Tsirkin
Quoted 108 lines · Blue Swirl
Quoted 107 lines · Michael S. Tsirkin
Quoted 85 lines · Blue Swirl
Quoted 84 lines · Michael S. Tsirkin
Quoted 20 lines · Blue Swirl
Quoted 14 lines · Michael S. Tsirkin
commit
5caef97a16010f818ea8b950e2ee24ba876643adintroduced
a regression: we do not make IO base/limit upper 16
bit registers writeable, so we should report a 16 bit
IO range type, not a 32 bit one.
Note thatPCI_PREF_RANGE_TYPE_32is0x0, butPCI_IO_RANGE_TYPE_32is0x1.In particular, this broke sparc64.
Note: this just reverts to behaviour prior to the patch. Making
PCI_IO_BASE_UPPER16andPCI_IO_LIMIT_UPPER16registers writeable should, and seems to, work just as well, but as no system seems to actually be interested in 32 bit IO, let's not make unnecessary changes.Quoted 4 lines
Reported-by Mark Cave-Ayland <[email protected]>Signed-off-by Michael S. Tsirkin <[email protected]>Mark, can you confirm that this fixes the bug for you?
Quoted 7 lines
No, running
qemu-system-sparc64 -serial stdio
still shows black screen and the following on console:
OpenBIOS for Sparc64
Unhandled Exception0x0000000000000032
PC =0x00000000ffd19e18NPC =0x00000000ffd19e1cStopping executionThe weird thing is the range type does not seem to be accessed at all. So I guessed there's some memory corruption here. Running valgrind shows this:
--11114-- WARNING: unhandled syscall: 340
--11114-- You may be able to write your own handler. --11114-- Read the fileREADME_MISSING_SYSCALL_OR_IOCTL. --11114-- Nevertheless we consider this a bug. Please report --11114-- it at http://valgrind.org/support/bug_reports.html.
==11114== Invalid read of size 4
==11114== at0x2A68C0:pci_apb_init(apb_pci.c:350) ==11114== by0x2F7A84:sun4uv_init(sun4u.c:779) ==11114== by0x13D716: main (vl.c:3397)
==11114== Address0x156c7d30is 0 bytes after a block of size 64 alloc'd
==11114== at0x557DD69: malloc (vg_replace_malloc.c:236) ==11114== by0x225F56:malloc_and_trace(vl.c:2156) ==11114== by0x584AFEC: ??? (in/lib/libglib-2.0.so.0.2800.8) ==11114== by0x584B528:g_malloc0(in/lib/libglib-2.0.so.0.2800.8) ==11114== by0x19C50C:qemu_allocate_irqs(irq.c:47) ==11114== by0x2F7A4C:sun4uv_init(sun4u.c:778) ==11114== by0x13D716: main (vl.c:3397)
==11114==
apb: here
==11114== Warning: client switching stacks? SP change:0xfec42cbc-->0x16894008
==11114== to suppress, use: --max-stackframe=398791500 or greater
==11114== Warning: client switching stacks? SP change:0x16893fa0-->0xfec42cc0
==11114== to suppress, use: --max-stackframe=398791392 or greater
==11114== Warning: client switching stacks? SP change:0xfec42fe0-->0x16893fd0
==11114== to suppress, use: --max-stackframe=398790640 or greater
==11114== further instances of this message will not be shown. QEMU 1.0.50 monitor - type 'help' for more information (qemu) ==11114== Thread 2:
==11114== Conditional jump or move depends on uninitialised value(s) ==11114== at0x2A8351:compute_all_sub(cc_helper.c:37) ==11114== by0x2A8782:helper_compute_psr(cc_helper.c:470) ==11114== by0x9AD9A19: ???
==11114==
==11114== Conditional jump or move depends on uninitialised value(s) ==11114== at0x2A827C:compute_all_sub_xcc(cc_helper.c:60) ==11114== by0x2A8795:helper_compute_psr(cc_helper.c:473) ==11114== by0x9AD9A19: ???
==11114==
==11114== Conditional jump or move depends on uninitialised value(s) ==11114== at0x2A8296:compute_all_sub_xcc(cc_helper.c:295) ==11114== by0x2A8795:helper_compute_psr(cc_helper.c:473) ==11114== by0x9AD9A19: ???
==11114==Quoted 3 lines
Quoted 1 line
Is the above a problem?
It looks like Sparc does not reset registers at CPU reset. Nice catch.
Invalid read and address after block are also worrying.
irqs are allocated with
#defineMAX_PILS16irq =
qemu_allocate_irqs(cpu_set_irq, env, MAX_PILS);then passed to apb:
pci_bus =
pci_apb_init(APB_SPECIAL_BASE, APB_MEM_BASE, irq, &pci_bus2, &pci_bus3);which does:
PCIBus *pci_apb_init(target_phys_addr_tspecial_base,target_phys_addr_tmem_base,qemu_irq*pic, PCIBus **bus2, PCIBus **bus3)Quoted 7 lines
Quoted 5 lines
and
for (i = 0; i < 32; i++) {
sysbus_connect_irq(s, i, pic[i]);
}Awful. But using 32 for
MAX_PILSdoes not help either.Could you please clarify what is the SABRE device? Is it, in fact, a bridge device? Or not?
Quoted 8 lines
Quoted 5 lines
Quoted 2 lines
Yes, it's the host bridge, also known as PBM. It's documented in UltraSPARC IIi User's Manual
Btw would be nice to host the manuals at qemu.org our code points at sun.com URLs :(
I have most if not all manuals, downloaded from sun.com, but I'm not sure if they can be redistributed.
Okay ...
Let's change the link to point to some other place which has them?Quoted 8 lines
Quoted 6 lines
I am looking at 19.3.1 PCI Configuration Space and it appears to show that this is a regular device with a couple of custom registers at pffsets
0x40and0x41.Why do we want to pretend it is a bridge?
It's the host bridge and the device class is
PCI_CLASS_BRIDGE_HOST.
Quoted 8 lines
Quoted 6 lines
Yes. But the *header* type is 0 (NORMAL) while the code in
pci_init_mask_bridgewhich is the only user of theis_bridgeregister initializes a type 1 (BRIDGE) header.So it just happens to do a vaguely correct thing.
Well, that is still according to device spec.
I tried to find anything in the spec that says any register after 0x10 is implemented but failed.
Can you tell me which chater and what it says?
Quoted 262 lines
Quoted 21 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
and there it says that the device is
found in the configuration space.Quoted 8 lines
Quoted 6 lines
Quoted 1 line
The secondary bridges are Simbas and should be called APBs.
As far as I can see from the code, it has header type NORMAL but sets
is_bridge.
This was done by this commit:776e1bbb6cf4fe66a93c1a5dd814bbb650deca00IIRC otherwise some registers are not writable.
Yes but which ones? I looked at the manual and it does not list any registers. Playing with code, it looks like we just need to make *some*
BAR writeable. I tried withpci_set_long(d->wmask + PCI_BASE_ADDRESS_0, 0xfffffff0); topci_set_long(d->wmask + PCI_BASE_ADDRESS_5, 0xfffffff0);Quoted 2 lines
and any one of these makes bios get at least to the prompt.
I now know the root cause of the problem. OpenBIOS programs the BARs somewhat correctly just by accident. The initial
io_baseandmem_basefor BARs are not correct, but because the host bridge BARs (and also 6 of which 4 are not even BARs!) are programmed first, the bases happened to settle to values that happen to work. The commit revealed the problem since the settling didn't happen. The mask changes just let the host bridge setup continue to do the magic.By just changing OpenBIOS (see attached patch), I can get the devices to work (assuming that VGA is a separate problem). There's no need to change QEMU.
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
--
MSTFrom
3f957e2dc8477f00f6d3a9491d81399ee750c725Mon Sep 17 00:00:00 2001
Message-Id: <3f957e2dc8477f00f6d3a9491d81399ee750c725.1330890410.git.blauwirbel@gmail.com>
From: Blue Swirl <[email protected]>
Date: Sun, 4 Mar 2012 19:46:38 +0000
Subject: [PATCH] pci: fix BAR setupA change in QEMU on how PCI bridges are setup revealed a bug in OpenBIOS PCI setup. On Sparc64, the BARs just happened to get somewhat correct values by accident before the commit but not after the change.
Avoid to set up BARs for host bridge. Fix bridge check, this lead to setting up 6 BARs instead of more correct 2. If a bridge doesn't have any devices behind it, disable it entirely. Fix Sparc64 PCI memory base.
Signed-off-by Blue Swirl <[email protected]>--- arch/sparc64/openbios.c | 2 +- drivers/pci.c | 67 ++++++++++++++++++++++++++++++++++------------ drivers/pci.h | 7 +++++ 3 files changed, 57 insertions(+), 19 deletions(-)arch/sparc64/openbios.c +1
-1@@ -64,7 +64,7 @@ static const struct hwdef hwdefs[] = { .cfg_base = APB_SPECIAL_BASE, .cfg_len = 0x2000000, .host_mem_base = APB_MEM_BASE, - .pci_mem_base = 0, + .pci_mem_base = 0x10000000, .mem_len = 0x10000000, .io_base = APB_SPECIAL_BASE + 0x2000000ULL, // PCI Bus I/O space .io_len = 0x10000,drivers/pci.c +49
-18@@ -966,11 +966,18 @@ static void ob_pci_configure_bar(pci_addr addr, pci_config_t *config, size = min_align; reloc = (reloc + size -1 ) & ~(size -1 );if (*io_base == base) { +PCI_DPRINTF ("changing io_base from 0x%lx to 0x%x\n" , + *io_base, reloc + size); *io_base = reloc + size; reloc -= arch->io_base; }else { +PCI_DPRINTF ("changing mem_base from 0x%lx to 0x%x\n" , + *mem_base, reloc + size); *mem_base = reloc + size; } +PCI_DPRINTF ("Configuring BARs for %s: reloc 0x%x omask 0x%x " +"io_base 0x%lx mem_base 0x%lx\n" , + config->path, reloc, *p_omask, *io_base, *mem_base);pci_config_write32 (addr, config_addr, reloc | *p_omask); config->assigned[reg] = reloc | *p_omask; }@@ -1021,26 +1028,30 @@ ob_pci_configure(pci_addr addr, pci_config_t *config, int num_regs, int rom_bar,pci_config_write16 (addr,PCI_COMMAND , cmd); } -static void ob_configure_pci_device (const char * parent_path, -int *bus_num,unsigned long *mem_base,unsigned long *io_base, -int bus,int devnum,int fn,int *p_is_multi); +static int ob_configure_pci_device (const char * parent_path, +int *bus_num,unsigned long *mem_base, +unsigned long *io_base,int bus,int devnum, +int fn,int *p_is_multi); -static void ob_scan_pci_bus (int *bus_num,unsigned long *mem_base, -unsigned long *io_base,const char *path, -int bus) +static int ob_scan_pci_bus (int *bus_num,unsigned long *mem_base, +unsigned long *io_base,const char *path, +int bus) { -int devnum, fn, is_multi; +int devnum, fn, is_multi, ndevices =0 ;PCI_DPRINTF ("\nScanning bus %d at %s...\n" , bus, path);for (devnum =0 ; devnum <32 ; devnum++) { is_multi =0 ;for (fn =0 ; fn==0 || (is_multi && fn<8 ); fn++) { -ob_configure_pci_device (path, bus_num, mem_base, io_base, - bus, devnum, fn, &is_multi); + ndevices +=ob_configure_pci_device (path, bus_num, + mem_base, io_base, + bus, devnum, fn, + &is_multi); } } +return ndevices; } static void ob_configure_pci_bridge(pci_addr addr,@@ -1048,6 +1059,9 @@ static void ob_configure_pci_bridge(pci_addr addr,unsigned long *io_base, int primary_bus, pci_config_t *config) { + int ndevices; +uint8_t command; + config->primary_bus = primary_bus;pci_config_write8 (addr,PCI_PRIMARY_BUS , config->primary_bus);@@ -1062,16 +1076,30 @@ static void ob_configure_pci_bridge(pci_addr addr,/* make pci bridge parent device, prepare for recursion */ -ob_scan_pci_bus (bus_num, mem_base, io_base, - config->path, config->secondary_bus); + ndevices =ob_scan_pci_bus (bus_num, mem_base, io_base, + config->path, config->secondary_bus); +if (!ndevices) { +/* no devices, disable bridging */ +PCI_DPRINTF ("disabling bridge %s\n" , config->path); + command =pci_config_read8 (addr,PCI_COMMAND ); + command &= ~(PCI_COMMAND_IO |PCI_COMMAND_MEMORY | +PCI_COMMAND_VGA_PALETTE |PCI_COMMAND_MASTER ); +pci_config_write8 (addr,PCI_COMMAND , command); +pci_config_write8 (addr,PCI_IO_BASE ,0 ); +pci_config_write8 (addr,PCI_IO_LIMIT ,0 ); +pci_config_write8 (addr,PCI_MEMORY_BASE ,0 ); +pci_config_write8 (addr,PCI_MEMORY_LIMIT ,0 ); +return ; + }/* bus scan updates *bus_num to last revealed pci bus number */ config->subordinate_bus = *bus_num;pci_config_write8 (addr,PCI_SUBORDINATE_BUS , config->subordinate_bus); -PCI_DPRINTF ("bridge %s PCI bus primary=%d secondary=%d subordinate=%d\n" , - config->path, config->primary_bus, config->secondary_bus, - config->subordinate_bus); +PCI_DPRINTF ("bridge %s PCI bus primary=%d secondary=%d subordinate=%d" +" ndev=%d\n" , + config->path, config->primary_bus, config->secondary_bus, + config->subordinate_bus, ndevices);pci_set_bus_range (config); }@@ -1117,7 +1145,7 @@ static int ob_pci_read_identification(int bus, int devnum, int fn,return 1 ; } -static void ob_configure_pci_device (const char * parent_path, +static int ob_configure_pci_device (const char * parent_path,int *bus_num,unsigned long *mem_base,unsigned long *io_base,int bus,int devnum,int fn,int *p_is_multi) {@@ -1133,7 +1161,7 @@ static void ob_configure_pci_device(const char* parent_path,int is_host_bridge =0 ;if (!ob_pci_read_identification (bus, devnum, fn, &vid, &did, &class, &subclass)) { -return ; +return 0 ; } addr =PCI_ADDR (bus, devnum, fn);@@ -1195,16 +1223,18 @@ static void ob_configure_pci_device(const char* parent_path,if (get_property (phandle,"vendor-id" ,NULL )) {PCI_DPRINTF ("host bridge already configured\n" ); -return ; +return 0 ; } }activate_dev (phandle); -if (htype &PCI_HEADER_TYPE_BRIDGE ) { +if (htype &PCI_HEADER_TYPE_BRIDGE || (class ==PCI_BASE_CLASS_BRIDGE )) { +PCI_DPRINTF ("Bridge 2 bars, htype %x\n" , htype); num_bars =2 ; rom_bar =PCI_ROM_ADDRESS1 ; }else { +PCI_DPRINTF ("Device 6 bars, htype %x\n" , htype); num_bars =6 ; rom_bar =PCI_ROM_ADDRESS ; }@@ -1240,6 +1270,7 @@ static void ob_configure_pci_device(const char* parent_path,ob_configure_pci_bridge (addr, bus_num, mem_base, io_base, bus, &config); } +return 1 ; }int ob_pci_init (void )drivers/pci.h +7
-0@@ -7,6 +7,8 @@#define PCI_COMMAND 0x04#define PCI_COMMAND_IO 0x01#define PCI_COMMAND_MEMORY 0x02 +#define PCI_COMMAND_MASTER 0x4/* Enable bus mastering */ +#define PCI_COMMAND_VGA_PALETTE 0x20/* Enable palette snooping */ #define PCI_STATUS 0x06/* 16 bits */ #define PCI_STATUS_CAP_LIST 0x10/* Support Capability List */ @@ -44,6 +46,11 @@#define PCI_BASE_ADDR_4 0x20#define PCI_BASE_ADDR_5 0x24 +#define PCI_IO_BASE 0x1c/* I/O range behind the bridge */ +#define PCI_IO_LIMIT 0x1d +#define PCI_MEMORY_BASE 0x20/* Memory range behind */ +#define PCI_MEMORY_LIMIT 0x22 +#define PCI_SUBSYSTEM_VENDOR_ID 0x2c#define PCI_SUBSYSTEM_ID 0x2eSignature · 1 line
1.7.2.5
Quoted 153 lines · Michael S. Tsirkin
Quoted 152 lines · Blue Swirl
Quoted 151 lines · Michael S. Tsirkin
Quoted 124 lines · Blue Swirl
Quoted 123 lines · Michael S. Tsirkin
Quoted 122 lines · Blue Swirl
Quoted 120 lines · Michael S. Tsirkin
Quoted 108 lines · Blue Swirl
Quoted 107 lines · Michael S. Tsirkin
Quoted 85 lines · Blue Swirl
Quoted 84 lines · Michael S. Tsirkin
Quoted 20 lines · Blue Swirl
Quoted 18 lines · Michael S. Tsirkin
commit 5caef97a16010f818ea8b950e2ee24ba876643ad introduced
a regression: we do not make IO base/limit upper 16
bit registers writeable, so we should report a 16 bit
IO range type, not a 32 bit one.
Note that PCI_PREF_RANGE_TYPE_32 is 0x0, but PCI_IO_RANGE_TYPE_32 is 0x1.In particular, this broke sparc64.
Note: this just reverts to behaviour prior to the patch.
Making PCI_IO_BASE_UPPER16 and PCI_IO_LIMIT_UPPER16
registers writeable should, and seems to, work just as well, but
as no system seems to actually be interested in 32 bit IO,
let's not make unnecessary changes.Reported-by: Mark Cave-Ayland <[email protected]>
Signed-off-by: Michael S. Tsirkin <[email protected]>Mark, can you confirm that this fixes the bug for you?
Quoted 7 lines
No, running
qemu-system-sparc64 -serial stdio
still shows black screen and the following on console:
OpenBIOS for Sparc64
Unhandled Exception0x0000000000000032
PC =0x00000000ffd19e18NPC =0x00000000ffd19e1cStopping executionThe weird thing is the range type does not seem to be accessed at all. So I guessed there's some memory corruption here. Running valgrind shows this:
--11114-- WARNING: unhandled syscall: 340
--11114-- You may be able to write your own handler. --11114-- Read the fileREADME_MISSING_SYSCALL_OR_IOCTL. --11114-- Nevertheless we consider this a bug. Please report --11114-- it at http://valgrind.org/support/bug_reports.html.
==11114== Invalid read of size 4
==11114== at0x2A68C0:pci_apb_init(apb_pci.c:350) ==11114== by0x2F7A84:sun4uv_init(sun4u.c:779) ==11114== by0x13D716: main (vl.c:3397)
==11114== Address0x156c7d30is 0 bytes after a block of size 64 alloc'd
==11114== at0x557DD69: malloc (vg_replace_malloc.c:236) ==11114== by0x225F56:malloc_and_trace(vl.c:2156) ==11114== by0x584AFEC: ??? (in/lib/libglib-2.0.so.0.2800.8) ==11114== by0x584B528:g_malloc0(in/lib/libglib-2.0.so.0.2800.8) ==11114== by0x19C50C:qemu_allocate_irqs(irq.c:47) ==11114== by0x2F7A4C:sun4uv_init(sun4u.c:778) ==11114== by0x13D716: main (vl.c:3397)
==11114==
apb: here
==11114== Warning: client switching stacks? SP change:0xfec42cbc-->0x16894008
==11114== to suppress, use: --max-stackframe=398791500 or greater
==11114== Warning: client switching stacks? SP change:0x16893fa0-->0xfec42cc0
==11114== to suppress, use: --max-stackframe=398791392 or greater
==11114== Warning: client switching stacks? SP change:0xfec42fe0-->0x16893fd0
==11114== to suppress, use: --max-stackframe=398790640 or greater
==11114== further instances of this message will not be shown. QEMU 1.0.50 monitor - type 'help' for more information (qemu) ==11114== Thread 2:
==11114== Conditional jump or move depends on uninitialised value(s) ==11114== at0x2A8351:compute_all_sub(cc_helper.c:37) ==11114== by0x2A8782:helper_compute_psr(cc_helper.c:470) ==11114== by0x9AD9A19: ???
==11114==
==11114== Conditional jump or move depends on uninitialised value(s) ==11114== at0x2A827C:compute_all_sub_xcc(cc_helper.c:60) ==11114== by0x2A8795:helper_compute_psr(cc_helper.c:473) ==11114== by0x9AD9A19: ???
==11114==
==11114== Conditional jump or move depends on uninitialised value(s) ==11114== at0x2A8296:compute_all_sub_xcc(cc_helper.c:295) ==11114== by0x2A8795:helper_compute_psr(cc_helper.c:473) ==11114== by0x9AD9A19: ???
==11114==Quoted 3 lines
Quoted 1 line
Is the above a problem?
It looks like Sparc does not reset registers at CPU reset. Nice catch.
Invalid read and address after block are also worrying.
irqs are allocated with
#defineMAX_PILS16irq =
qemu_allocate_irqs(cpu_set_irq, env, MAX_PILS);then passed to apb:
pci_bus =
pci_apb_init(APB_SPECIAL_BASE, APB_MEM_BASE, irq, &pci_bus2, &pci_bus3);which does:
PCIBus *pci_apb_init(target_phys_addr_tspecial_base,target_phys_addr_tmem_base,qemu_irq*pic, PCIBus **bus2, PCIBus **bus3)Quoted 7 lines
Quoted 5 lines
and
for (i = 0; i < 32; i++) {
sysbus_connect_irq(s, i, pic[i]);
}Awful. But using 32 for
MAX_PILSdoes not help either.Could you please clarify what is the SABRE device? Is it, in fact, a bridge device? Or not?
Quoted 8 lines
Quoted 5 lines
Quoted 2 lines
Yes, it's the host bridge, also known as PBM. It's documented in UltraSPARC IIi User's Manual
Btw would be nice to host the manuals at qemu.org our code points at sun.com URLs :(
I have most if not all manuals, downloaded from sun.com, but I'm not sure if they can be redistributed.
Okay ...
Let's change the link to point to some other place which has them?Quoted 8 lines
Quoted 6 lines
I am looking at 19.3.1 PCI Configuration Space and it appears to show that this is a regular device with a couple of custom registers at pffsets
0x40and0x41.Why do we want to pretend it is a bridge?
It's the host bridge and the device class is
PCI_CLASS_BRIDGE_HOST.Yes. But the *header* type is 0 (NORMAL) while the code in
pci_init_mask_bridgewhich is the only user of theis_bridgeregister initializes a type 1 (BRIDGE) header.
Quoted 7 lines
Quoted 3 lines
Quoted 1 line
So it just happens to do a vaguely correct thing.
Well, that is still according to device spec.
I tried to find anything in the spec that says any register after
0x10is implemented but failed.
Can you tell me which chater and what it says?
19.3.1.10 tells that the header type is 0, as you noted too. Still, the register layout matches bridge spec instead, for example there are bus number registers in place of BAR 2. This conflicts with bridge spec 3.2.4.9. Maybe the device predates the specification.
Quoted 263 lines
Quoted 262 lines
Quoted 21 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
and there it says that the device is
found in the configuration space.Quoted 8 lines
Quoted 6 lines
Quoted 1 line
The secondary bridges are Simbas and should be called APBs.
As far as I can see from the code, it has header type NORMAL but sets
is_bridge.
This was done by this commit:776e1bbb6cf4fe66a93c1a5dd814bbb650deca00IIRC otherwise some registers are not writable.
Yes but which ones? I looked at the manual and it does not list any registers. Playing with code, it looks like we just need to make *some*
BAR writeable. I tried withpci_set_long(d->wmask + PCI_BASE_ADDRESS_0, 0xfffffff0); topci_set_long(d->wmask + PCI_BASE_ADDRESS_5, 0xfffffff0);Quoted 2 lines
and any one of these makes bios get at least to the prompt.
I now know the root cause of the problem. OpenBIOS programs the BARs somewhat correctly just by accident. The initial
io_baseandmem_basefor BARs are not correct, but because the host bridge BARs (and also 6 of which 4 are not even BARs!) are programmed first, the bases happened to settle to values that happen to work. The commit revealed the problem since the settling didn't happen. The mask changes just let the host bridge setup continue to do the magic.By just changing OpenBIOS (see attached patch), I can get the devices to work (assuming that VGA is a separate problem). There's no need to change QEMU.
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
--
MSTFrom
3f957e2dc8477f00f6d3a9491d81399ee750c725Mon Sep 17 00:00:00 2001
Message-Id: <3f957e2dc8477f00f6d3a9491d81399ee750c725.1330890410.git.blauwirbel@gmail.com>
From: Blue Swirl <[email protected]>
Date: Sun, 4 Mar 2012 19:46:38 +0000
Subject: [PATCH] pci: fix BAR setupA change in QEMU on how PCI bridges are setup revealed a bug in OpenBIOS PCI setup. On Sparc64, the BARs just happened to get somewhat correct values by accident before the commit but not after the change.
Avoid to set up BARs for host bridge. Fix bridge check, this lead to setting up 6 BARs instead of more correct 2. If a bridge doesn't have any devices behind it, disable it entirely. Fix Sparc64 PCI memory base.
Signed-off-by Blue Swirl <[email protected]>---
arch/sparc64/openbios.c | 2 +-
drivers/pci.c | 67 ++++++++++++++++++++++++++++++++++------------drivers/pci.h| 7 +++++3 files changed, 57 insertions(+), 19 deletions(-)arch/sparc64/openbios.c +1
-1@@ -64,7 +64,7 @@ static const struct hwdef hwdefs[] = { .cfg_base = APB_SPECIAL_BASE, .cfg_len = 0x2000000, .host_mem_base = APB_MEM_BASE, - .pci_mem_base = 0, + .pci_mem_base = 0x10000000, .mem_len = 0x10000000,.io_base =
APB_SPECIAL_BASE+0x2000000ULL, // PCI Bus I/O space .io_len =0x10000,drivers/pci.c +49
-18@@ -966,11 +966,18 @@ static void ob_pci_configure_bar(pci_addr addr, pci_config_t *config, size = min_align; reloc = (reloc + size -1) & ~(size - 1); if (*io_base == base) { + PCI_DPRINTF("changing io_base from 0x%lx to 0x%x\n", + *io_base, reloc + size); *io_base = reloc + size; reloc -= arch->io_base; } else { + PCI_DPRINTF("changing mem_base from 0x%lx to 0x%x\n", + *mem_base, reloc + size); *mem_base = reloc + size; } + PCI_DPRINTF("Configuring BARs for %s: reloc 0x%x omask 0x%x " + "io_base 0x%lx mem_base 0x%lx\n", + config->path, reloc, *p_omask, *io_base, *mem_base); pci_config_write32(addr, config_addr, reloc | *p_omask); config->assigned[reg] = reloc | *p_omask; }@@ -1021,26 +1028,30 @@ ob_pci_configure(pci_addr addr, pci_config_t *config, int num_regs, int rom_bar, pci_config_write16(addr, PCI_COMMAND, cmd); } -static void ob_configure_pci_device (const char * parent_path, - int *bus_num, unsigned long *mem_base, unsigned long *io_base, - int bus, int devnum, int fn, int *p_is_multi); +static int ob_configure_pci_device (const char * parent_path, + int *bus_num, unsigned long *mem_base, + unsigned long *io_base, int bus, int devnum, + int fn, int *p_is_multi); -static void ob_scan_pci_bus (int *bus_num,unsigned long *mem_base, - unsigned long *io_base, const char *path, - int bus) +static int ob_scan_pci_bus (int *bus_num,unsigned long *mem_base, + unsigned long *io_base, const char *path, + int bus) { - int devnum, fn, is_multi; + int devnum, fn, is_multi, ndevices = 0; PCI_DPRINTF("\nScanning bus %d at %s...\n", bus, path); for (devnum = 0; devnum < 32; devnum++) { is_multi = 0; for (fn = 0; fn==0 || (is_multi && fn<8); fn++) { - ob_configure_pci_device(path, bus_num, mem_base, io_base, - bus, devnum, fn, &is_multi); + ndevices += ob_configure_pci_device(path, bus_num, + mem_base, io_base, + bus, devnum, fn, + &is_multi); } } + return ndevices; } static void ob_configure_pci_bridge(pci_addr addr,@@ -1048,6 +1059,9 @@ static void ob_configure_pci_bridge(pci_addr addr, unsigned long *io_base, int primary_bus, pci_config_t *config) { + int ndevices; + uint8_t command; + config->primary_bus = primary_bus; pci_config_write8(addr, PCI_PRIMARY_BUS, config->primary_bus);@@ -1062,16 +1076,30 @@ static void ob_configure_pci_bridge(pci_addr addr, /* make pci bridge parent device, prepare for recursion */ - ob_scan_pci_bus(bus_num, mem_base, io_base, - config->path, config->secondary_bus); + ndevices = ob_scan_pci_bus(bus_num, mem_base, io_base, + config->path, config->secondary_bus); + if (!ndevices) { + /* no devices, disable bridging */ + PCI_DPRINTF("disabling bridge %s\n", config->path); + command = pci_config_read8(addr, PCI_COMMAND); + command &= ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY | + PCI_COMMAND_VGA_PALETTE | PCI_COMMAND_MASTER); + pci_config_write8(addr, PCI_COMMAND, command); + pci_config_write8(addr, PCI_IO_BASE, 0); + pci_config_write8(addr, PCI_IO_LIMIT, 0); + pci_config_write8(addr, PCI_MEMORY_BASE, 0); + pci_config_write8(addr, PCI_MEMORY_LIMIT, 0); + return; + } /* bus scan updates *bus_num to last revealed pci bus number */ config->subordinate_bus = *bus_num; pci_config_write8(addr, PCI_SUBORDINATE_BUS, config->subordinate_bus); - PCI_DPRINTF("bridge %s PCI bus primary=%d secondary=%d subordinate=%d\n", - config->path, config->primary_bus, config->secondary_bus, - config->subordinate_bus); + PCI_DPRINTF("bridge %s PCI bus primary=%d secondary=%d subordinate=%d" + " ndev=%d\n", + config->path, config->primary_bus, config->secondary_bus, + config->subordinate_bus, ndevices); pci_set_bus_range(config); }@@ -1117,7 +1145,7 @@ static int ob_pci_read_identification(int bus, int devnum, int fn, return 1; } -static void ob_configure_pci_device (const char * parent_path, +static int ob_configure_pci_device (const char * parent_path, int *bus_num, unsigned long *mem_base, unsigned long *io_base, int bus, int devnum, int fn, int *p_is_multi) {@@ -1133,7 +1161,7 @@ static void ob_configure_pci_device(const char* parent_path, int is_host_bridge = 0; if (!ob_pci_read_identification(bus, devnum, fn, &vid, &did, &class, &subclass)) { - return; + return 0; } addr = PCI_ADDR(bus, devnum, fn);@@ -1195,16 +1223,18 @@ static void ob_configure_pci_device(const char* parent_path, if (get_property(phandle, "vendor-id", NULL)) { PCI_DPRINTF("host bridge already configured\n"); - return; + return 0; } } activate_dev(phandle); - if (htype & PCI_HEADER_TYPE_BRIDGE) { + if (htype & PCI_HEADER_TYPE_BRIDGE || (class == PCI_BASE_CLASS_BRIDGE)) { + PCI_DPRINTF("Bridge 2 bars, htype %x\n", htype); num_bars = 2; rom_bar = PCI_ROM_ADDRESS1; } else { + PCI_DPRINTF("Device 6 bars, htype %x\n", htype); num_bars = 6; rom_bar = PCI_ROM_ADDRESS; }@@ -1240,6 +1270,7 @@ static void ob_configure_pci_device(const char* parent_path, ob_configure_pci_bridge(addr, bus_num, mem_base, io_base, bus, &config); } + return 1; } int ob_pci_init(void)drivers/pci.h +7
-1@@ -7,6 +7,8 @@ #define PCI_COMMAND 0x04 #define PCI_COMMAND_IO 0x01 #define PCI_COMMAND_MEMORY 0x02 +#define PCI_COMMAND_MASTER 0x4 /* Enable bus mastering */ +#define PCI_COMMAND_VGA_PALETTE 0x20 /* Enable palette snooping */ #define PCI_STATUS 0x06 /* 16 bits */ #define PCI_STATUS_CAP_LIST 0x10 /* Support Capability List */@@ -44,6 +46,11 @@ #define PCI_BASE_ADDR_4 0x20 #define PCI_BASE_ADDR_5 0x24 +#define PCI_IO_BASE 0x1c/* I/O range behind the bridge */ +#define PCI_IO_LIMIT 0x1d +#define PCI_MEMORY_BASE 0x20/* Memory range behind */ +#define PCI_MEMORY_LIMIT 0x22 + #define PCI_SUBSYSTEM_VENDOR_ID 0x2c #define PCI_SUBSYSTEM_ID 0x2e --1.7.2.5
Quoted 158 lines · Blue Swirl
Quoted 157 lines · Michael S. Tsirkin
Quoted 155 lines · Blue Swirl
Quoted 144 lines · Michael S. Tsirkin
Quoted 124 lines · Blue Swirl
Quoted 123 lines · Michael S. Tsirkin
Quoted 122 lines · Blue Swirl
Quoted 120 lines · Michael S. Tsirkin
Quoted 108 lines · Blue Swirl
Quoted 107 lines · Michael S. Tsirkin
Quoted 85 lines · Blue Swirl
Quoted 84 lines · Michael S. Tsirkin
Quoted 27 lines · Blue Swirl
On Sun, Mar 4, 2012 at 09:46, Michael S. Tsirkin <[email protected]> wrote:
commit 5caef97a16010f818ea8b950e2ee24ba876643ad introduced
a regression: we do not make IO base/limit upper 16
bit registers writeable, so we should report a 16 bit
IO range type, not a 32 bit one.
Note that PCI_PREF_RANGE_TYPE_32 is 0x0, but PCI_IO_RANGE_TYPE_32 is 0x1.In particular, this broke sparc64.
Note: this just reverts to behaviour prior to the patch.
Making PCI_IO_BASE_UPPER16 and PCI_IO_LIMIT_UPPER16
registers writeable should, and seems to, work just as well, but
as no system seems to actually be interested in 32 bit IO,
let's not make unnecessary changes.Reported-by: Mark Cave-Ayland <[email protected]>
Signed-off-by: Michael S. Tsirkin <[email protected]>Mark, can you confirm that this fixes the bug for you?
No, running
qemu-system-sparc64 -serial stdio
still shows black screen and the following on console:
OpenBIOS for Sparc64
Unhandled Exception 0x0000000000000032
PC = 0x00000000ffd19e18 NPC = 0x00000000ffd19e1c
Stopping executionThe weird thing is the range type does not seem to be accessed at all. So I guessed there's some memory corruption here. Running valgrind shows this:
--11114-- WARNING: unhandled syscall: 340
--11114-- You may be able to write your own handler. --11114-- Read the fileREADME_MISSING_SYSCALL_OR_IOCTL. --11114-- Nevertheless we consider this a bug. Please report --11114-- it at http://valgrind.org/support/bug_reports.html.
==11114== Invalid read of size 4
==11114== at0x2A68C0:pci_apb_init(apb_pci.c:350) ==11114== by0x2F7A84:sun4uv_init(sun4u.c:779) ==11114== by0x13D716: main (vl.c:3397)
==11114== Address0x156c7d30is 0 bytes after a block of size 64 alloc'd
==11114== at0x557DD69: malloc (vg_replace_malloc.c:236) ==11114== by0x225F56:malloc_and_trace(vl.c:2156) ==11114== by0x584AFEC: ??? (in/lib/libglib-2.0.so.0.2800.8) ==11114== by0x584B528:g_malloc0(in/lib/libglib-2.0.so.0.2800.8) ==11114== by0x19C50C:qemu_allocate_irqs(irq.c:47) ==11114== by0x2F7A4C:sun4uv_init(sun4u.c:778) ==11114== by0x13D716: main (vl.c:3397)
==11114==
apb: here
==11114== Warning: client switching stacks? SP change:0xfec42cbc-->0x16894008
==11114== to suppress, use: --max-stackframe=398791500 or greater
==11114== Warning: client switching stacks? SP change:0x16893fa0-->0xfec42cc0
==11114== to suppress, use: --max-stackframe=398791392 or greater
==11114== Warning: client switching stacks? SP change:0xfec42fe0-->0x16893fd0
==11114== to suppress, use: --max-stackframe=398790640 or greater
==11114== further instances of this message will not be shown. QEMU 1.0.50 monitor - type 'help' for more information (qemu) ==11114== Thread 2:
==11114== Conditional jump or move depends on uninitialised value(s) ==11114== at0x2A8351:compute_all_sub(cc_helper.c:37) ==11114== by0x2A8782:helper_compute_psr(cc_helper.c:470) ==11114== by0x9AD9A19: ???
==11114==
==11114== Conditional jump or move depends on uninitialised value(s) ==11114== at0x2A827C:compute_all_sub_xcc(cc_helper.c:60) ==11114== by0x2A8795:helper_compute_psr(cc_helper.c:473) ==11114== by0x9AD9A19: ???
==11114==
==11114== Conditional jump or move depends on uninitialised value(s) ==11114== at0x2A8296:compute_all_sub_xcc(cc_helper.c:295) ==11114== by0x2A8795:helper_compute_psr(cc_helper.c:473) ==11114== by0x9AD9A19: ???
==11114==Quoted 3 lines
Quoted 1 line
Is the above a problem?
It looks like Sparc does not reset registers at CPU reset. Nice catch.
Invalid read and address after block are also worrying.
irqs are allocated with
#defineMAX_PILS16irq =
qemu_allocate_irqs(cpu_set_irq, env, MAX_PILS);then passed to apb:
pci_bus =
pci_apb_init(APB_SPECIAL_BASE, APB_MEM_BASE, irq, &pci_bus2, &pci_bus3);which does:
PCIBus *pci_apb_init(target_phys_addr_tspecial_base,target_phys_addr_tmem_base,qemu_irq*pic, PCIBus **bus2, PCIBus **bus3)Quoted 7 lines
Quoted 5 lines
and
for (i = 0; i < 32; i++) {
sysbus_connect_irq(s, i, pic[i]);
}Awful. But using 32 for
MAX_PILSdoes not help either.Could you please clarify what is the SABRE device? Is it, in fact, a bridge device? Or not?
Quoted 8 lines
Quoted 5 lines
Quoted 2 lines
Yes, it's the host bridge, also known as PBM. It's documented in UltraSPARC IIi User's Manual
Btw would be nice to host the manuals at qemu.org our code points at sun.com URLs :(
I have most if not all manuals, downloaded from sun.com, but I'm not sure if they can be redistributed.
Okay ...
Let's change the link to point to some other place which has them?Quoted 7 lines
Quoted 6 lines
I am looking at 19.3.1 PCI Configuration Space and it appears to show that this is a regular device with a couple of custom registers at pffsets
0x40and0x41.Why do we want to pretend it is a bridge?
Quoted 8 lines
Quoted 1 line
It's the host bridge and the device class is
PCI_CLASS_BRIDGE_HOST.Yes. But the *header* type is 0 (NORMAL) while the code in
pci_init_mask_bridgewhich is the only user of theis_bridgeregister initializes a type 1 (BRIDGE) header.So it just happens to do a vaguely correct thing.
Well, that is still according to device spec.
Quoted 7 lines
Quoted 3 lines
I tried to find anything in the spec that says any register after
0x10is implemented but failed.
Can you tell me which chater and what it says?19.3.1.10 tells that the header type is 0, as you noted too. Still, the register layout matches bridge spec instead, for example there are bus number registers in place of BAR 2.
Sorry I don't see this in 19.3.1
Where are these registers documented?
In my spec all registers from 0x10 on are greyed out which it says above means 'not implemented'?
My spec also says 'Base Address' for 0x10 - 0x27.
I see bus number and subordinate bus number
registers at 0x40 and 0x41, this is outside
the configuration header. The spec also says
they are unused.
Are we looking at the same spec? Mine is copyright 1997.
Quoted 2 lines
This conflicts with bridge
spec 3.2.4.9. Maybe the device predates the specification.
bridge spec 1.0 was released in 1994, 1.1 in 1998. This spec is from 1997, but the device might be older.
Quoted 263 lines
Quoted 263 lines
Quoted 262 lines
Quoted 21 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
and there it says that the device is
found in the configuration space.Quoted 8 lines
Quoted 6 lines
Quoted 1 line
The secondary bridges are Simbas and should be called APBs.
As far as I can see from the code, it has header type NORMAL but sets
is_bridge.
This was done by this commit:776e1bbb6cf4fe66a93c1a5dd814bbb650deca00IIRC otherwise some registers are not writable.
Yes but which ones? I looked at the manual and it does not list any registers. Playing with code, it looks like we just need to make *some*
BAR writeable. I tried withpci_set_long(d->wmask + PCI_BASE_ADDRESS_0, 0xfffffff0); topci_set_long(d->wmask + PCI_BASE_ADDRESS_5, 0xfffffff0);Quoted 2 lines
and any one of these makes bios get at least to the prompt.
I now know the root cause of the problem. OpenBIOS programs the BARs somewhat correctly just by accident. The initial
io_baseandmem_basefor BARs are not correct, but because the host bridge BARs (and also 6 of which 4 are not even BARs!) are programmed first, the bases happened to settle to values that happen to work. The commit revealed the problem since the settling didn't happen. The mask changes just let the host bridge setup continue to do the magic.By just changing OpenBIOS (see attached patch), I can get the devices to work (assuming that VGA is a separate problem). There's no need to change QEMU.
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
--
MSTFrom
3f957e2dc8477f00f6d3a9491d81399ee750c725Mon Sep 17 00:00:00 2001
Message-Id: <3f957e2dc8477f00f6d3a9491d81399ee750c725.1330890410.git.blauwirbel@gmail.com>
From: Blue Swirl <[email protected]>
Date: Sun, 4 Mar 2012 19:46:38 +0000
Subject: [PATCH] pci: fix BAR setupA change in QEMU on how PCI bridges are setup revealed a bug in OpenBIOS PCI setup. On Sparc64, the BARs just happened to get somewhat correct values by accident before the commit but not after the change.
Avoid to set up BARs for host bridge. Fix bridge check, this lead to setting up 6 BARs instead of more correct 2. If a bridge doesn't have any devices behind it, disable it entirely. Fix Sparc64 PCI memory base.
Signed-off-by Blue Swirl <[email protected]>---
arch/sparc64/openbios.c | 2 +-
drivers/pci.c | 67 ++++++++++++++++++++++++++++++++++------------drivers/pci.h| 7 +++++3 files changed, 57 insertions(+), 19 deletions(-)arch/sparc64/openbios.c +1
-1@@ -64,7 +64,7 @@ static const struct hwdef hwdefs[] = { .cfg_base = APB_SPECIAL_BASE, .cfg_len = 0x2000000, .host_mem_base = APB_MEM_BASE, - .pci_mem_base = 0, + .pci_mem_base = 0x10000000, .mem_len = 0x10000000,.io_base =
APB_SPECIAL_BASE+0x2000000ULL, // PCI Bus I/O space .io_len =0x10000,drivers/pci.c +49
-18@@ -966,11 +966,18 @@ static void ob_pci_configure_bar(pci_addr addr, pci_config_t *config, size = min_align; reloc = (reloc + size -1) & ~(size - 1); if (*io_base == base) { + PCI_DPRINTF("changing io_base from 0x%lx to 0x%x\n", + *io_base, reloc + size); *io_base = reloc + size; reloc -= arch->io_base; } else { + PCI_DPRINTF("changing mem_base from 0x%lx to 0x%x\n", + *mem_base, reloc + size); *mem_base = reloc + size; } + PCI_DPRINTF("Configuring BARs for %s: reloc 0x%x omask 0x%x " + "io_base 0x%lx mem_base 0x%lx\n", + config->path, reloc, *p_omask, *io_base, *mem_base); pci_config_write32(addr, config_addr, reloc | *p_omask); config->assigned[reg] = reloc | *p_omask; }@@ -1021,26 +1028,30 @@ ob_pci_configure(pci_addr addr, pci_config_t *config, int num_regs, int rom_bar, pci_config_write16(addr, PCI_COMMAND, cmd); } -static void ob_configure_pci_device (const char * parent_path, - int *bus_num, unsigned long *mem_base, unsigned long *io_base, - int bus, int devnum, int fn, int *p_is_multi); +static int ob_configure_pci_device (const char * parent_path, + int *bus_num, unsigned long *mem_base, + unsigned long *io_base, int bus, int devnum, + int fn, int *p_is_multi); -static void ob_scan_pci_bus (int *bus_num,unsigned long *mem_base, - unsigned long *io_base, const char *path, - int bus) +static int ob_scan_pci_bus (int *bus_num,unsigned long *mem_base, + unsigned long *io_base, const char *path, + int bus) { - int devnum, fn, is_multi; + int devnum, fn, is_multi, ndevices = 0; PCI_DPRINTF("\nScanning bus %d at %s...\n", bus, path); for (devnum = 0; devnum < 32; devnum++) { is_multi = 0; for (fn = 0; fn==0 || (is_multi && fn<8); fn++) { - ob_configure_pci_device(path, bus_num, mem_base, io_base, - bus, devnum, fn, &is_multi); + ndevices += ob_configure_pci_device(path, bus_num, + mem_base, io_base, + bus, devnum, fn, + &is_multi); } } + return ndevices; } static void ob_configure_pci_bridge(pci_addr addr,@@ -1048,6 +1059,9 @@ static void ob_configure_pci_bridge(pci_addr addr, unsigned long *io_base, int primary_bus, pci_config_t *config) { + int ndevices; + uint8_t command; + config->primary_bus = primary_bus; pci_config_write8(addr, PCI_PRIMARY_BUS, config->primary_bus);@@ -1062,16 +1076,30 @@ static void ob_configure_pci_bridge(pci_addr addr, /* make pci bridge parent device, prepare for recursion */ - ob_scan_pci_bus(bus_num, mem_base, io_base, - config->path, config->secondary_bus); + ndevices = ob_scan_pci_bus(bus_num, mem_base, io_base, + config->path, config->secondary_bus); + if (!ndevices) { + /* no devices, disable bridging */ + PCI_DPRINTF("disabling bridge %s\n", config->path); + command = pci_config_read8(addr, PCI_COMMAND); + command &= ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY | + PCI_COMMAND_VGA_PALETTE | PCI_COMMAND_MASTER); + pci_config_write8(addr, PCI_COMMAND, command); + pci_config_write8(addr, PCI_IO_BASE, 0); + pci_config_write8(addr, PCI_IO_LIMIT, 0); + pci_config_write8(addr, PCI_MEMORY_BASE, 0); + pci_config_write8(addr, PCI_MEMORY_LIMIT, 0); + return; + } /* bus scan updates *bus_num to last revealed pci bus number */ config->subordinate_bus = *bus_num; pci_config_write8(addr, PCI_SUBORDINATE_BUS, config->subordinate_bus); - PCI_DPRINTF("bridge %s PCI bus primary=%d secondary=%d subordinate=%d\n", - config->path, config->primary_bus, config->secondary_bus, - config->subordinate_bus); + PCI_DPRINTF("bridge %s PCI bus primary=%d secondary=%d subordinate=%d" + " ndev=%d\n", + config->path, config->primary_bus, config->secondary_bus, + config->subordinate_bus, ndevices); pci_set_bus_range(config); }@@ -1117,7 +1145,7 @@ static int ob_pci_read_identification(int bus, int devnum, int fn, return 1; } -static void ob_configure_pci_device (const char * parent_path, +static int ob_configure_pci_device (const char * parent_path, int *bus_num, unsigned long *mem_base, unsigned long *io_base, int bus, int devnum, int fn, int *p_is_multi) {@@ -1133,7 +1161,7 @@ static void ob_configure_pci_device(const char* parent_path, int is_host_bridge = 0; if (!ob_pci_read_identification(bus, devnum, fn, &vid, &did, &class, &subclass)) { - return; + return 0; } addr = PCI_ADDR(bus, devnum, fn);@@ -1195,16 +1223,18 @@ static void ob_configure_pci_device(const char* parent_path, if (get_property(phandle, "vendor-id", NULL)) { PCI_DPRINTF("host bridge already configured\n"); - return; + return 0; } } activate_dev(phandle); - if (htype & PCI_HEADER_TYPE_BRIDGE) { + if (htype & PCI_HEADER_TYPE_BRIDGE || (class == PCI_BASE_CLASS_BRIDGE)) { + PCI_DPRINTF("Bridge 2 bars, htype %x\n", htype); num_bars = 2; rom_bar = PCI_ROM_ADDRESS1; } else { + PCI_DPRINTF("Device 6 bars, htype %x\n", htype); num_bars = 6; rom_bar = PCI_ROM_ADDRESS; }@@ -1240,6 +1270,7 @@ static void ob_configure_pci_device(const char* parent_path, ob_configure_pci_bridge(addr, bus_num, mem_base, io_base, bus, &config); } + return 1; } int ob_pci_init(void)drivers/pci.h +7
-1@@ -7,6 +7,8 @@ #define PCI_COMMAND 0x04 #define PCI_COMMAND_IO 0x01 #define PCI_COMMAND_MEMORY 0x02 +#define PCI_COMMAND_MASTER 0x4 /* Enable bus mastering */ +#define PCI_COMMAND_VGA_PALETTE 0x20 /* Enable palette snooping */ #define PCI_STATUS 0x06 /* 16 bits */ #define PCI_STATUS_CAP_LIST 0x10 /* Support Capability List */@@ -44,6 +46,11 @@ #define PCI_BASE_ADDR_4 0x20 #define PCI_BASE_ADDR_5 0x24 +#define PCI_IO_BASE 0x1c/* I/O range behind the bridge */ +#define PCI_IO_LIMIT 0x1d +#define PCI_MEMORY_BASE 0x20/* Memory range behind */ +#define PCI_MEMORY_LIMIT 0x22 + #define PCI_SUBSYSTEM_VENDOR_ID 0x2c #define PCI_SUBSYSTEM_ID 0x2e --1.7.2.5
Quoted 173 lines · Michael S. Tsirkin
Quoted 158 lines · Blue Swirl
Quoted 157 lines · Michael S. Tsirkin
Quoted 155 lines · Blue Swirl
Quoted 144 lines · Michael S. Tsirkin
Quoted 124 lines · Blue Swirl
Quoted 123 lines · Michael S. Tsirkin
Quoted 122 lines · Blue Swirl
Quoted 120 lines · Michael S. Tsirkin
Quoted 108 lines · Blue Swirl
Quoted 107 lines · Michael S. Tsirkin
Quoted 85 lines · Blue Swirl
Quoted 84 lines · Michael S. Tsirkin
On Sun, Mar 04, 2012 at 10:27:24AM +0000, Blue Swirl wrote:
On Sun, Mar 4, 2012 at 09:46, Michael S. Tsirkin <[email protected]> wrote:
commit 5caef97a16010f818ea8b950e2ee24ba876643ad introduced
a regression: we do not make IO base/limit upper 16
bit registers writeable, so we should report a 16 bit
IO range type, not a 32 bit one.
Note that PCI_PREF_RANGE_TYPE_32 is 0x0, but PCI_IO_RANGE_TYPE_32 is 0x1.In particular, this broke sparc64.
Note: this just reverts to behaviour prior to the patch.
Making PCI_IO_BASE_UPPER16 and PCI_IO_LIMIT_UPPER16
registers writeable should, and seems to, work just as well, but
as no system seems to actually be interested in 32 bit IO,
let's not make unnecessary changes.Reported-by: Mark Cave-Ayland <[email protected]>
Signed-off-by: Michael S. Tsirkin <[email protected]>Mark, can you confirm that this fixes the bug for you?
No, running
qemu-system-sparc64 -serial stdio
still shows black screen and the following on console:
OpenBIOS for Sparc64
Unhandled Exception 0x0000000000000032
PC = 0x00000000ffd19e18 NPC = 0x00000000ffd19e1c
Stopping executionThe weird thing is the range type does not seem to be accessed
at all. So I guessed there's some memory corruption here.
Running valgrind shows this:--11114-- WARNING: unhandled syscall: 340
--11114-- You may be able to write your own handler.
--11114-- Read the file README_MISSING_SYSCALL_OR_IOCTL.
--11114-- Nevertheless we consider this a bug. Please report
--11114-- it at http://valgrind.org/support/bug_reports.html.
==11114== Invalid read of size 4
==11114== at 0x2A68C0: pci_apb_init (apb_pci.c:350)
==11114== by 0x2F7A84: sun4uv_init (sun4u.c:779)
==11114== by 0x13D716: main (vl.c:3397)
==11114== Address 0x156c7d30 is 0 bytes after a block of size 64
alloc'd
==11114== at 0x557DD69: malloc (vg_replace_malloc.c:236)
==11114== by 0x225F56: malloc_and_trace (vl.c:2156)
==11114== by 0x584AFEC: ??? (in /lib/libglib-2.0.so.0.2800.8)
==11114== by 0x584B528: g_malloc0 (in /lib/libglib-2.0.so.0.2800.8)
==11114== by 0x19C50C: qemu_allocate_irqs (irq.c:47)
==11114== by 0x2F7A4C: sun4uv_init (sun4u.c:778)
==11114== by 0x13D716: main (vl.c:3397)
==11114==
apb: here
==11114== Warning: client switching stacks? SP change: 0xfec42cbc -->
0x16894008
==11114== to suppress, use: --max-stackframe=398791500 or
greater
==11114== Warning: client switching stacks? SP change: 0x16893fa0 -->
0xfec42cc0
==11114== to suppress, use: --max-stackframe=398791392 or
greater
==11114== Warning: client switching stacks? SP change: 0xfec42fe0 -->
0x16893fd0
==11114== to suppress, use: --max-stackframe=398790640 or
greater
==11114== further instances of this message will not be shown.
QEMU 1.0.50 monitor - type 'help' for more information
(qemu) ==11114== Thread 2:
==11114== Conditional jump or move depends on uninitialised value(s)
==11114== at 0x2A8351: compute_all_sub (cc_helper.c:37)
==11114== by 0x2A8782: helper_compute_psr (cc_helper.c:470)
==11114== by 0x9AD9A19: ???
==11114==
==11114== Conditional jump or move depends on uninitialised value(s)
==11114== at 0x2A827C: compute_all_sub_xcc (cc_helper.c:60)
==11114== by 0x2A8795: helper_compute_psr (cc_helper.c:473)
==11114== by 0x9AD9A19: ???
==11114==
==11114== Conditional jump or move depends on uninitialised value(s)
==11114== at 0x2A8296: compute_all_sub_xcc (cc_helper.c:295)
==11114== by 0x2A8795: helper_compute_psr (cc_helper.c:473)
==11114== by 0x9AD9A19: ???
==11114==Quoted 3 lines
Quoted 1 line
Is the above a problem?
It looks like Sparc does not reset registers at CPU reset. Nice catch.
Invalid read and address after block are also worrying.
irqs are allocated with
#defineMAX_PILS16irq =
qemu_allocate_irqs(cpu_set_irq, env, MAX_PILS);then passed to apb:
pci_bus =
pci_apb_init(APB_SPECIAL_BASE, APB_MEM_BASE, irq, &pci_bus2, &pci_bus3);which does:
PCIBus *pci_apb_init(target_phys_addr_tspecial_base,target_phys_addr_tmem_base,qemu_irq*pic, PCIBus **bus2, PCIBus **bus3)Quoted 7 lines
Quoted 5 lines
and
for (i = 0; i < 32; i++) {
sysbus_connect_irq(s, i, pic[i]);
}Awful. But using 32 for
MAX_PILSdoes not help either.Could you please clarify what is the SABRE device? Is it, in fact, a bridge device? Or not?
Quoted 8 lines
Quoted 5 lines
Quoted 2 lines
Yes, it's the host bridge, also known as PBM. It's documented in UltraSPARC IIi User's Manual
Btw would be nice to host the manuals at qemu.org our code points at sun.com URLs :(
I have most if not all manuals, downloaded from sun.com, but I'm not sure if they can be redistributed.
Okay ...
Let's change the link to point to some other place which has them?Quoted 7 lines
Quoted 6 lines
I am looking at 19.3.1 PCI Configuration Space and it appears to show that this is a regular device with a couple of custom registers at pffsets
0x40and0x41.Why do we want to pretend it is a bridge?
Quoted 8 lines
Quoted 1 line
It's the host bridge and the device class is
PCI_CLASS_BRIDGE_HOST.Yes. But the *header* type is 0 (NORMAL) while the code in
pci_init_mask_bridgewhich is the only user of theis_bridgeregister initializes a type 1 (BRIDGE) header.So it just happens to do a vaguely correct thing.
Well, that is still according to device spec.
Quoted 7 lines
Quoted 3 lines
I tried to find anything in the spec that says any register after
0x10is implemented but failed.
Can you tell me which chater and what it says?19.3.1.10 tells that the header type is 0, as you noted too. Still, the register layout matches bridge spec instead, for example there are bus number registers in place of BAR 2.
Sorry I don't see this in 19.3.1
Where are these registers documented?
In my spec all registers from0x10on are greyed out which it says above means 'not implemented'?
My spec also says 'Base Address' for0x10-0x27.
Quoted 4 lines
I see bus number and subordinate bus number
registers at0x40and0x41, this is outside
the configuration header. The spec also says
they are unused.
Oh, I somehow read that they were in bridge locations 0x18 and 0x19. Perhaps the is_bridge property should be removed after OpenBIOS no longer wants to write to the registers.
Quoted 1 line
Are we looking at the same spec? Mine is copyright 1997.
Yes, Part No.: 805-0087-01.
Quoted 270 lines
Quoted 2 lines
This conflicts with bridge
spec 3.2.4.9. Maybe the device predates the specification.bridge spec 1.0 was released in 1994, 1.1 in 1998. This spec is from 1997, but the device might be older.
Quoted 263 lines
Quoted 263 lines
Quoted 262 lines
Quoted 21 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
and there it says that the device is
found in the configuration space.Quoted 8 lines
Quoted 6 lines
Quoted 1 line
The secondary bridges are Simbas and should be called APBs.
As far as I can see from the code, it has header type NORMAL but sets
is_bridge.
This was done by this commit:776e1bbb6cf4fe66a93c1a5dd814bbb650deca00IIRC otherwise some registers are not writable.
Yes but which ones? I looked at the manual and it does not list any registers. Playing with code, it looks like we just need to make *some*
BAR writeable. I tried withpci_set_long(d->wmask + PCI_BASE_ADDRESS_0, 0xfffffff0); topci_set_long(d->wmask + PCI_BASE_ADDRESS_5, 0xfffffff0);Quoted 2 lines
and any one of these makes bios get at least to the prompt.
I now know the root cause of the problem. OpenBIOS programs the BARs somewhat correctly just by accident. The initial
io_baseandmem_basefor BARs are not correct, but because the host bridge BARs (and also 6 of which 4 are not even BARs!) are programmed first, the bases happened to settle to values that happen to work. The commit revealed the problem since the settling didn't happen. The mask changes just let the host bridge setup continue to do the magic.By just changing OpenBIOS (see attached patch), I can get the devices to work (assuming that VGA is a separate problem). There's no need to change QEMU.
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
--
MSTFrom
3f957e2dc8477f00f6d3a9491d81399ee750c725Mon Sep 17 00:00:00 2001
Message-Id: <3f957e2dc8477f00f6d3a9491d81399ee750c725.1330890410.git.blauwirbel@gmail.com>
From: Blue Swirl <[email protected]>
Date: Sun, 4 Mar 2012 19:46:38 +0000
Subject: [PATCH] pci: fix BAR setupA change in QEMU on how PCI bridges are setup revealed a bug in OpenBIOS PCI setup. On Sparc64, the BARs just happened to get somewhat correct values by accident before the commit but not after the change.
Avoid to set up BARs for host bridge. Fix bridge check, this lead to setting up 6 BARs instead of more correct 2. If a bridge doesn't have any devices behind it, disable it entirely. Fix Sparc64 PCI memory base.
Signed-off-by Blue Swirl <[email protected]>---
arch/sparc64/openbios.c | 2 +-
drivers/pci.c | 67 ++++++++++++++++++++++++++++++++++------------drivers/pci.h| 7 +++++3 files changed, 57 insertions(+), 19 deletions(-)arch/sparc64/openbios.c +1
-1@@ -64,7 +64,7 @@ static const struct hwdef hwdefs[] = { .cfg_base = APB_SPECIAL_BASE, .cfg_len = 0x2000000, .host_mem_base = APB_MEM_BASE, - .pci_mem_base = 0, + .pci_mem_base = 0x10000000, .mem_len = 0x10000000,.io_base =
APB_SPECIAL_BASE+0x2000000ULL, // PCI Bus I/O space .io_len =0x10000,drivers/pci.c +49
-18@@ -966,11 +966,18 @@ static void ob_pci_configure_bar(pci_addr addr, pci_config_t *config, size = min_align; reloc = (reloc + size -1) & ~(size - 1); if (*io_base == base) { + PCI_DPRINTF("changing io_base from 0x%lx to 0x%x\n", + *io_base, reloc + size); *io_base = reloc + size; reloc -= arch->io_base; } else { + PCI_DPRINTF("changing mem_base from 0x%lx to 0x%x\n", + *mem_base, reloc + size); *mem_base = reloc + size; } + PCI_DPRINTF("Configuring BARs for %s: reloc 0x%x omask 0x%x " + "io_base 0x%lx mem_base 0x%lx\n", + config->path, reloc, *p_omask, *io_base, *mem_base); pci_config_write32(addr, config_addr, reloc | *p_omask); config->assigned[reg] = reloc | *p_omask; }@@ -1021,26 +1028,30 @@ ob_pci_configure(pci_addr addr, pci_config_t *config, int num_regs, int rom_bar, pci_config_write16(addr, PCI_COMMAND, cmd); } -static void ob_configure_pci_device (const char * parent_path, - int *bus_num, unsigned long *mem_base, unsigned long *io_base, - int bus, int devnum, int fn, int *p_is_multi); +static int ob_configure_pci_device (const char * parent_path, + int *bus_num, unsigned long *mem_base, + unsigned long *io_base, int bus, int devnum, + int fn, int *p_is_multi); -static void ob_scan_pci_bus (int *bus_num,unsigned long *mem_base, - unsigned long *io_base, const char *path, - int bus) +static int ob_scan_pci_bus (int *bus_num,unsigned long *mem_base, + unsigned long *io_base, const char *path, + int bus) { - int devnum, fn, is_multi; + int devnum, fn, is_multi, ndevices = 0; PCI_DPRINTF("\nScanning bus %d at %s...\n", bus, path); for (devnum = 0; devnum < 32; devnum++) { is_multi = 0; for (fn = 0; fn==0 || (is_multi && fn<8); fn++) { - ob_configure_pci_device(path, bus_num, mem_base, io_base, - bus, devnum, fn, &is_multi); + ndevices += ob_configure_pci_device(path, bus_num, + mem_base, io_base, + bus, devnum, fn, + &is_multi); } } + return ndevices; } static void ob_configure_pci_bridge(pci_addr addr,@@ -1048,6 +1059,9 @@ static void ob_configure_pci_bridge(pci_addr addr, unsigned long *io_base, int primary_bus, pci_config_t *config) { + int ndevices; + uint8_t command; + config->primary_bus = primary_bus; pci_config_write8(addr, PCI_PRIMARY_BUS, config->primary_bus);@@ -1062,16 +1076,30 @@ static void ob_configure_pci_bridge(pci_addr addr, /* make pci bridge parent device, prepare for recursion */ - ob_scan_pci_bus(bus_num, mem_base, io_base, - config->path, config->secondary_bus); + ndevices = ob_scan_pci_bus(bus_num, mem_base, io_base, + config->path, config->secondary_bus); + if (!ndevices) { + /* no devices, disable bridging */ + PCI_DPRINTF("disabling bridge %s\n", config->path); + command = pci_config_read8(addr, PCI_COMMAND); + command &= ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY | + PCI_COMMAND_VGA_PALETTE | PCI_COMMAND_MASTER); + pci_config_write8(addr, PCI_COMMAND, command); + pci_config_write8(addr, PCI_IO_BASE, 0); + pci_config_write8(addr, PCI_IO_LIMIT, 0); + pci_config_write8(addr, PCI_MEMORY_BASE, 0); + pci_config_write8(addr, PCI_MEMORY_LIMIT, 0); + return; + } /* bus scan updates *bus_num to last revealed pci bus number */ config->subordinate_bus = *bus_num; pci_config_write8(addr, PCI_SUBORDINATE_BUS, config->subordinate_bus); - PCI_DPRINTF("bridge %s PCI bus primary=%d secondary=%d subordinate=%d\n", - config->path, config->primary_bus, config->secondary_bus, - config->subordinate_bus); + PCI_DPRINTF("bridge %s PCI bus primary=%d secondary=%d subordinate=%d" + " ndev=%d\n", + config->path, config->primary_bus, config->secondary_bus, + config->subordinate_bus, ndevices); pci_set_bus_range(config); }@@ -1117,7 +1145,7 @@ static int ob_pci_read_identification(int bus, int devnum, int fn, return 1; } -static void ob_configure_pci_device (const char * parent_path, +static int ob_configure_pci_device (const char * parent_path, int *bus_num, unsigned long *mem_base, unsigned long *io_base, int bus, int devnum, int fn, int *p_is_multi) {@@ -1133,7 +1161,7 @@ static void ob_configure_pci_device(const char* parent_path, int is_host_bridge = 0; if (!ob_pci_read_identification(bus, devnum, fn, &vid, &did, &class, &subclass)) { - return; + return 0; } addr = PCI_ADDR(bus, devnum, fn);@@ -1195,16 +1223,18 @@ static void ob_configure_pci_device(const char* parent_path, if (get_property(phandle, "vendor-id", NULL)) { PCI_DPRINTF("host bridge already configured\n"); - return; + return 0; } } activate_dev(phandle); - if (htype & PCI_HEADER_TYPE_BRIDGE) { + if (htype & PCI_HEADER_TYPE_BRIDGE || (class == PCI_BASE_CLASS_BRIDGE)) { + PCI_DPRINTF("Bridge 2 bars, htype %x\n", htype); num_bars = 2; rom_bar = PCI_ROM_ADDRESS1; } else { + PCI_DPRINTF("Device 6 bars, htype %x\n", htype); num_bars = 6; rom_bar = PCI_ROM_ADDRESS; }@@ -1240,6 +1270,7 @@ static void ob_configure_pci_device(const char* parent_path, ob_configure_pci_bridge(addr, bus_num, mem_base, io_base, bus, &config); } + return 1; } int ob_pci_init(void)drivers/pci.h +7
-1@@ -7,6 +7,8 @@ #define PCI_COMMAND 0x04 #define PCI_COMMAND_IO 0x01 #define PCI_COMMAND_MEMORY 0x02 +#define PCI_COMMAND_MASTER 0x4 /* Enable bus mastering */ +#define PCI_COMMAND_VGA_PALETTE 0x20 /* Enable palette snooping */ #define PCI_STATUS 0x06 /* 16 bits */ #define PCI_STATUS_CAP_LIST 0x10 /* Support Capability List */@@ -44,6 +46,11 @@ #define PCI_BASE_ADDR_4 0x20 #define PCI_BASE_ADDR_5 0x24 +#define PCI_IO_BASE 0x1c/* I/O range behind the bridge */ +#define PCI_IO_LIMIT 0x1d +#define PCI_MEMORY_BASE 0x20/* Memory range behind */ +#define PCI_MEMORY_LIMIT 0x22 + #define PCI_SUBSYSTEM_VENDOR_ID 0x2c #define PCI_SUBSYSTEM_ID 0x2e --1.7.2.5
Quoted 10 lines · Blue Swirl
Quoted 10 lines
Quoted 3 lines
19.3.1.10 tells that the header type is 0, as you noted too. Still, the register layout matches bridge spec instead, for example there are bus number registers in place of BAR 2.
Sorry I don't see this in 19.3.1
Where are these registers documented?
In my spec all registers from0x10on are greyed out which it says above means 'not implemented'?
My spec also says 'Base Address' for0x10-0x27.
Quoted 8 lines
Quoted 4 lines
I see bus number and subordinate bus number
registers at0x40and0x41, this is outside
the configuration header. The spec also says
they are unused.Oh, I somehow read that they were in bridge locations
0x18and0x19. Perhaps theis_bridgeproperty should be removed after OpenBIOS no longer wants to write to the registers.
So we are in agreement then?
The device seems to (more or less) go by the spec, but openbios gets confused, apparently by the absence of BARs.
Can you try debugging openbios to see what is wrong?
Signature · 1 line
MST
Quoted 16 lines · Michael S. Tsirkin
Quoted 15 lines · Blue Swirl
Quoted 14 lines
Quoted 3 lines
19.3.1.10 tells that the header type is 0, as you noted too. Still, the register layout matches bridge spec instead, for example there are bus number registers in place of BAR 2.
Sorry I don't see this in 19.3.1
Where are these registers documented?
In my spec all registers from0x10on are greyed out which it says above means 'not implemented'?
My spec also says 'Base Address' for0x10-0x27.I see bus number and subordinate bus number
registers at0x40and0x41, this is outside
the configuration header. The spec also says
they are unused.
Quoted 6 lines
Quoted 3 lines
Oh, I somehow read that they were in bridge locations
0x18and0x19. Perhaps theis_bridgeproperty should be removed after OpenBIOS no longer wants to write to the registers.So we are in agreement then?
The device seems to (more or less) go by the spec,
QEMU is correct here as is your original commit. The only change (beside bug fixes for the problems you found, thanks) should be for is_bridge.
Quoted 3 lines
but openbios gets confused, apparently by the absence of BARs.
Can you try debugging openbios to see what is wrong?
On second thought, I think 32 bit I/O was confusing OpenBIOS, probably the host bridge device not so much. PCI handling in OpenBIOS should be fixed.
Quoted 2 lines
--
MST
Quoted 21 lines · Blue Swirl
Quoted 20 lines · Michael S. Tsirkin
Quoted 18 lines · Blue Swirl
Quoted 10 lines
Quoted 3 lines
19.3.1.10 tells that the header type is 0, as you noted too. Still, the register layout matches bridge spec instead, for example there are bus number registers in place of BAR 2.
Sorry I don't see this in 19.3.1
Where are these registers documented?
In my spec all registers from0x10on are greyed out which it says above means 'not implemented'?
My spec also says 'Base Address' for0x10-0x27.Quoted 4 lines
I see bus number and subordinate bus number
registers at0x40and0x41, this is outside
the configuration header. The spec also says
they are unused.Oh, I somehow read that they were in bridge locations
0x18and0x19. Perhaps theis_bridgeproperty should be removed after OpenBIOS no longer wants to write to the registers.
Quoted 6 lines
Quoted 2 lines
So we are in agreement then?
The device seems to (more or less) go by the spec,QEMU is correct here as is your original commit. The only change (beside bug fixes for the problems you found, thanks) should be for
is_bridge.
You mean remove is_bridge? Right.
Quoted 7 lines
Quoted 3 lines
but openbios gets confused, apparently by the absence of BARs.
Can you try debugging openbios to see what is wrong?
On second thought, I think 32 bit I/O was confusing OpenBIOS, probably the host bridge device not so much. PCI handling in OpenBIOS should be fixed.
We can make IO 32 bit. Want to try?
Anyway, so I won't revert this in core for now?
Quoted 2 lines
Quoted 2 lines
--
MST
Quoted 11 lines · Blue Swirl
I now know the root cause of the problem. OpenBIOS programs the BARs somewhat correctly just by accident. The initial
io_baseandmem_basefor BARs are not correct, but because the host bridge BARs (and also 6 of which 4 are not even BARs!) are programmed first, the bases happened to settle to values that happen to work. The commit revealed the problem since the settling didn't happen. The mask changes just let the host bridge setup continue to do the magic.By just changing OpenBIOS (see attached patch), I can get the devices to work (assuming that VGA is a separate problem). There's no need to change QEMU.
Hi Blue/Michael,
Thanks for debugging this. I can confirm that building OpenBIOS SVN trunk with Blue's patch and testing against QEMU git master with the attached patch (to temporarily back out 2b50aa1f14d8e0a40f905ad0c022443c15646914 and de58ac72b6a062d1a61478284c0c0f8a0428613e which breaks VGA on PPC/SPARC64) appears to fix the problem for me.
Thanks a lot to both of you for taking the time to track this down :)
ATB,
Mark.
ioport.c +7 -21
@@ -328,7 +328,6 @@ void portio_list_init(PortioList *piolist, piolist->ports = callbacks; piolist->nr =0 ; piolist->regions = g_new0(MemoryRegion *, n); - piolist->aliases = g_new0(MemoryRegion *, n); piolist->address_space =NULL ; piolist->opaque = opaque; piolist->name = name;
@@ -337,7 +336,6 @@ void portio_list_init(PortioList *piolist,void portio_list_destroy (PortioList *piolist) {g_free (piolist->regions); -g_free (piolist->aliases); } static void portio_list_add_1(PortioList *piolist,
@@ -347,7 +345,7 @@ static void portio_list_add_1(PortioList *piolist, {MemoryRegionPortio *pio;MemoryRegionOps *ops; -MemoryRegion *region, *alias; +MemoryRegion *region;unsigned i;/* Copy the sub-list and null-terminate it. */
@@ -364,20 +362,12 @@ static void portio_list_add_1(PortioList *piolist, ops->old_portio = pio; region =g_new (MemoryRegion,1 ); - alias =g_new (MemoryRegion,1 ); -/* -* Use an alias so that the callback is called with an absolute address, -* rather than an offset relative to to start + off_low. -*/ memory_region_init_io (region, ops, piolist->opaque, piolist->name, -UINT64_MAX ); -memory_region_init_alias (alias, piolist->name, - region, start + off_low, off_high - off_low); + off_high - off_low); +memory_region_set_offset (region, start + off_low);memory_region_add_subregion (piolist->address_space, - start + off_low, alias); - piolist->regions[piolist->nr] = region; - piolist->aliases[piolist->nr] = alias; - ++piolist->nr; + start + off_low, region); + piolist->regions[piolist->nr++] = region; } void portio_list_add(PortioList *piolist,
@@ -419,19 +409,15 @@ void portio_list_add(PortioList *piolist,void portio_list_del (PortioList *piolist) { -MemoryRegion *mr, *alias; +MemoryRegion *mr;unsigned i;for (i =0 ; i < piolist->nr; ++i) { mr = piolist->regions[i]; - alias = piolist->aliases[i]; -memory_region_del_subregion (piolist->address_space, alias); -memory_region_destroy (alias); +memory_region_del_subregion (piolist->address_space, mr);memory_region_destroy (mr);g_free ((MemoryRegionOps *)mr->ops);g_free (mr); -g_free (alias); piolist->regions[i] =NULL ; - piolist->aliases[i] =NULL ; } }
ioport.h +0 -1
@@ -60,7 +60,6 @@ typedef struct PortioList {struct MemoryRegion *address_space;unsigned nr;struct MemoryRegion **regions; -struct MemoryRegion **aliases;void *opaque;const char *name; } PortioList;
memory.c +16 -10
@@ -389,17 +389,17 @@ static void memory_region_iorange_read(IORange *iorange, *data = ((uint64_t )1 << (width *8 )) -1 ;if (mrp) { - *data = mrp->read (mr->opaque, offset); + *data = mrp->read (mr->opaque, offset + mr->offset); }else if (width ==2 ) { mrp =find_portio (mr, offset,1 , false);assert (mrp); - *data = mrp->read (mr->opaque, offset) | - (mrp->read (mr->opaque, offset +1 ) <<8 ); + *data = mrp->read (mr->opaque, offset + mr->offset) | + (mrp->read (mr->opaque, offset + mr->offset +1 ) <<8 ); }return ; } *data =0 ; -access_with_adjusted_size (offset, data, width, +access_with_adjusted_size (offset + mr->offset, data, width, mr->ops->impl.min_access_size, mr->ops->impl.max_access_size, memory_region_read_accessor, mr);
@@ -416,16 +416,16 @@ static void memory_region_iorange_write(IORange *iorange,const MemoryRegionPortio *mrp =find_portio (mr, offset, width, true);if (mrp) { - mrp->write (mr->opaque, offset, data); + mrp->write (mr->opaque, offset + mr->offset, data); }else if (width ==2 ) { mrp =find_portio (mr, offset,1 , false);assert (mrp); - mrp->write (mr->opaque, offset, data &0xff ); - mrp->write (mr->opaque, offset +1 , data >>8 ); + mrp->write (mr->opaque, offset + mr->offset, data &0xff ); + mrp->write (mr->opaque, offset + mr->offset +1 , data >>8 ); }return ; } -access_with_adjusted_size (offset, &data, width, +access_with_adjusted_size (offset + mr->offset, &data, width, mr->ops->impl.min_access_size, mr->ops->impl.max_access_size, memory_region_write_accessor, mr);
@@ -796,6 +796,7 @@ void memory_region_init(MemoryRegion *mr, mr->size =int128_2_64 (); } mr->addr =0 ; + mr->offset =0 ; mr->subpage = false; mr->enabled = true; mr->terminates = false;
@@ -857,7 +858,7 @@ static uint64_t memory_region_dispatch_read1(MemoryRegion *mr, }/* FIXME: support unaligned access */ -access_with_adjusted_size (addr, &data, size, +access_with_adjusted_size (addr + mr->offset, &data, size, mr->ops->impl.min_access_size, mr->ops->impl.max_access_size, memory_region_read_accessor, mr);
@@ -911,7 +912,7 @@ static void memory_region_dispatch_write(MemoryRegion *mr, }/* FIXME: support unaligned access */ -access_with_adjusted_size (addr, &data, size, +access_with_adjusted_size (addr + mr->offset, &data, size, mr->ops->impl.min_access_size, mr->ops->impl.max_access_size, memory_region_write_accessor, mr);
@@ -1054,6 +1055,11 @@ bool memory_region_is_rom(MemoryRegion *mr)return mr->ram && mr->readonly; } +void memory_region_set_offset (MemoryRegion *mr,target_phys_addr_t offset) +{ + mr->offset = offset; +} +void memory_region_set_log (MemoryRegion *mr,bool log,unsigned client) {uint8_t mask =1 << client;
memory.h +9 -0
@@ -115,6 +115,7 @@ struct MemoryRegion {MemoryRegion *parent;Int128 size;target_phys_addr_t addr; +target_phys_addr_t offset;void (*destructor)(MemoryRegion *mr);ram_addr_t ram_addr;IORange iorange;
@@ -370,6 +371,14 @@ bool memory_region_is_rom(MemoryRegion *mr);void *memory_region_get_ram_ptr (MemoryRegion *mr);/** +* memory_region_set_offset: Sets an offset to be added to MemoryRegionOps +* callbacks. +* +* This function is deprecated and should not be used in new code. +*/ +void memory_region_set_offset (MemoryRegion *mr,target_phys_addr_t offset); + +/** * memory_region_set_log: Turn dirty logging on or off for a region. * * Turns dirty logging on or off for a specified client (display, migration).
Quoted 3 lines · Blue Swirl
Yes, it's the host bridge, also known as PBM. It's documented in UltraSPARC IIi User's Manual and there it says that the device is found in the configuration space.
So it seems I can make things work if
I disable is_bridge and make some bits in
BAR4 writeable:
pci_set_long(d->wmask + 0x20, 0xffff0000);
I don't yet know why, and the manual says there
should be no BARs.
Quoted 6 lines
The secondary bridges are Simbas and should be called APBs.
Quoted 4 lines
--
MST
Quoted 85 lines · Blue Swirl
Quoted 84 lines · Michael S. Tsirkin
Quoted 20 lines · Blue Swirl
Quoted 14 lines · Michael S. Tsirkin
commit
5caef97a16010f818ea8b950e2ee24ba876643adintroduced
a regression: we do not make IO base/limit upper 16
bit registers writeable, so we should report a 16 bit
IO range type, not a 32 bit one.
Note thatPCI_PREF_RANGE_TYPE_32is0x0, butPCI_IO_RANGE_TYPE_32is0x1.In particular, this broke sparc64.
Note: this just reverts to behaviour prior to the patch. Making
PCI_IO_BASE_UPPER16andPCI_IO_LIMIT_UPPER16registers writeable should, and seems to, work just as well, but as no system seems to actually be interested in 32 bit IO, let's not make unnecessary changes.Quoted 4 lines
Reported-by Mark Cave-Ayland <[email protected]>Signed-off-by Michael S. Tsirkin <[email protected]>Mark, can you confirm that this fixes the bug for you?
Quoted 7 lines
No, running
qemu-system-sparc64 -serial stdio
still shows black screen and the following on console:
OpenBIOS for Sparc64
Unhandled Exception0x0000000000000032
PC =0x00000000ffd19e18NPC =0x00000000ffd19e1cStopping executionThe weird thing is the range type does not seem to be accessed at all. So I guessed there's some memory corruption here. Running valgrind shows this:
--11114-- WARNING: unhandled syscall: 340
--11114-- You may be able to write your own handler. --11114-- Read the fileREADME_MISSING_SYSCALL_OR_IOCTL. --11114-- Nevertheless we consider this a bug. Please report --11114-- it at http://valgrind.org/support/bug_reports.html.
==11114== Invalid read of size 4
==11114== at0x2A68C0:pci_apb_init(apb_pci.c:350) ==11114== by0x2F7A84:sun4uv_init(sun4u.c:779) ==11114== by0x13D716: main (vl.c:3397)
==11114== Address0x156c7d30is 0 bytes after a block of size 64 alloc'd
==11114== at0x557DD69: malloc (vg_replace_malloc.c:236) ==11114== by0x225F56:malloc_and_trace(vl.c:2156) ==11114== by0x584AFEC: ??? (in/lib/libglib-2.0.so.0.2800.8) ==11114== by0x584B528:g_malloc0(in/lib/libglib-2.0.so.0.2800.8) ==11114== by0x19C50C:qemu_allocate_irqs(irq.c:47) ==11114== by0x2F7A4C:sun4uv_init(sun4u.c:778) ==11114== by0x13D716: main (vl.c:3397)
==11114==
apb: here
==11114== Warning: client switching stacks? SP change:0xfec42cbc-->0x16894008
==11114== to suppress, use: --max-stackframe=398791500 or greater
==11114== Warning: client switching stacks? SP change:0x16893fa0-->0xfec42cc0
==11114== to suppress, use: --max-stackframe=398791392 or greater
==11114== Warning: client switching stacks? SP change:0xfec42fe0-->0x16893fd0
==11114== to suppress, use: --max-stackframe=398790640 or greater
==11114== further instances of this message will not be shown. QEMU 1.0.50 monitor - type 'help' for more information (qemu) ==11114== Thread 2:
==11114== Conditional jump or move depends on uninitialised value(s) ==11114== at0x2A8351:compute_all_sub(cc_helper.c:37) ==11114== by0x2A8782:helper_compute_psr(cc_helper.c:470) ==11114== by0x9AD9A19: ???
==11114==
==11114== Conditional jump or move depends on uninitialised value(s) ==11114== at0x2A827C:compute_all_sub_xcc(cc_helper.c:60) ==11114== by0x2A8795:helper_compute_psr(cc_helper.c:473) ==11114== by0x9AD9A19: ???
==11114==
==11114== Conditional jump or move depends on uninitialised value(s) ==11114== at0x2A8296:compute_all_sub_xcc(cc_helper.c:295) ==11114== by0x2A8795:helper_compute_psr(cc_helper.c:473) ==11114== by0x9AD9A19: ???
==11114==
Quoted 3 lines
Quoted 1 line
Is the above a problem?
It looks like Sparc does not reset registers at CPU reset. Nice catch.
The following is likely also needed, maybe the define should be shared with apb.
hw/sun4u.c +1 -1
@@ -81,7 +81,7 @@#define FW_CFG_SPARC64_HEIGHT (FW_CFG_ARCH_LOCAL + 0x01)#define FW_CFG_SPARC64_DEPTH (FW_CFG_ARCH_LOCAL + 0x02) -#define MAX_PILS 16 +#define MAX_PILS 32#define TICK_MAX 0x7fffffffffffffffULL
Quoted 33 lines · Blue Swirl
Quoted 14 lines · Michael S. Tsirkin
commit
5caef97a16010f818ea8b950e2ee24ba876643adintroduced
a regression: we do not make IO base/limit upper 16
bit registers writeable, so we should report a 16 bit
IO range type, not a 32 bit one.
Note thatPCI_PREF_RANGE_TYPE_32is0x0, butPCI_IO_RANGE_TYPE_32is0x1.In particular, this broke sparc64.
Note: this just reverts to behaviour prior to the patch. Making
PCI_IO_BASE_UPPER16andPCI_IO_LIMIT_UPPER16registers writeable should, and seems to, work just as well, but as no system seems to actually be interested in 32 bit IO, let's not make unnecessary changes.Quoted 4 lines
Reported-by Mark Cave-Ayland <[email protected]>Signed-off-by Michael S. Tsirkin <[email protected]>Mark, can you confirm that this fixes the bug for you?
No, running
qemu-system-sparc64 -serial stdio
still shows black screen and the following on console:
OpenBIOS for Sparc64
Unhandled Exception0x0000000000000032
PC =0x00000000ffd19e18NPC =0x00000000ffd19e1cStopping executionThis unassigned memory exception is triggered because CMD646 IDE I/O registers are not accessible:
(qemu) info pci
Bus 0, device 5, function 0:
Quoted 8 lines
IDE controller: PCI device 1095:0646
IRQ 1.
BAR0: I/O at 0xffffffffffffffff [0x0006].
BAR1: I/O at 0xffffffffffffffff [0x0002].
BAR2: I/O at 0xffffffffffffffff [0x0006].
BAR3: I/O at 0xffffffffffffffff [0x0002].
BAR4: I/O at 0xffffffffffffffff [0x000e].
id ""The BARs are not initialized, so they aren't accessible.
But perhaps the dump was not taken at the point of failure, can you provide a relevant dump if so?
Signature · 1 line
error compiling committee.c: too many arguments to function
Quoted 43 lines · Avi Kivity
Quoted 31 lines · Blue Swirl
Quoted 14 lines · Michael S. Tsirkin
commit
5caef97a16010f818ea8b950e2ee24ba876643adintroduced
a regression: we do not make IO base/limit upper 16
bit registers writeable, so we should report a 16 bit
IO range type, not a 32 bit one.
Note thatPCI_PREF_RANGE_TYPE_32is0x0, butPCI_IO_RANGE_TYPE_32is0x1.In particular, this broke sparc64.
Note: this just reverts to behaviour prior to the patch. Making
PCI_IO_BASE_UPPER16andPCI_IO_LIMIT_UPPER16registers writeable should, and seems to, work just as well, but as no system seems to actually be interested in 32 bit IO, let's not make unnecessary changes.Quoted 4 lines
Reported-by Mark Cave-Ayland <[email protected]>Signed-off-by Michael S. Tsirkin <[email protected]>Mark, can you confirm that this fixes the bug for you?
No, running
qemu-system-sparc64 -serial stdio
still shows black screen and the following on console:
OpenBIOS for Sparc64
Unhandled Exception0x0000000000000032
PC =0x00000000ffd19e18NPC =0x00000000ffd19e1cStopping executionThis unassigned memory exception is triggered because CMD646 IDE I/O registers are not accessible:
Quoted 10 lines
(qemu) info pci
Bus 0, device 5, function 0:
IDE controller: PCI device 1095:0646
IRQ 1.
BAR0: I/O at0xffffffffffffffff[0x0006].
BAR1: I/O at0xffffffffffffffff[0x0002].
BAR2: I/O at0xffffffffffffffff[0x0006].
BAR3: I/O at0xffffffffffffffff[0x0002].
BAR4: I/O at0xffffffffffffffff[0x000e].
id ""
Quoted 4 lines
The BARs are not initialized, so they aren't accessible.
But perhaps the dump was not taken at the point of failure, can you provide a relevant dump if so?
No, this is after failure.
Quoted 4 lines
--
error compilingcommittee.c: too many arguments to function
Quoted 15 lines · Blue Swirl
Quoted 15 lines
Quoted 14 lines
This unassigned memory exception is triggered because CMD646 IDE I/O registers are not accessible:
(qemu) info pci
Bus 0, device 5, function 0:IDE controller: PCI device 1095:0646 IRQ 1. BAR0: I/O at 0xffffffffffffffff [0x0006]. BAR1: I/O at 0xffffffffffffffff [0x0002]. BAR2: I/O at 0xffffffffffffffff [0x0006]. BAR3: I/O at 0xffffffffffffffff [0x0002]. BAR4: I/O at 0xffffffffffffffff [0x000e]. id ""
Quoted 6 lines
Quoted 4 lines
The BARs are not initialized, so they aren't accessible.
But perhaps the dump was not taken at the point of failure, can you provide a relevant dump if so?
No, this is after failure.
I don't see why the guest expects the BARs to work then.
Signature · 1 line
error compiling committee.c: too many arguments to function
Quoted 16 lines · Avi Kivity
Quoted 15 lines · Blue Swirl
Quoted 15 lines
Quoted 14 lines
This unassigned memory exception is triggered because CMD646 IDE I/O registers are not accessible:
(qemu) info pci
Bus 0, device 5, function 0:
IDE controller: PCI device 1095:0646
IRQ 1.
BAR0: I/O at0xffffffffffffffff[0x0006].
BAR1: I/O at0xffffffffffffffff[0x0002].
BAR2: I/O at0xffffffffffffffff[0x0006].
BAR3: I/O at0xffffffffffffffff[0x0002].
BAR4: I/O at0xffffffffffffffff[0x000e].
id ""
Quoted 8 lines
Quoted 6 lines
Quoted 4 lines
The BARs are not initialized, so they aren't accessible.
But perhaps the dump was not taken at the point of failure, can you provide a relevant dump if so?
No, this is after failure.
I don't see why the guest expects the BARs to work then.
OpenBIOS could initialize them before this commit, now it obviously can't (or initializes the bridges incorrectly).
Maybe also the devices should be moved behind the bridges, that's where they really should be.
Quoted 4 lines
--
error compilingcommittee.c: too many arguments to function
Quoted 22 lines · Blue Swirl
Quoted 21 lines · Avi Kivity
Quoted 20 lines · Blue Swirl
Quoted 19 lines
Quoted 4 lines
This unassigned memory exception is triggered because CMD646 IDE I/O registers are not accessible:
Quoted 10 lines
(qemu) info pci
Bus 0, device 5, function 0:
IDE controller: PCI device 1095:0646
IRQ 1.
BAR0: I/O at0xffffffffffffffff[0x0006].
BAR1: I/O at0xffffffffffffffff[0x0002].
BAR2: I/O at0xffffffffffffffff[0x0006].
BAR3: I/O at0xffffffffffffffff[0x0002].
BAR4: I/O at0xffffffffffffffff[0x000e].
id ""The BARs are not initialized, so they aren't accessible.
But perhaps the dump was not taken at the point of failure, can you provide a relevant dump if so?
Quoted 6 lines
Quoted 3 lines
Quoted 1 line
No, this is after failure.
I don't see why the guest expects the BARs to work then.
OpenBIOS could initialize them before this commit, now it obviously can't (or initializes the bridges incorrectly).
I traced all config reads and writes to the bridge and there's no difference I can see between before and after this commit.
I think there's some other bug, tweaking this specific bit just happens to trigger it.
Quoted 7 lines
Maybe also the devices should be moved behind the bridges, that's where they really should be.
Quoted 4 lines
--
error compilingcommittee.c: too many arguments to function
Quoted 16 lines · Avi Kivity
Quoted 15 lines · Blue Swirl
Quoted 15 lines
Quoted 14 lines
This unassigned memory exception is triggered because CMD646 IDE I/O registers are not accessible:
(qemu) info pci
Bus 0, device 5, function 0:IDE controller: PCI device 1095:0646 IRQ 1. BAR0: I/O at 0xffffffffffffffff [0x0006]. BAR1: I/O at 0xffffffffffffffff [0x0002]. BAR2: I/O at 0xffffffffffffffff [0x0006]. BAR3: I/O at 0xffffffffffffffff [0x0002]. BAR4: I/O at 0xffffffffffffffff [0x000e]. id ""
Quoted 8 lines
Quoted 6 lines
Quoted 4 lines
The BARs are not initialized, so they aren't accessible.
But perhaps the dump was not taken at the point of failure, can you provide a relevant dump if so?
No, this is after failure.
I don't see why the guest expects the BARs to work then.
I don't belive it does - it probably got hang before initializing BARs.
Quoted 2 lines
Signature · 1 line
error compiling committee.c: too many arguments to function
Quoted 22 lines · Michael S. Tsirkin
Quoted 21 lines · Avi Kivity
Quoted 20 lines · Blue Swirl
Quoted 19 lines
Quoted 4 lines
This unassigned memory exception is triggered because CMD646 IDE I/O registers are not accessible:
Quoted 10 lines
(qemu) info pci
Bus 0, device 5, function 0:
IDE controller: PCI device 1095:0646
IRQ 1.
BAR0: I/O at0xffffffffffffffff[0x0006].
BAR1: I/O at0xffffffffffffffff[0x0002].
BAR2: I/O at0xffffffffffffffff[0x0006].
BAR3: I/O at0xffffffffffffffff[0x0002].
BAR4: I/O at0xffffffffffffffff[0x000e].
id ""The BARs are not initialized, so they aren't accessible.
But perhaps the dump was not taken at the point of failure, can you provide a relevant dump if so?
Quoted 6 lines
Quoted 3 lines
Quoted 1 line
No, this is after failure.
I don't see why the guest expects the BARs to work then.
I don't belive it does - it probably got hang before initializing BARs.
This is later, the crash happens when IDE driver is accessing CMD646 registers after the PCI device is configured.
I changed OpenBIOS to disable any bridges with no devices, but that didn't help. It looks like this is not related to bridges, I disabled the secondary bridges with this patch and still there is the crash.
hw/apb_pci.c +6 -1
@@ -256,11 +256,13 @@ static const MemoryRegionOps pci_ioport_ops = { .endianness = DEVICE_NATIVE_ENDIAN, }; +#if 0 /* The APB host has an IRQ line for each IRQ line of each slot. */ static int pci_apb_map_irq (PCIDevice *pci_dev,int irq_num) {return ((pci_dev->devfn &0x18 ) >>1 ) + irq_num; } +#endif static int pci_pbm_map_irq (PCIDevice *pci_dev,int irq_num) {
@@ -322,8 +324,10 @@ PCIBus *pci_apb_init(target_phys_addr_t special_base,SysBusDevice *s;APBState *d;unsigned int i; +#if 0 PCIDevice *pci_dev;PCIBridge *br; +#endif /* Ultrasparc PBM main bus */ dev =qdev_create (NULL ,"pbm" );
@@ -352,6 +356,7 @@ PCIBus *pci_apb_init(target_phys_addr_t special_base,pci_create_simple (d->bus,0 ,"pbm-pci" ); +#if 0 /* APB secondary busses */ pci_dev =pci_create_multifunction (d->bus,PCI_DEVFN (1 ,0 ), true,"pbm-bridge" );
@@ -368,7 +373,7 @@ PCIBus *pci_apb_init(target_phys_addr_t special_base, pci_apb_map_irq);qdev_init_nofail (&pci_dev->qdev); *bus3 =pci_bridge_get_sec_bus (br); - +#endif return d->bus; }
Quoted 3 lines
Quoted 3 lines
--
error compilingcommittee.c: too many arguments to function
Quoted 30 lines · Blue Swirl
Quoted 22 lines · Michael S. Tsirkin
Quoted 21 lines · Avi Kivity
Quoted 20 lines · Blue Swirl
Quoted 19 lines
Quoted 4 lines
This unassigned memory exception is triggered because CMD646 IDE I/O registers are not accessible:
Quoted 10 lines
(qemu) info pci
Bus 0, device 5, function 0:
IDE controller: PCI device 1095:0646
IRQ 1.
BAR0: I/O at0xffffffffffffffff[0x0006].
BAR1: I/O at0xffffffffffffffff[0x0002].
BAR2: I/O at0xffffffffffffffff[0x0006].
BAR3: I/O at0xffffffffffffffff[0x0002].
BAR4: I/O at0xffffffffffffffff[0x000e].
id ""The BARs are not initialized, so they aren't accessible.
But perhaps the dump was not taken at the point of failure, can you provide a relevant dump if so?
Quoted 6 lines
Quoted 3 lines
Quoted 1 line
No, this is after failure.
I don't see why the guest expects the BARs to work then.
I don't belive it does - it probably got hang before initializing BARs.
Quoted 6 lines
This is later, the crash happens when IDE driver is accessing CMD646 registers after the PCI device is configured.
I changed OpenBIOS to disable any bridges with no devices, but that didn't help. It looks like this is not related to bridges, I disabled the secondary bridges with this patch and still there is the crash.
It seems to have to do with the host bridge.
It's unusual to have host bridge present itself
as a pci to pci bridge but there it is.
Quoted 49 lines
hw/apb_pci.c +6
-1@@ -256,11 +256,13 @@ static const MemoryRegionOps pci_ioport_ops = { .endianness = DEVICE_NATIVE_ENDIAN, }; +#if 0 /* The APB host has an IRQ line for each IRQ line of each slot. */ static int pci_apb_map_irq (PCIDevice *pci_dev,int irq_num) {return ((pci_dev->devfn &0x18 ) >>1 ) + irq_num; } +#endif static int pci_pbm_map_irq (PCIDevice *pci_dev,int irq_num) {@@ -322,8 +324,10 @@ PCIBus *pci_apb_init(target_phys_addr_t special_base,SysBusDevice *s;APBState *d;unsigned int i; +#if 0 PCIDevice *pci_dev;PCIBridge *br; +#endif /* Ultrasparc PBM main bus */ dev =qdev_create (NULL ,"pbm" );@@ -352,6 +356,7 @@ PCIBus *pci_apb_init(target_phys_addr_t special_base,pci_create_simple (d->bus,0 ,"pbm-pci" ); +#if 0 /* APB secondary busses */ pci_dev =pci_create_multifunction (d->bus,PCI_DEVFN (1 ,0 ), true,"pbm-bridge" );@@ -368,7 +373,7 @@ PCIBus *pci_apb_init(target_phys_addr_t special_base, pci_apb_map_irq);qdev_init_nofail (&pci_dev->qdev); *bus3 =pci_bridge_get_sec_bus (br); - +#endif return d->bus; }Quoted 3 lines
Quoted 3 lines
--
error compilingcommittee.c: too many arguments to function
Quoted 34 lines · Michael S. Tsirkin
Quoted 33 lines · Blue Swirl
Quoted 22 lines · Michael S. Tsirkin
Quoted 21 lines · Avi Kivity
Quoted 20 lines · Blue Swirl
Quoted 19 lines
Quoted 4 lines
This unassigned memory exception is triggered because CMD646 IDE I/O registers are not accessible:
Quoted 10 lines
(qemu) info pci
Bus 0, device 5, function 0:
IDE controller: PCI device 1095:0646
IRQ 1.
BAR0: I/O at0xffffffffffffffff[0x0006].
BAR1: I/O at0xffffffffffffffff[0x0002].
BAR2: I/O at0xffffffffffffffff[0x0006].
BAR3: I/O at0xffffffffffffffff[0x0002].
BAR4: I/O at0xffffffffffffffff[0x000e].
id ""The BARs are not initialized, so they aren't accessible.
But perhaps the dump was not taken at the point of failure, can you provide a relevant dump if so?
Quoted 6 lines
Quoted 3 lines
Quoted 1 line
No, this is after failure.
I don't see why the guest expects the BARs to work then.
I don't belive it does - it probably got hang before initializing BARs.
This is later, the crash happens when IDE driver is accessing CMD646 registers after the PCI device is configured.
Quoted 7 lines
Quoted 3 lines
I changed OpenBIOS to disable any bridges with no devices, but that didn't help. It looks like this is not related to bridges, I disabled the secondary bridges with this patch and still there is the crash.
It seems to have to do with the host bridge.
It's unusual to have host bridge present itself
as a pci to pci bridge but there it is.
It looks like the I/O base calculations in OpenBIOS are confused by host bridge, after that all BARs are wrong. OpenBIOS also thinks that the host bridge is a device and attempts to configure six BARs instead of two.
Quoted 49 lines
Quoted 49 lines
hw/apb_pci.c +6
-1@@ -256,11 +256,13 @@ static const MemoryRegionOps pci_ioport_ops = { .endianness = DEVICE_NATIVE_ENDIAN, }; +#if 0 /* The APB host has an IRQ line for each IRQ line of each slot. */ static int pci_apb_map_irq(PCIDevice *pci_dev, int irq_num) { return ((pci_dev->devfn & 0x18) >> 1) + irq_num; } +#endif static int pci_pbm_map_irq(PCIDevice *pci_dev, int irq_num) {@@ -322,8 +324,10 @@ PCIBus *pci_apb_init(target_phys_addr_t special_base, SysBusDevice *s; APBState *d; unsigned int i; +#if 0 PCIDevice *pci_dev; PCIBridge *br; +#endif /* Ultrasparc PBM main bus */ dev = qdev_create(NULL, "pbm");@@ -352,6 +356,7 @@ PCIBus *pci_apb_init(target_phys_addr_t special_base, pci_create_simple(d->bus, 0, "pbm-pci"); +#if 0 /* APB secondary busses */ pci_dev = pci_create_multifunction(d->bus, PCI_DEVFN(1, 0), true, "pbm-bridge");@@ -368,7 +373,7 @@ PCIBus *pci_apb_init(target_phys_addr_t special_base, pci_apb_map_irq); qdev_init_nofail(&pci_dev->qdev); *bus3 = pci_bridge_get_sec_bus(br); - +#endif return d->bus; }Quoted 3 lines
Quoted 3 lines
--
error compilingcommittee.c: too many arguments to function
Quoted 5 lines · Blue Swirl
Quoted 3 lines
It seems to have to do with the host bridge.
It's unusual to have host bridge present itself
as a pci to pci bridge but there it is.It looks like the I/O base calculations in OpenBIOS are confused
Where's the source for that, BTW? Have build instructions?
Quoted 4 lines
by
host bridge, after that all BARs are wrong. OpenBIOS also thinks that the host bridge is a device and attempts to configure six BARs instead of two.
According to the spec it is a device, so should be ok? If I just make BAR4 writeable we get past the bios screen at least.
Maybe openbios gets confused if a device has no BARs? Do things work for you with the patch below? All it does is make BAR4 writeable, accesses go nowhere.
hw/apb_pci.c +1 -1
@@ -433,6 +433,7 @@ static int pbm_pci_host_init(PCIDevice *d)pci_set_word (d->config +PCI_STATUS ,PCI_STATUS_FAST_BACK |PCI_STATUS_66MHZ |PCI_STATUS_DEVSEL_MEDIUM ); +pci_set_long (d->wmask +0x20 ,0xfffffff0 );return 0 ; }
@@ -444,7 +445,6 @@ static void pbm_pci_host_class_init(ObjectClass *klass, void *data) k->vendor_id =PCI_VENDOR_ID_SUN ; k->device_id =PCI_DEVICE_ID_SUN_SABRE ; k->class_id =PCI_CLASS_BRIDGE_HOST ; - k->is_bridge =1 ; }static TypeInfo pbm_pci_host_info = {
Signature · 1 line
MST
Quoted 8 lines · Michael S. Tsirkin
Quoted 5 lines · Blue Swirl
Quoted 3 lines
It seems to have to do with the host bridge.
It's unusual to have host bridge present itself
as a pci to pci bridge but there it is.It looks like the I/O base calculations in OpenBIOS are confused
Where's the source for that, BTW? Have build instructions?
Under roms/openbios or www.openbios.org. You need xsltproc. ../config/scripts/switch-arch sparc64
make build-verbose
qemu-system-sparc64 -bios obj-sparc64/openbios-builtin.elf.nostrip
Quoted 11 lines
Quoted 4 lines
by
host bridge, after that all BARs are wrong. OpenBIOS also thinks that the host bridge is a device and attempts to configure six BARs instead of two.According to the spec it is a device, so should be ok? If I just make BAR4 writeable we get past the bios screen at least.
Maybe openbios gets confused if a device has no BARs? Do things work for you with the patch below? All it does is make BAR4 writeable, accesses go nowhere.
Looking at serial console, there is no crash, but VGA still does not work.
Quoted 24 lines
hw/apb_pci.c +0
-0@@ -433,6 +433,7 @@ static int pbm_pci_host_init(PCIDevice *d) pci_set_word(d->config + PCI_STATUS,PCI_STATUS_FAST_BACK |
PCI_STATUS_66MHZ|PCI_STATUS_DEVSEL_MEDIUM);
+ pci_set_long(d->wmask +0x20,0xfffffff0); return 0;
}hw/apb_pci.c +0
-2@@ -444,7 +445,6 @@ static void pbm_pci_host_class_init(ObjectClass *klass, void *data) k->vendor_id = PCI_VENDOR_ID_SUN; k->device_id = PCI_DEVICE_ID_SUN_SABRE; k->class_id = PCI_CLASS_BRIDGE_HOST; - k->is_bridge = 1; } static TypeInfo pbm_pci_host_info = { --MST
Quoted 8 lines · Blue Swirl
Quoted 6 lines
According to the spec it is a device, so should be ok? If I just make BAR4 writeable we get past the bios screen at least.
Maybe openbios gets confused if a device has no BARs? Do things work for you with the patch below? All it does is make BAR4 writeable, accesses go nowhere.Looking at serial console, there is no crash, but VGA still does not work.
Note that I've just emailed the list about a VGA regression I've found on PPC caused by one of Avi's commits - perhaps Michael's fix does work, but you're being bitten by the same bug?
ATB,
Mark.
Quoted 11 lines · Mark Cave-Ayland
Quoted 8 lines · Blue Swirl
Quoted 6 lines
According to the spec it is a device, so should be ok? If I just make BAR4 writeable we get past the bios screen at least.
Maybe openbios gets confused if a device has no BARs? Do things work for you with the patch below? All it does is make BAR4 writeable, accesses go nowhere.Looking at serial console, there is no crash, but VGA still does not work.
Quoted 8 lines
Note that I've just emailed the list about a VGA regression I've found on PPC caused by one of Avi's commits - perhaps Michael's fix does work, but you're being bitten by the same bug?
ATB,
Mark.
It's not a fix as such - just a hack to see what makes bios crash.
Signature · 1 line
MST
Quoted 11 lines · Mark Cave-Ayland
Quoted 8 lines · Blue Swirl
Quoted 6 lines
According to the spec it is a device, so should be ok? If I just make BAR4 writeable we get past the bios screen at least.
Maybe openbios gets confused if a device has no BARs? Do things work for you with the patch below? All it does is make BAR4 writeable, accesses go nowhere.Looking at serial console, there is no crash, but VGA still does not work.
Quoted 8 lines
Note that I've just emailed the list about a VGA regression I've found on PPC caused by one of Avi's commits - perhaps Michael's fix does work, but you're being bitten by the same bug?
ATB,
Mark.
Can you pls try applying my patch on top of old tree where VGA did work, and see what happens?
Signature · 1 line
MST
Quoted 6 lines · Blue Swirl
Quoted 5 lines · Michael S. Tsirkin
Quoted 4 lines · Blue Swirl
Quoted 3 lines
It seems to have to do with the host bridge.
It's unusual to have host bridge present itself
as a pci to pci bridge but there it is.
Quoted 8 lines
Quoted 3 lines
Quoted 1 line
It looks like the I/O base calculations in OpenBIOS are confused
Where's the source for that, BTW? Have build instructions?
Under roms/openbios or www.openbios.org. You need xsltproc. ../config/scripts/switch-arch sparc64
make build-verbose
qemu-system-sparc64 -bios obj-sparc64/openbios-builtin.elf.nostrip
I don't see anything obviously wrong in there, but the behaviour does seem to indicate some firmware bug ... I don't have the right toolchain - care debugging?
Quoted 5 lines
Quoted 5 lines
Quoted 4 lines
by
host bridge, after that all BARs are wrong. OpenBIOS also thinks that the host bridge is a device and attempts to configure six BARs instead of two.
Quoted 8 lines
Quoted 6 lines
According to the spec it is a device, so should be ok? If I just make BAR4 writeable we get past the bios screen at least.
Maybe openbios gets confused if a device has no BARs? Do things work for you with the patch below? All it does is make BAR4 writeable, accesses go nowhere.Looking at serial console, there is no crash, but VGA still does not work.
What do info pci/ifo mtree show now?
Quoted 24 lines
Quoted 24 lines
hw/apb_pci.c +0
-0@@ -433,6 +433,7 @@ static int pbm_pci_host_init(PCIDevice *d) pci_set_word(d->config + PCI_STATUS,PCI_STATUS_FAST_BACK |
PCI_STATUS_66MHZ|PCI_STATUS_DEVSEL_MEDIUM);
+ pci_set_long(d->wmask +0x20,0xfffffff0); return 0;
}hw/apb_pci.c +0
-2@@ -444,7 +445,6 @@ static void pbm_pci_host_class_init(ObjectClass *klass, void *data) k->vendor_id = PCI_VENDOR_ID_SUN; k->device_id = PCI_DEVICE_ID_SUN_SABRE; k->class_id = PCI_CLASS_BRIDGE_HOST; - k->is_bridge = 1; } static TypeInfo pbm_pci_host_info = { --MST
Quoted 28 lines · Blue Swirl
Quoted 14 lines · Michael S. Tsirkin
commit
5caef97a16010f818ea8b950e2ee24ba876643adintroduced
a regression: we do not make IO base/limit upper 16
bit registers writeable, so we should report a 16 bit
IO range type, not a 32 bit one.
Note thatPCI_PREF_RANGE_TYPE_32is0x0, butPCI_IO_RANGE_TYPE_32is0x1.In particular, this broke sparc64.
Note: this just reverts to behaviour prior to the patch. Making
PCI_IO_BASE_UPPER16andPCI_IO_LIMIT_UPPER16registers writeable should, and seems to, work just as well, but as no system seems to actually be interested in 32 bit IO, let's not make unnecessary changes.Quoted 4 lines
Reported-by Mark Cave-Ayland <[email protected]>Signed-off-by Michael S. Tsirkin <[email protected]>Mark, can you confirm that this fixes the bug for you?
No, running
qemu-system-sparc64 -serial stdio
still shows black screen and the following on console:
OpenBIOS for Sparc64
Unhandled Exception0x0000000000000032
PC =0x00000000ffd19e18NPC =0x00000000ffd19e1cStopping execution
Quoted 2 lines
This unassigned memory exception is triggered because CMD646 IDE I/O registers are not accessible:
So here's a theory: the issue is that both device IO and bridge IO have the same priority.
Bridge is initialized with IO at 0 to 4K
and so we have two devices at the same priority. And flipping a type bit affects this, by chance?
I tried the following and it seems to help.
But the real fix IMO is to either disable the bridge ranges at reset, in hardware, or have the BIOS do this.
Avi, could you pls comment on my analysis?
hw/pci.c +1 -1
@@ -986,7 +986,7 @@ static void pci_update_mappings(PCIDevice *d) r->addr = new_addr;if (r->addr !=PCI_BAR_UNMAPPED ) {memory_region_add_subregion_overlap (r->address_space, - r->addr, r->memory,1 ); + r->addr, r->memory,2 ); } } }
Quoted 49 lines · Michael S. Tsirkin
Quoted 28 lines · Blue Swirl
Quoted 14 lines · Michael S. Tsirkin
commit
5caef97a16010f818ea8b950e2ee24ba876643adintroduced
a regression: we do not make IO base/limit upper 16
bit registers writeable, so we should report a 16 bit
IO range type, not a 32 bit one.
Note thatPCI_PREF_RANGE_TYPE_32is0x0, butPCI_IO_RANGE_TYPE_32is0x1.In particular, this broke sparc64.
Note: this just reverts to behaviour prior to the patch. Making
PCI_IO_BASE_UPPER16andPCI_IO_LIMIT_UPPER16registers writeable should, and seems to, work just as well, but as no system seems to actually be interested in 32 bit IO, let's not make unnecessary changes.Quoted 4 lines
Reported-by Mark Cave-Ayland <[email protected]>Signed-off-by Michael S. Tsirkin <[email protected]>Mark, can you confirm that this fixes the bug for you?
No, running
qemu-system-sparc64 -serial stdio
still shows black screen and the following on console:
OpenBIOS for Sparc64
Unhandled Exception0x0000000000000032
PC =0x00000000ffd19e18NPC =0x00000000ffd19e1cStopping executionQuoted 2 lines
This unassigned memory exception is triggered because CMD646 IDE I/O registers are not accessible:
So here's a theory: the issue is that both device IO and bridge IO have the same priority.
Bridge is initialized with IO at 0 to 4K
and so we have two devices at the same priority. And flipping a type bit affects this, by chance?I tried the following and it seems to help.
But the real fix IMO is to either disable the bridge ranges at reset, in hardware, or have the BIOS do this.Avi, could you pls comment on my analysis?
hw/pci.c +0
-0
hw/pci.c static void pci_update_mappings(PCIDevice *d) · line 992
Quoted 8 lines
hw/pci.c +1
-1@@ -986,7 +986,7 @@ static void pci_update_mappings(PCIDevice *d) r->addr = new_addr;if (r->addr !=PCI_BAR_UNMAPPED ) {memory_region_add_subregion_overlap (r->address_space, - r->addr, r->memory,1 ); + r->addr, r->memory,2 ); } } }
Grr. Scap the above, the patch does nothing, I didn't test it right.
Quoted 29 lines · Michael S. Tsirkin
Quoted 28 lines · Blue Swirl
Quoted 14 lines · Michael S. Tsirkin
commit
5caef97a16010f818ea8b950e2ee24ba876643adintroduced
a regression: we do not make IO base/limit upper 16
bit registers writeable, so we should report a 16 bit
IO range type, not a 32 bit one.
Note thatPCI_PREF_RANGE_TYPE_32is0x0, butPCI_IO_RANGE_TYPE_32is0x1.In particular, this broke sparc64.
Note: this just reverts to behaviour prior to the patch. Making
PCI_IO_BASE_UPPER16andPCI_IO_LIMIT_UPPER16registers writeable should, and seems to, work just as well, but as no system seems to actually be interested in 32 bit IO, let's not make unnecessary changes.Quoted 4 lines
Reported-by Mark Cave-Ayland <[email protected]>Signed-off-by Michael S. Tsirkin <[email protected]>Mark, can you confirm that this fixes the bug for you?
No, running
qemu-system-sparc64 -serial stdio
still shows black screen and the following on console:
OpenBIOS for Sparc64
Unhandled Exception0x0000000000000032
PC =0x00000000ffd19e18NPC =0x00000000ffd19e1cStopping execution
Quoted 8 lines
Quoted 2 lines
This unassigned memory exception is triggered because CMD646 IDE I/O registers are not accessible:
So here's a theory: the issue is that both device IO and bridge IO have the same priority.
Bridge is initialized with IO at 0 to 4K
and so we have two devices at the same priority. And flipping a type bit affects this, by chance?
What device shares its BAR with the bridge I/O window?
Quoted 11 lines
I tried the following and it seems to help.
But the real fix IMO is to either disable the bridge ranges at reset, in hardware, or have the BIOS do this.Avi, could you pls comment on my analysis?
hw/pci.c +0
-0
hw/pci.c static void pci_update_mappings(PCIDevice *d) · line 992
Quoted 8 lines
hw/pci.c +1
-1@@ -986,7 +986,7 @@ static void pci_update_mappings(PCIDevice *d) r->addr = new_addr;if (r->addr !=PCI_BAR_UNMAPPED ) {memory_region_add_subregion_overlap (r->address_space, - r->addr, r->memory,1 ); + r->addr, r->memory,2 ); } } }
Who says a BAR has higher priority than a bridge?
Signature · 1 line
error compiling committee.c: too many arguments to function
Quoted 38 lines · Michael S. Tsirkin
Quoted 28 lines · Blue Swirl
Quoted 14 lines · Michael S. Tsirkin
commit
5caef97a16010f818ea8b950e2ee24ba876643adintroduced
a regression: we do not make IO base/limit upper 16
bit registers writeable, so we should report a 16 bit
IO range type, not a 32 bit one.
Note thatPCI_PREF_RANGE_TYPE_32is0x0, butPCI_IO_RANGE_TYPE_32is0x1.In particular, this broke sparc64.
Note: this just reverts to behaviour prior to the patch. Making
PCI_IO_BASE_UPPER16andPCI_IO_LIMIT_UPPER16registers writeable should, and seems to, work just as well, but as no system seems to actually be interested in 32 bit IO, let's not make unnecessary changes.Quoted 4 lines
Reported-by Mark Cave-Ayland <[email protected]>Signed-off-by Michael S. Tsirkin <[email protected]>Mark, can you confirm that this fixes the bug for you?
No, running
qemu-system-sparc64 -serial stdio
still shows black screen and the following on console:
OpenBIOS for Sparc64
Unhandled Exception0x0000000000000032
PC =0x00000000ffd19e18NPC =0x00000000ffd19e1cStopping executionQuoted 2 lines
This unassigned memory exception is triggered because CMD646 IDE I/O registers are not accessible:
So here's a theory: the issue is that both device IO and bridge IO have the same priority.
Bridge is initialized with IO at 0 to 4K
and so we have two devices at the same priority. And flipping a type bit affects this, by chance?
Quoted 3 lines
I tried the following and it seems to help.
But the real fix IMO is to either disable the bridge ranges at reset, in hardware, or have the BIOS do this.
I'd suppose bridge ranges should be disabled at reset. BIOS should probably also program the bridge ranges so that only devices behind the bridge are visible, or if no devices exist, disable the bridge completely. It's possible that all of these could be buggy and the original commit could be correct.
Quoted 15 lines
Avi, could you pls comment on my analysis?
hw/pci.c +1
-1@@ -986,7 +986,7 @@ static void pci_update_mappings(PCIDevice *d) r->addr = new_addr; if (r->addr != PCI_BAR_UNMAPPED) { memory_region_add_subregion_overlap(r->address_space, - r->addr, r->memory, 1); + r->addr, r->memory, 2); } } }