Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 13 Sep 2015 04:21:43 +0200
From:      Marius Strobl <marius@alchemy.franken.de>
To:        Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Cc:        Alexey Dokuchaev <danfe@FreeBSD.org>, "freebsd-sparc64@freebsd.org" <freebsd-sparc64@freebsd.org>
Subject:   Re: PCI range checking under qemu-system-sparc64
Message-ID:  <20150913022143.GA7862@alchemy.franken.de>
In-Reply-To: <55EDFE00.9090109@ilande.co.uk>
References:  <557D82F8.50908@ilande.co.uk> <557DA6D5.4070800@FreeBSD.org> <557DCF54.7020606@ilande.co.uk> <A88F6A52-FA8A-4669-A2D6-23374F8E26BB@FreeBSD.org> <557DF887.20508@ilande.co.uk> <20150906110308.GA68829@FreeBSD.org> <55EC2E8D.4020803@ilande.co.uk> <20150906124859.GA14919@FreeBSD.org> <20150907203152.GA70457@alchemy.franken.de> <55EDFE00.9090109@ilande.co.uk>

next in thread | previous in thread | raw e-mail | index | archive | help

--3MwIy2ne0vdjdPXF
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

On Mon, Sep 07, 2015 at 10:13:36PM +0100, Mark Cave-Ayland wrote:
> On 07/09/15 21:31, Marius Strobl wrote:
> 
> > On Sun, Sep 06, 2015 at 12:48:59PM +0000, Alexey Dokuchaev wrote:
> >> On Sun, Sep 06, 2015 at 01:16:13PM +0100, Mark Cave-Ayland wrote:
> >>> On 06/09/15 12:03, Alexey Dokuchaev wrote:
> >>>> Mark did you have any success with getting the boot process further?
> >>>
> >>> Not really - due to changes with my job and involvment in GSoC this year
> >>> then my QEMU SPARC64 work hasn't really progressed much :(
> >>>
> >>> I don't have my FreeBSD environment setup right now (due to OS upgrade)
> >>> but can you post the console output for the boot as far as it gets with
> >>> the current version of the patch applied?
> >>
> >> Last few lines:
> >>
> >>   [...]
> >>   eeprom0: <EEPROM/clock> addr 0x1400002000-0x1400003fff on ebus0
> >>   eeprom0: cannot allocate resources
> >>   device_attach: eeprom0 attach returned 6
> >>   ebus0: <fdthree> addr 0 (no driver attached)
> >>   ebus0: <su> addr 0x14000003f8-0x14000003ff irq 43 (no driver attached)
> > 
> > This suggests that there's something wrong with the emulation of
> > the PCI-EBus-bridge (child space maps to a region not covered by
> > the BARs, child space not covered by the mapping, wrong resource
> > type in the ranges table or something like that), causing the
> > allocation of child resources to fail as in the eeprom(4) case
> > above. Such a problem would also explain why uart(4) doesn't try
> > to attach to 'su' albeit it should: uart_bus_probe() already
> > allocates the resource, failing silently if that doesn't work
> > and, thus, causing uart_bus_attach() never to be called.
> > 
> >> Full log available here:
> >>
> >> 	http://193.124.210.26/head-r287497-sparc64-qemu.log
> >>
> >> ebus0: <PCI-EBus2 bridge> port 0x4000-0x7fff mem 0x3000000-0x3ffffff at device 3.0 on pci0
> > 
> > That's already unusual; real PCI-EBus-bridges have two memory
> > BARs (although children may use I/O ports which are translated
> > to memory resources upstream) rather than an I/O port and a
> > memory one. However, the above actually should also work code-
> > wise, iff the resource types are encoded correctly in the ranges
> > table.
> 
> While the QEMU PCI-ebus properties don't necessarily reflect a real
> ultra2

You probably mean Ultra5/10 here; Ultra2 are SBus- rather than PCI-
based. Still, the machine QEMU emualtes only looks similar to a
real Ultra5/10 from a 10 km distance ...

>, they should be consistent in terms of ranges as several patches
> along those lines were required to enable NetBSD and OpenBSD to boot
> under qemu-system-sparc64. For reference I've included the properties
> from OpenBIOS below:
> 
> 
> 0 > cd /pci/  ok
> 0 > .properties
> name                      "pci"
> reg                       000001fe 00000000   00000000 02000000
> vendor-id                 108e
> device-id                 a000
> revision-id               0
> class-code                60000
> min-grant                 0
> max-latency               0
> devsel-speed              0
> fast-back-to-back         <empty>
> 66mhz-capable             <empty>
> subsystem-vendor-id       1af4
> subsystem-id              1100
> cache-line-size           0
> device_type               "pci"
> model                     "SUNW,sabre"
> compatible                {"pci108e,a000", "pciclass,0"}
> #address-cells            3
> #size-cells               2
> #interrupt-cells          1
> ranges                    -- 54 : 00 00 00 00 00 00 00 00 00 00 00 00 00
> 00 01 fe 01 00 00 00 00 00 00 00 02 00 00 00 01 00 00 00 00 00 00 00 00
> 00 00 00 00 00 01 fe 02 00 00 00 00 00 00 00 00 01 00 00 02 00 00 00 00
> 00 00 00 00 10 00 00 00 00 01 ff 00 10 00 00 00 00 00 00 10 00 00 00
> virtual-dma               -- 8 : c0 00 00 00 20 00 00 00
> #virtual-dma-size-cells   1
> #virtual-dma-addr-cells   1
> no-streaming-cache        <empty>
> interrupts                -- 10 : 00 00 07 f0 00 00 07 ee 00 00 07 ef 00
> 00 07 e5
> upa-portid                1f
> bus-range                 -- 8 : 00 00 00 00 00 00 00 02
> available                 -- 28 : 02 00 00 00 00 00 00 00 04 04 00 00 00
> 00 00 00 0b fc 00 00 01 00 00 00 00 00 00 00 00 00 83 80 00 00 00 00 00
> 00 7c 80
> interrupt-map             -- 30 : 00 00 20 00 00 00 00 00 00 00 00 00 00
> 00 00 01 ff e2 b7 40 00 00 00 10 00 00 28 00 00 00 00 00 00 00 00 00 00
> 00 00 01 ff e2 b7 40 00 00 00 14
> interrupt-map-mask        -- 10 : 00 00 f8 00 00 00 00 00 00 00 00 00 00
> 00 00 07
>  ok
> 0 > cd ebus  ok
> 0 > .properties
> name                      "ebus"
> vendor-id                 108e
> device-id                 1000
> revision-id               1
> class-code                68000
> min-grant                 0
> max-latency               0
> devsel-speed              0
> fast-back-to-back         <empty>
> 66mhz-capable             <empty>
> subsystem-vendor-id       1af4
> subsystem-id              1100
> cache-line-size           a00
> model                     "ebus"
> compatible                {"pci108e,1000", "pciclass,068000"}
> #address-cells            2
> #size-cells               1
> #interrupt-cells          1
> assigned-addresses        -- 28 : 02 00 18 10 00 00 00 00 03 00 00 00 00
> 00 00 00 01 00 00 00 01 00 18 14 00 00 00 00 00 00 40 00 00 00 00 00 00
> 00 40 00
> reg                       00001800 00000000 00000000   00000000 00000000
>                           02001810 00000000 00000000   00000000 01000000
>                           01001814 00000000 00000000   00000000 00004000
> interrupt-map             -- 14 : 00 00 00 14 00 00 03 f8 00 00 00 01 ff
> e1 b9 48 00 00 00 2b
> interrupt-map-mask        -- c : 00 00 01 ff ff ff ff ff 00 00 00 03
> ranges                    -- 30 : 00 00 00 10 00 00 00 00 02 00 18 10 00
> 00 00 00 00 00 00 00 01 00 00 00 00 00 00 14 00 00 00 00 01 00 18 14 00
> 00 00 00 00 00 00 00 00 00 40 00
>  ok
> 0 > cd su  ok
> 0 > .properties
> name                      "su"
> device_type               "serial"
> reg                       00000014 000003f8   00000008
> interrupts                1
>  ok
> 

Okay, so the address of "su" actually is mapped to the I/O port space
at the EBus bridge. Again that doesn't match any real machine but at
least is consistent with the BAR setup QEMU employs on the PCI side.

> 
> I wonder if the problem is the same as that in
> https://reviews.freebsd.org/D2791 which is that some assumptions about
> the device tree are hard-coded rather than being read and/or calculated
> from the PROM properties?
> 

The first generations of PCI-based sun4u machines don't adhere to
the IEEE 1754-1994 bus binding specifications (on the other hand,
I only ever got draft versions of these so I've no idea whether
they went final). E450 are worst in that regard, closely followed
by Ultra30. To that matter, even the interpretation of the ranges
property for the PCI-ISA-bridges found in PCI-Express-based sun4u
machines still doesn't follow the relevant bus binding document.
Thus, assuming the behavior of real hardware built by Fujitsu and
Sun - which includes distrusting knowingly incorrect OFW properties
in quite a few occasions - in sparc64 bus code rather than basing
it on the OFW standards generally is sane.
That said, later device-tree-related code in FreeBSD/sparc64 is
rather generic and has quite a few heuristics, which made things
work out-of-the box on several models we didn't have access to
ourselves. Actually, in some cases FreeBSD performed even better
than Linux, Net- and OpenBSD did in that regard, i. e. while these
latter needed changes, FreeBSD required none. This also is why -
apparently - the FreeBSD kernel manages to attach the 16550 of
QEMU as low-level console device, although the BAR layout of the
PCI-EBus-bridge doesn't match any real hardware.

However, looking at ebus(4), I've spotted a bug in the conversion
to NEW_PCIB. Interested parties might want to give the attached
patch a try. That bug definitely can lead to the problem seen with
QEMU, I'm not sure it's the only one in that regard, though; I'm
fairly certain in this case there's no problem with interpreting
the device-tree involved, given that the same code is used for
ISA busses which - at least in reality - unlike EBus ones use
I/O port instead of memory space for the resources of devices
such as UARTs etc. There could be other spots not prepared for
EBus devices suddenly requesting SYS_RES_IOPORT, too, though.

Marius


--3MwIy2ne0vdjdPXF
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="sparc64_NEW_PCIB.diff_fix"

Index: ebus.c
===================================================================
--- ebus.c	(revision 287726)
+++ ebus.c	(working copy)
@@ -69,7 +69,6 @@ __FBSDID("$FreeBSD$");
 #include <sys/kernel.h>
 #include <sys/malloc.h>
 #include <sys/module.h>
-
 #include <sys/rman.h>
 
 #include <dev/ofw/ofw_bus.h>
@@ -507,7 +506,7 @@ ebus_activate_resource(device_t bus, device_t chil
 	int i, rv;
 
 	sc = device_get_softc(bus);
-	if ((sc->sc_flags & EBUS_PCI) != 0 && type == SYS_RES_MEMORY) {
+	if ((sc->sc_flags & EBUS_PCI) != 0 && type != SYS_RES_IRQ) {
 		for (i = 0; i < sc->sc_nrange; i++) {
 			eri = &sc->sc_rinfo[i];
 			if (rman_is_region_manager(res, &eri->eri_rman) != 0) {
@@ -550,7 +549,7 @@ ebus_release_resource(device_t bus, device_t child
 	passthrough = (device_get_parent(child) != bus);
 	rl = BUS_GET_RESOURCE_LIST(bus, child);
 	sc = device_get_softc(bus);
-	if ((sc->sc_flags & EBUS_PCI) != 0 && type == SYS_RES_MEMORY) {
+	if ((sc->sc_flags & EBUS_PCI) != 0 && type != SYS_RES_IRQ) {
 		if ((rman_get_flags(res) & RF_ACTIVE) != 0 ){
 			rv = bus_deactivate_resource(child, type, rid, res);
 			if (rv != 0)

--3MwIy2ne0vdjdPXF--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20150913022143.GA7862>