Bug 131371 - [panic] 7.1-R sparc64 panics on boot on Tatung U4MP
Summary: [panic] 7.1-R sparc64 panics on boot on Tatung U4MP
Status: Closed FIXED
Alias: None
Product: Base System
Classification: Unclassified
Component: sparc64 (show other bugs)
Version: 7.1-RELEASE
Hardware: Any Any
: Normal Affects Only Me
Assignee: freebsd-sparc64 (Nobody)
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2009-02-04 17:20 UTC by Rory Arms
Modified: 2009-03-22 21:57 UTC (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Rory Arms 2009-02-04 17:20:01 UTC
Just decided to try installing FreeBSD/sparc64 on a Tatung U4MP

The U4MP is a rackmount is based on the SUN SPARCengine UltraAXmp+ system board. This one has dual UltraSPARC II 450 MHz processors and 2048 MiB of RAM.

I decided to netboot FreeBSD right from a CD image on a server, via OPB.

Here's the log of the bootup with some POST output prior to kernel bootstrap:

UltraAX-MP+ WorkServer (2 X UltraSPARC-II 448MHz), No Keyboard
OpenBoot 3.10.50 ME, 2048 MB memory installed, Serial #15728707.
Ethernet address 8:0:20:f0:0:43, Host ID: 80f00043.


Initializing1024 megs of memory at addr                 0 897
Software Power ON

CPU0 has assumed the role of Boot CPU

@(#) UltraAX-MP+ WorkServer  3.10.50 ME created 1999/09/13 14:38
Online:  CPU0  UltraSPARC-II (v10.0) 5:1 4096KB 2-2 ECache MCap 10
Online:  CPU1  UltraSPARC-II (v10.0) 5:1 4096KB 2-2 ECache MCap 10
Offline: CPU2
Offline: CPU3
Enter Checking KB
ps/2 kbd check: 0000.0000.0000.00fe
Checking Sun KB
Marvin SC Dtag SRAM supports upto 8192KB of ECache
Setting system ECache size to 4096KB
Clearing DTAGS...Done
Clearing E-Cache Tags...Done
Clearing I/D TLBs...Done
Probing Memory...
memory @ 0000.0000.0000.0000 :    128   128   128   128   128   128   128   128
memory @ 0000.0000.4000.0000 :    X   X   X   X   X   X   X   X
memory @ 0000.0000.8000.0000 :    128   128   128   128   128   128   128   128
memory @ 0000.0000.c000.0000 :    X   X   X   X   X   X   X   X
Done
MEM BASE = 0000.0000.8000.0000
MEM SIZE = 0000.0000.4000.0000
Clearing Memory...Done
MMUs ON
Copying ROM to RAM...Done
ROM PC = 0000.01ff.f000.4730
Dcmpesig noMmry.000.00.00045a4 29KB..Doe
Satn oth krel t00.00f057d
ttya initialized
SC Control: EWP:0 IAP:0 FATAL:0 WAKEUP:0 BXIR:0 BPOR:0 SXIR:0 SPOR:1 POR:0
Probing Memory Bank #0 128 128 128 128 128 128 128 128 : 1024 Megabytes
Probing Memory Bank #1   0   0   0   0   0   0   0   0 :   0 Megabytes
Probing Memory Bank #2 128 128 128 128 128 128 128 128 : 1024 Megabytes
Probing Memory Bank #3   0   0   0   0   0   0   0   0 :   0 Megabytes
Setting 60ns memory timings

Environmental monitoring:  Disabled
i2c adc adc adc gpio gpio
Probing Floppy: No drives detected
Probing UPA slots...
UPA slot 0  cpu
UPA slot 1  cpu
UPA slot 4  pci pci
UPA slot 1f  pci pci
Probing /pci@1f,4000 at Device 1  network
Probing /pci@1f,4000 at Device 2  Nothing there
Probing /pci@1f,4000 at Device 3  Nothing there
Probing /pci@1f,4000 at Device 4  Nothing there
Probing /pci@1f,2000 at Device 1  Nothing there
Probing /pci@4,4000 at Device 6  scsi disk tape scsi disk tape
Probing /pci@4,4000 at Device 2  SUNW,m64Pro
Probing /pci@4,4000 at Device 3  Nothing there
Probing /pci@4,4000 at Device 4  Nothing there
Probing /pci@4,4000 at Device 5  Nothing there
Probing /pci@4,2000 at Device 1  Nothing there
SC Control: EWP:0 IAP:0 FATAL:0 WAKEUP:0 BXIR:0 BPOR:0 SXIR:0 SPOR:1 POR:0
Probing Memory Bank #0 128 128 128 128 128 128 128 128 : 1024 Megabytes
Probing Memory Bank #1   0   0   0   0   0   0   0   0 :   0 Megabytes
Probing Memory Bank #2 128 128 128 128 128 128 128 128 : 1024 Megabytes
Probing Memory Bank #3   0   0   0   0   0   0   0   0 :   0 Megabytes
Setting 60ns memory timings

Environmental monitoring:  Disabled
i2c adc adc adc gpio gpio
Probing Floppy: No drives detected
Probing UPA slots...
UPA slot 0  cpu
UPA slot 1  cpu
UPA slot 4  pci pci
UPA slot 1f  pci pci
Probing /pci@1f,4000 at Device 1  network
Probing /pci@1f,4000 at Device 2  Nothing there
Probing /pci@1f,4000 at Device 3  Nothing there
Probing /pci@1f,4000 at Device 4  Nothing there
Probing /pci@1f,2000 at Device 1  Nothing there
Probing /pci@4,4000 at Device 6  scsi disk tape scsi disk tape
Probing /pci@4,4000 at Device 2  SUNW,m64Pro
Probing /pci@4,4000 at Device 3  Nothing there
Probing /pci@4,4000 at Device 4  Nothing there
Probing /pci@4,4000 at Device 5  Nothing there
Probing /pci@4,2000 at Device 1  Nothing there

UltraAX-MP+ WorkServer (2 X UltraSPARC-II 448MHz), No Keyboard
OpenBoot 3.10.50 ME, 2048 MB memory installed, Serial #15728707.
Ethernet address 8:0:20:f0:0:43, Host ID: 80f00043.


Executing last command: boot /pci@1f,4000/network@1,1:bootp,loader-sparc64
Boot device: /pci@1f,4000/network@1,1:bootp,loader-sparc64  File and args:
Using Onboard Transceiver - Link Up.
36a00
Server  IP address: 10.101.1.1
Client  IP address: 10.101.1.13
Gateway IP address: 10.101.1.1
Consoles: Open Firmware console

Booting with sun4u support.

FreeBSD/sparc64 bootstrap loader, Revision 1.0
(root@obrian.cse.buffalo.edu, Thu Jan  1 08:47:00 UTC 2009)
bootpath="/pci@1f,4000/network@1,1:bootp,loader-sparc64"
boot: ethernet address: 08:00:20:f0:00:43
Using Onboard Transceiver - Link Up.
net_open: server addr: 10.101.1.1
net_open: server path: /mnt/cdrom
Loading /boot/defaults/loader.conf
/boot/kernel/kernel data=0x739b48+0x74b38 syms=[0x8+0x7d058+0x8+0x6bd34]
-
Hit [Enter] to boot immediately, or any other key for command prompt.
Booting [/boot/kernel/kernel]...
jumping to kernel entry at 0xc0070000.
stray vector interrupt 2029
Copyright (c) 1992-2009 The FreeBSD Project.
Copyright (c) 1979, 1980, 1983, 1986, 1988, 1989, 1991, 1992, 1993, 1994
        The Regents of the University of California. All rights reserved.
FreeBSD is a registered trademark of The FreeBSD Foundation.
FreeBSD 7.1-RELEASE #0: Fri Jan  2 01:32:39 UTC 2009
    root@obrian.cse.buffalo.edu:/usr/obj/usr/src/sys/GENERIC
real memory  = 2147483648 (2048 MB)
avail memory = 2075926528 (1979 MB)
cpu0: Sun Microsystems UltraSparc-II Processor (448.00 MHz CPU)
cpu1: Sun Microsystems UltraSparc-II Processor (448.00 MHz CPU)
FreeBSD/SMP: Multiprocessor System Detected: 2 CPUs
registered firmware set <isp_1000>
registered firmware set <isp_1040>
registered firmware set <isp_1040_it>
registered firmware set <isp_1080>
registered firmware set <isp_1080_it>
registered firmware set <isp_12160>
registered firmware set <isp_12160_it>
registered firmware set <isp_2100>
registered firmware set <isp_2200>
registered firmware set <isp_2300>
registered firmware set <isp_2322>
registered firmware set <isp_2400>
kbd0 at kbdmux0
ath_hal: 0.9.20.3 (AR5210, AR5211, AR5212, RF5111, RF5112, RF2413, RF5413, REGOP
S_FUNC)
nexus0: <Open Firmware Nexus device>
pcib0: <U2P UPA-PCI bridge> mem 0x1fe00004000-0x1fe00005fff,0x1fe01000000-0x1fe0
10000ff,0x1fe00000000-0x1fe0000cfff irq 2033,2030,2031,2021,2024,2034 on nexus0
pcib0: Psycho, impl 0, version 4, IGN 0x1f, bus B, 33MHz
pcib0: [FILTER]
pcib0: [FILTER]
pcib0: [GIANT-LOCKED]
pcib0: [ITHREAD]
pcib0: [GIANT-LOCKED]
pcib0: [ITHREAD]
initializing counter-timer
Timecounter "pcib0" frequency 1000000 Hz quality 100
pcib0: DVMA map: 0xfc000000 to 0xffffffff
pcib0: [FILTER]
pci0: <OFW PCI bus> on pcib0
ebus0: <PCI-EBus2 bridge> mem 0x70000000-0x70ffffff,0x71000000-0x717fffff at dev
ice 1.0 on pci0
auxio0: <Sun Auxiliary I/O> addr 0x1400726000-0x1400726003,0x1400728000-0x140072
8003,0x140072a000-0x140072a003,0x140072c000-0x140072c003,0x140072f000-0x140072f0
03 on ebus0
ebus0: <power> addr 0x1400724000-0x1400724003 irq 37 (no driver attached)
ebus0: <SUNW,pll> addr 0x1400504000-0x1400504002 (no driver attached)
ebus0: <sc> addr 0x1400500000-0x1400500007 (no driver attached)
scc0: <Siemens SAB 82532 dual channel SCC> addr 0x1400400000-0x140040007f irq 43
 on ebus0
scc0: [FILTER]
uart0: <SAB 82532 v3.2, channel A> on scc0
uart0: [FILTER]
uart0: CTS oflow
uart0: console (9600,n,8,1)
uart1: <SAB 82532 v3.2, channel B> on scc0
uart1: [FILTER]
uart1: CTS oflow
uart2: <16550 or compatible> addr 0x14003803f8-0x14003803ff irq 41 on ebus0
uart2: [FILTER]
uart2: keyboard (1200,n,8,1)
uart2: keyboard not present
uart3: <16550 or compatible> addr 0x14003602f8-0x14003602ff irq 42 on ebus0
uart3: [FILTER]
ebus0: <ecpp> addr 0x1400340278-0x1400340287,0x140030015c-0x140030015d,0x1400700
000-0x140070000f irq 34 (no driver attached)
ebus0: <fdthree> addr 0x14003203f0-0x14003203f7,0x1400706000-0x140070600f,0x1400
720000-0x1400720003 irq 39 (no driver attached)
eeprom0: <EEPROM/clock> addr 0x1400000000-0x1400001fff on ebus0
eeprom0: model mk48t59
ebus0: <flashprom> addr 0x1000000000-0x10000fffff (no driver attached)
ebus0: <i2c> addr 0x1400600000-0x1400600003 irq 40 (no driver attached)
hme0: <Sun HME 10/100 Ethernet> mem 0x8000-0xffff at device 1.1 on pci0
miibus0: <MII bus> on hme0
nsphy0: <DP83840 10/100 media interface> PHY 1 on miibus0
nsphy0:  10baseT, 10baseT-FDX, 100baseTX, 100baseTX-FDX, auto
hme0: Ethernet address: 08:00:20:f0:00:43
hme0: [ITHREAD]
pcib1: <U2P UPA-PCI bridge> mem 0x1fe00002000-0x1fe00003fff,0x1fe01800000-0x1fe0
18000ff,0x1fe00000000-0x1fe0000cfff irq 2032,2030,2031,2021,2024,2034 on nexus0
pcib1: Psycho, impl 0, version 4, IGN 0x1f, bus A, 66MHz
pcib1: [FILTER]
pci1: <OFW PCI bus> on pcib1
pcib2: <U2P UPA-PCI bridge> mem 0x1c800004000-0x1c800005fff,0x1c801000000-0x1c80
10000ff,0x1c800000000-0x1c80000cfff irq 305,302,303 on nexus0
pcib2: Psycho, impl 0, version 4, IGN 0x4, bus B, 33MHz
pcib2: [FILTER]
pcib2: [FILTER]
panic: psycho_set_intr: failed to set up interrupt 3
cpuid = 0
Uptime: 1s
Automatic reboot in 15 seconds - press a key on the console to abort
Rebooting...
Resetting ...

How-To-Repeat: It panics every single time on this model, however I've ever tried any other version, either. I'll be testing with NetBSD/sparc64 4.0 next and see how it does, as it looks like the psycho driver that FreeBSD uses was derived from NetBSD. Note that the system boots and runs just fine with the copy of Solaris 8 that's installed on one of the local drives.
Comment 1 marius 2009-02-04 21:30:32 UTC
On Wed, Feb 04, 2009 at 05:11:11PM +0000, Rory Arms wrote:
> 
> pcib2: <U2P UPA-PCI bridge> mem 0x1c800004000-0x1c800005fff,0x1c801000000-0x1c80
> 10000ff,0x1c800000000-0x1c80000cfff irq 305,302,303 on nexus0
> pcib2: Psycho, impl 0, version 4, IGN 0x4, bus B, 33MHz
> pcib2: [FILTER]
> pcib2: [FILTER]
> panic: psycho_set_intr: failed to set up interrupt 3

Could you please give the following stable/7 kernel a try?
http://people.freebsd.org/~marius/psycho.gz
It's built with the patch at:
http://people.freebsd.org/~marius/psycho.diff

Marius
Comment 2 Mark Linimon freebsd_committer freebsd_triage 2009-02-05 23:00:43 UTC
State Changed
From-To: open->feedback

Note that submitter was asked for feedback.
Comment 3 Rory Arms 2009-02-12 23:52:52 UTC
Thanks, Marius. As mentioned in my reply email to you a few days ago,  
your patch resolves this issue. I look forward to seeing it committed  
to 7.1-STABLE.

- rory
Comment 4 dfilter service freebsd_committer freebsd_triage 2009-03-19 20:52:59 UTC
Author: marius
Date: Thu Mar 19 20:52:46 2009
New Revision: 190109
URL: http://svn.freebsd.org/changeset/base/190109

Log:
  - Ensure we find no unexpected partner.
  - Failing to register as interrupt controller during attach shouldn't
    be fatal so just inform about this instead of panicing.
  - Disable rerun of the streaming cache as workaround for a silicon bug
    of certain Psycho versions.
  - Remove the comment regarding lack of newbus'ified bus_dma(9) as being
    able to associate a DMA tag with a device would allow to implement
    CDMA flushing/syncing in bus_dmamap_sync(9) but that would totally
    kill performance. Given that for devices not behind a PCI-PCI bridge
    the host-to-PCI bridges also only do CDMA flushing/syncing based on
    interrupts there's no additional disadvantage for polling(4) callbacks
    in the case schizo(4) has to do the CDMA flushing/syncing but rather a
    general problem.
  - Don't panic if the power failure, power management or over-temperature
    interrupts doesn't exist as these aren't mandatory and not available
    with all controllers (not even Psychos). [1]
  - Take advantage of KOBJMETHOD_END.
  - Remove some redundant variables.
  - Add missing const.
  
  PR:	131371 [1]

Modified:
  head/sys/sparc64/pci/psycho.c
  head/sys/sparc64/pci/psychovar.h

Modified: head/sys/sparc64/pci/psycho.c
==============================================================================
--- head/sys/sparc64/pci/psycho.c	Thu Mar 19 20:48:47 2009	(r190108)
+++ head/sys/sparc64/pci/psycho.c	Thu Mar 19 20:52:46 2009	(r190109)
@@ -83,7 +83,7 @@ static void psycho_set_intr(struct psych
     driver_filter_t, driver_intr_t);
 static int psycho_find_intrmap(struct psycho_softc *, u_int, bus_addr_t *,
     bus_addr_t *, u_long *);
-static driver_filter_t psycho_dmasync;
+static driver_filter_t psycho_dma_sync_stub;
 static void psycho_intr_enable(void *);
 static void psycho_intr_disable(void *);
 static void psycho_intr_assign(void *);
@@ -150,7 +150,7 @@ static device_method_t psycho_methods[] 
 	/* ofw_bus interface */
 	DEVMETHOD(ofw_bus_get_node,	psycho_get_node),
 
-	{ 0, 0 }
+	KOBJMETHOD_END
 };
 
 static devclass_t psycho_devclass;
@@ -175,7 +175,7 @@ struct psycho_icarg {
 	bus_addr_t		pica_clr;
 };
 
-struct psycho_dmasync {
+struct psycho_dma_sync {
 	struct psycho_softc	*pds_sc;
 	driver_filter_t		*pds_handler;	/* handler to call */
 	void			*pds_arg;	/* argument for the handler */
@@ -232,14 +232,14 @@ struct psycho_desc {
 	const char	*pd_name;
 };
 
-static const struct psycho_desc psycho_compats[] = {
+static const struct psycho_desc const psycho_compats[] = {
 	{ "pci108e,8000", PSYCHO_MODE_PSYCHO,	"Psycho compatible" },
 	{ "pci108e,a000", PSYCHO_MODE_SABRE,	"Sabre compatible" },
 	{ "pci108e,a001", PSYCHO_MODE_SABRE,	"Hummingbird compatible" },
 	{ NULL,		  0,			NULL }
 };
 
-static const struct psycho_desc psycho_models[] = {
+static const struct psycho_desc const psycho_models[] = {
 	{ "SUNW,psycho",  PSYCHO_MODE_PSYCHO,	"Psycho" },
 	{ "SUNW,sabre",   PSYCHO_MODE_SABRE,	"Sabre" },
 	{ NULL,		  0,			NULL }
@@ -296,8 +296,8 @@ psycho_attach(device_t dev)
 	phandle_t child, node;
 	uint32_t dvmabase, prop, prop_array[2];
 	int32_t rev;
-	u_int ver;
-	int i, n, nrange, rid;
+	u_int rerun, ver;
+	int i, n;
 
 	node = ofw_bus_get_node(dev);
 	sc = device_get_softc(dev);
@@ -315,7 +315,7 @@ psycho_attach(device_t dev)
 	 * (2) the shared Psycho configuration registers
 	 */
 	if (sc->sc_mode == PSYCHO_MODE_PSYCHO) {
-		rid = 2;
+		i = 2;
 		sc->sc_pcictl =
 		    bus_get_resource_start(dev, SYS_RES_MEMORY, 0) -
 		    bus_get_resource_start(dev, SYS_RES_MEMORY, 2);
@@ -332,18 +332,18 @@ psycho_attach(device_t dev)
 			/* NOTREACHED */
 		}
 	} else {
-		rid = 0;
+		i = 0;
 		sc->sc_pcictl = PSR_PCICTL0;
 		sc->sc_half = 0;
 	}
-	sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
+	sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &i,
 	    (sc->sc_mode == PSYCHO_MODE_PSYCHO ? RF_SHAREABLE : 0) |
 	    RF_ACTIVE);
 	if (sc->sc_mem_res == NULL)
 		panic("%s: could not allocate registers", __func__);
 
 	/*
-	 * Match other Psycho's that are already configured against
+	 * Match other Psychos that are already configured against
 	 * the base physical address.  This will be the same for a
 	 * pair of devices that share register space.
 	 */
@@ -363,6 +363,8 @@ psycho_attach(device_t dev)
 			panic("%s: could not malloc mutex", __func__);
 		mtx_init(sc->sc_mtx, "pcib_mtx", NULL, MTX_SPIN);
 	} else {
+		if (sc->sc_mode != PSYCHO_MODE_PSYCHO)
+			panic("%s: no partner expected", __func__);
 		if (mtx_initialized(osc->sc_mtx) == 0)
 			panic("%s: mutex not initialized", __func__);
 		sc->sc_mtx = osc->sc_mtx;
@@ -408,16 +410,17 @@ psycho_attach(device_t dev)
 	case 0:
 		dr |= DIAG_RTRY_DIS;
 		dr &= ~DIAG_DWSYNC_DIS;
-		/* XXX need to also disable rerun of the streaming buffers. */
+		rerun = 0;
 		break;
 	case 1:
 		csr &= ~PCICTL_ARB_PARK;
 		dr |= DIAG_RTRY_DIS | DIAG_DWSYNC_DIS;
-		/* XXX need to also disable rerun of the streaming buffers. */
+		rerun = 0;
 		break;
 	default:
 		dr |= DIAG_DWSYNC_DIS;
 		dr &= ~DIAG_RTRY_DIS;
+		rerun = 1;
 		break;
 	}
 
@@ -460,13 +463,12 @@ psycho_attach(device_t dev)
 	    rman_manage_region(&sc->sc_pci_mem_rman, 0, PSYCHO_MEM_SIZE) != 0)
 		panic("%s: failed to set up memory rman", __func__);
 
-	nrange = OF_getprop_alloc(node, "ranges", sizeof(*range),
-	    (void **)&range);
+	n = OF_getprop_alloc(node, "ranges", sizeof(*range), (void **)&range);
 	/*
 	 * Make sure that the expected ranges are present.  The
 	 * OFW_PCI_CS_MEM64 one is not currently used though.
 	 */
-	if (nrange != PSYCHO_NRANGE)
+	if (n != PSYCHO_NRANGE)
 		panic("%s: unsupported number of ranges", __func__);
 	/*
 	 * Find the addresses of the various bus spaces.
@@ -493,7 +495,8 @@ psycho_attach(device_t dev)
 		/*
 		 * Hunt through all the interrupt mapping regs and register
 		 * our interrupt controller for the corresponding interrupt
-		 * vectors.
+		 * vectors.  We do this early in order to be able to catch
+		 * stray interrupts.
 		 */
 		for (n = 0; n <= PSYCHO_MAX_INO; n++) {
 			if (psycho_find_intrmap(sc, n, &intrmap, &intrclr,
@@ -523,22 +526,23 @@ psycho_attach(device_t dev)
 			    INTMAP_ENABLE(INTMAP_VEC(sc->sc_ign, n),
 			    PCPU_GET(mid)));
 #endif
-			if (intr_controller_register(INTMAP_VEC(sc->sc_ign, n),
-			    &psycho_ic, pica) != 0)
-				panic("%s: could not register interrupt "
-				    "controller for INO %d", __func__, n);
+			i = intr_controller_register(INTMAP_VEC(sc->sc_ign, n),
+			    &psycho_ic, pica);
+			if (i != 0)
+				device_printf(dev, "could not register "
+				    "interrupt controller for INO %d (%d)\n",
+				    n, i);
 		}
 
-		if (sc->sc_mode == PSYCHO_MODE_PSYCHO) {
-			/* Initialize the counter-timer. */
+		if (sc->sc_mode == PSYCHO_MODE_PSYCHO)
 			sparc64_counter_init(device_get_nameunit(dev),
 			    rman_get_bustag(sc->sc_mem_res),
 			    rman_get_bushandle(sc->sc_mem_res), PSR_TC0);
-		}
 
 		/*
 		 * Set up IOMMU and PCI configuration if we're the first
-		 * of a pair of Psycho's to arrive here.
+		 * of a pair of Psychos to arrive here or a Hummingbird
+		 * or Sabre.
 		 *
 		 * We should calculate a TSB size based on amount of RAM
 		 * and number of bus controllers and number and type of
@@ -556,10 +560,10 @@ psycho_attach(device_t dev)
 		else
 			sc->sc_is->is_pmaxaddr =
 			    IOMMU_MAXADDR(PSYCHO_IOMMU_BITS);
-		sc->sc_is->is_sb[0] = 0;
-		sc->sc_is->is_sb[1] = 0;
+		sc->sc_is->is_sb[0] = sc->sc_is->is_sb[1] = 0;
 		if (OF_getproplen(node, "no-streaming-cache") < 0)
 			sc->sc_is->is_sb[0] = sc->sc_pcictl + PCR_STRBUF;
+		sc->sc_is->is_flags |= (rerun != 1) ? IOMMU_RERUN_DISABLE : 0;
 		psycho_iommu_init(sc, 3, dvmabase);
 	} else {
 		/* Just copy IOMMU state, config tag and address. */
@@ -694,12 +698,20 @@ psycho_set_intr(struct psycho_softc *sc,
 	rid = index;
 	sc->sc_irq_res[index] = bus_alloc_resource_any(sc->sc_dev, SYS_RES_IRQ,
 	    &rid, RF_ACTIVE);
+	if (sc->sc_irq_res[index] == NULL && intrmap >= PSR_POWER_INT_MAP) {
+		/*
+		 * These interrupts aren't mandatory and not available
+		 * with all controllers (not even Psychos).
+		 */
+		return;
+	}
 	if (sc->sc_irq_res[index] == NULL ||
 	    INTIGN(vec = rman_get_start(sc->sc_irq_res[index])) != sc->sc_ign ||
 	    INTVEC(PSYCHO_READ8(sc, intrmap)) != vec ||
 	    intr_vectors[vec].iv_ic != &psycho_ic ||
-	    bus_setup_intr(sc->sc_dev, sc->sc_irq_res[index], INTR_TYPE_MISC,
-	    filt, intr, sc, &sc->sc_ihand[index]) != 0)
+	    bus_setup_intr(sc->sc_dev, sc->sc_irq_res[index],
+	    INTR_TYPE_MISC | INTR_FAST, filt, intr, sc,
+	    &sc->sc_ihand[index]) != 0)
 		panic("%s: failed to set up interrupt %d", __func__, index);
 }
 
@@ -1065,9 +1077,9 @@ psycho_read_ivar(device_t dev, device_t 
 }
 
 static int
-psycho_dmasync(void *arg)
+psycho_dma_sync_stub(void *arg)
 {
-	struct psycho_dmasync *pds = arg;
+	struct psycho_dma_sync *pds = arg;
 
 	(void)PCIB_READ_CONFIG(pds->pds_ppb, pds->pds_bus, pds->pds_slot,
 	    pds->pds_func, PCIR_VENDOR, 2);
@@ -1125,7 +1137,7 @@ psycho_setup_intr(device_t dev, device_t
 	devclass_t pci_devclass;
 	device_t cdev, pdev, pcidev;
 	struct psycho_softc *sc;
-	struct psycho_dmasync *pds;
+	struct psycho_dma_sync *pds;
 	u_long vec;
 	int error;
 
@@ -1142,17 +1154,12 @@ psycho_setup_intr(device_t dev, device_t
 	}
 
 	/*
-	 * The Sabre-APB-combination has a bug where it does not drain
-	 * DMA write data for devices behind additional PCI-PCI bridges
-	 * underneath the APB PCI-PCI bridge.  The workaround is to do
-	 * a read on the farest PCI-PCI bridge followed by a read of the
-	 * PCI DMA write sync register of the Sabre.
-	 * XXX installing the wrapper for an affected device and the
-	 * actual workaround in psycho_dmasync() should be moved to
-	 * psycho(4)-specific bus_dma_tag_create() and bus_dmamap_sync()
-	 * methods, respectively, once DMA tag creation is newbus'ified,
-	 * so the workaround isn't only applied for interrupt handlers
-	 * but also for polling(4) callbacks.
+	 * The Sabre-APB-combination does not automatically flush DMA
+	 * write data for devices behind additional PCI-PCI bridges
+	 * underneath the APB PCI-PCI bridge.  The procedure for a
+	 * manual flush is to do a PIO read on the far side of the
+	 * farthest PCI-PCI bridge followed by a read of the PCI DMA
+	 * write sync register of the Sabre.
 	 */
 	if (sc->sc_mode == PSYCHO_MODE_SABRE) {
 		pds = malloc(sizeof(*pds), M_DEVBUF, M_NOWAIT | M_ZERO);
@@ -1191,20 +1198,20 @@ psycho_setup_intr(device_t dev, device_t
 			pds->pds_func = pci_get_function(pcidev);
 			if (bootverbose)
 				device_printf(dev, "installed DMA sync "
-				    "workaround for device %d.%d on bus %d\n",
+				    "wrapper for device %d.%d on bus %d\n",
 				    pds->pds_slot, pds->pds_func,
 				    pds->pds_bus);
 			if (intr == NULL) {
 				pds->pds_handler = filt;
 				error = bus_generic_setup_intr(dev, child,
-				    ires, flags, psycho_dmasync, intr, pds,
-				    cookiep);
+				    ires, flags, psycho_dma_sync_stub, intr,
+				    pds, cookiep);
 			} else {
 				pds->pds_handler = (driver_filter_t *)intr;
 				error = bus_generic_setup_intr(dev, child,
 				    ires, flags, filt,
-				    (driver_intr_t *)psycho_dmasync, pds,
-				    cookiep);
+				    (driver_intr_t *)psycho_dma_sync_stub,
+				    pds, cookiep);
 			}
 		} else
 			error = bus_generic_setup_intr(dev, child, ires,
@@ -1226,7 +1233,7 @@ psycho_teardown_intr(device_t dev, devic
     void *cookie)
 {
 	struct psycho_softc *sc;
-	struct psycho_dmasync *pds;
+	struct psycho_dma_sync *pds;
 	int error;
 
 	sc = device_get_softc(dev);
@@ -1314,8 +1321,8 @@ psycho_activate_resource(device_t bus, d
 		    type, rid, r));
 	if (type == SYS_RES_MEMORY) {
 		/*
-		 * Need to memory-map the device space, as some drivers depend
-		 * on the virtual address being set and useable.
+		 * Need to memory-map the device space, as some drivers
+		 * depend on the virtual address being set and usable.
 		 */
 		error = sparc64_bus_mem_map(rman_get_bustag(r),
 		    rman_get_bushandle(r), rman_get_size(r), 0, 0, &p);

Modified: head/sys/sparc64/pci/psychovar.h
==============================================================================
--- head/sys/sparc64/pci/psychovar.h	Thu Mar 19 20:48:47 2009	(r190108)
+++ head/sys/sparc64/pci/psychovar.h	Thu Mar 19 20:52:46 2009	(r190109)
@@ -49,8 +49,8 @@ struct psycho_softc {
 
 	phandle_t			sc_node;	/* Firmware node */
 	u_int				sc_mode;
-#define	PSYCHO_MODE_SABRE	1
-#define	PSYCHO_MODE_PSYCHO	2
+#define	PSYCHO_MODE_SABRE		0
+#define	PSYCHO_MODE_PSYCHO		1
 
 	/* Bus A or B of a psycho pair? */
 	u_int				sc_half;
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
Comment 5 dfilter service freebsd_committer freebsd_triage 2009-03-22 21:38:45 UTC
Author: marius
Date: Sun Mar 22 21:38:24 2009
New Revision: 190290
URL: http://svn.freebsd.org/changeset/base/190290

Log:
  MFC: r190109
  
  - Ensure we find no unexpected partner.
  - Failing to register as interrupt controller during attach shouldn't
    be fatal so just inform about this instead of panicing.
  - Disable rerun of the streaming cache as workaround for a silicon bug
    of certain Psycho versions.
  - Remove the comment regarding lack of newbus'ified bus_dma(9) as being
    able to associate a DMA tag with a device would allow to implement
    CDMA flushing/syncing in bus_dmamap_sync(9) but that would totally
    kill performance. Given that for devices not behind a PCI-PCI bridge
    the host-to-PCI bridges also only do CDMA flushing/syncing based on
    interrupts there's no additional disadvantage for polling(4) callbacks
    in the case schizo(4) has to do the CDMA flushing/syncing but rather a
    general problem.
  - Don't panic if the power failure, power management or over-temperature
    interrupts doesn't exist as these aren't mandatory and not available
    with all controllers (not even Psychos). [1]
  - Take advantage of KOBJMETHOD_END.
  - Remove some redundant variables.
  - Add missing const.
  
  PR:	131371 [1]

Modified:
  stable/7/sys/   (props changed)
  stable/7/sys/contrib/pf/   (props changed)
  stable/7/sys/dev/ath/ath_hal/   (props changed)
  stable/7/sys/dev/cxgb/   (props changed)
  stable/7/sys/sparc64/pci/psycho.c
  stable/7/sys/sparc64/pci/psychovar.h

Modified: stable/7/sys/sparc64/pci/psycho.c
==============================================================================
--- stable/7/sys/sparc64/pci/psycho.c	Sun Mar 22 21:31:02 2009	(r190289)
+++ stable/7/sys/sparc64/pci/psycho.c	Sun Mar 22 21:38:24 2009	(r190290)
@@ -84,7 +84,7 @@ static void psycho_set_intr(struct psych
     driver_filter_t, driver_intr_t);
 static int psycho_find_intrmap(struct psycho_softc *, u_int, bus_addr_t *,
     bus_addr_t *, u_long *);
-static driver_filter_t psycho_dmasync;
+static driver_filter_t psycho_dma_sync_stub;
 static void psycho_intr_enable(void *);
 static void psycho_intr_disable(void *);
 static void psycho_intr_assign(void *);
@@ -151,7 +151,7 @@ static device_method_t psycho_methods[] 
 	/* ofw_bus interface */
 	DEVMETHOD(ofw_bus_get_node,	psycho_get_node),
 
-	{ 0, 0 }
+	KOBJMETHOD_END
 };
 
 static devclass_t psycho_devclass;
@@ -176,7 +176,7 @@ struct psycho_icarg {
 	bus_addr_t		pica_clr;
 };
 
-struct psycho_dmasync {
+struct psycho_dma_sync {
 	struct psycho_softc	*pds_sc;
 	driver_filter_t		*pds_handler;	/* handler to call */
 	void			*pds_arg;	/* argument for the handler */
@@ -233,14 +233,14 @@ struct psycho_desc {
 	const char	*pd_name;
 };
 
-static const struct psycho_desc psycho_compats[] = {
+static const struct psycho_desc const psycho_compats[] = {
 	{ "pci108e,8000", PSYCHO_MODE_PSYCHO,	"Psycho compatible" },
 	{ "pci108e,a000", PSYCHO_MODE_SABRE,	"Sabre compatible" },
 	{ "pci108e,a001", PSYCHO_MODE_SABRE,	"Hummingbird compatible" },
 	{ NULL,		  0,			NULL }
 };
 
-static const struct psycho_desc psycho_models[] = {
+static const struct psycho_desc const psycho_models[] = {
 	{ "SUNW,psycho",  PSYCHO_MODE_PSYCHO,	"Psycho" },
 	{ "SUNW,sabre",   PSYCHO_MODE_SABRE,	"Sabre" },
 	{ NULL,		  0,			NULL }
@@ -297,8 +297,8 @@ psycho_attach(device_t dev)
 	phandle_t child, node;
 	uint32_t dvmabase, prop, prop_array[2];
 	int32_t rev;
-	u_int ver;
-	int i, n, nrange, rid;
+	u_int rerun, ver;
+	int i, n;
 
 	node = ofw_bus_get_node(dev);
 	sc = device_get_softc(dev);
@@ -316,7 +316,7 @@ psycho_attach(device_t dev)
 	 * (2) the shared Psycho configuration registers
 	 */
 	if (sc->sc_mode == PSYCHO_MODE_PSYCHO) {
-		rid = 2;
+		i = 2;
 		sc->sc_pcictl =
 		    bus_get_resource_start(dev, SYS_RES_MEMORY, 0) -
 		    bus_get_resource_start(dev, SYS_RES_MEMORY, 2);
@@ -333,18 +333,18 @@ psycho_attach(device_t dev)
 			/* NOTREACHED */
 		}
 	} else {
-		rid = 0;
+		i = 0;
 		sc->sc_pcictl = PSR_PCICTL0;
 		sc->sc_half = 0;
 	}
-	sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
+	sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &i,
 	    (sc->sc_mode == PSYCHO_MODE_PSYCHO ? RF_SHAREABLE : 0) |
 	    RF_ACTIVE);
 	if (sc->sc_mem_res == NULL)
 		panic("%s: could not allocate registers", __func__);
 
 	/*
-	 * Match other Psycho's that are already configured against
+	 * Match other Psychos that are already configured against
 	 * the base physical address.  This will be the same for a
 	 * pair of devices that share register space.
 	 */
@@ -364,6 +364,8 @@ psycho_attach(device_t dev)
 			panic("%s: could not malloc mutex", __func__);
 		mtx_init(sc->sc_mtx, "pcib_mtx", NULL, MTX_SPIN);
 	} else {
+		if (sc->sc_mode != PSYCHO_MODE_PSYCHO)
+			panic("%s: no partner expected", __func__);
 		if (mtx_initialized(osc->sc_mtx) == 0)
 			panic("%s: mutex not initialized", __func__);
 		sc->sc_mtx = osc->sc_mtx;
@@ -409,16 +411,17 @@ psycho_attach(device_t dev)
 	case 0:
 		dr |= DIAG_RTRY_DIS;
 		dr &= ~DIAG_DWSYNC_DIS;
-		/* XXX need to also disable rerun of the streaming buffers. */
+		rerun = 0;
 		break;
 	case 1:
 		csr &= ~PCICTL_ARB_PARK;
 		dr |= DIAG_RTRY_DIS | DIAG_DWSYNC_DIS;
-		/* XXX need to also disable rerun of the streaming buffers. */
+		rerun = 0;
 		break;
 	default:
 		dr |= DIAG_DWSYNC_DIS;
 		dr &= ~DIAG_RTRY_DIS;
+		rerun = 1;
 		break;
 	}
 
@@ -461,13 +464,12 @@ psycho_attach(device_t dev)
 	    rman_manage_region(&sc->sc_pci_mem_rman, 0, PSYCHO_MEM_SIZE) != 0)
 		panic("%s: failed to set up memory rman", __func__);
 
-	nrange = OF_getprop_alloc(node, "ranges", sizeof(*range),
-	    (void **)&range);
+	n = OF_getprop_alloc(node, "ranges", sizeof(*range), (void **)&range);
 	/*
 	 * Make sure that the expected ranges are present.  The
 	 * OFW_PCI_CS_MEM64 one is not currently used though.
 	 */
-	if (nrange != PSYCHO_NRANGE)
+	if (n != PSYCHO_NRANGE)
 		panic("%s: unsupported number of ranges", __func__);
 	/*
 	 * Find the addresses of the various bus spaces.
@@ -494,7 +496,8 @@ psycho_attach(device_t dev)
 		/*
 		 * Hunt through all the interrupt mapping regs and register
 		 * our interrupt controller for the corresponding interrupt
-		 * vectors.
+		 * vectors.  We do this early in order to be able to catch
+		 * stray interrupts.
 		 */
 		for (n = 0; n <= PSYCHO_MAX_INO; n++) {
 			if (psycho_find_intrmap(sc, n, &intrmap, &intrclr,
@@ -524,22 +527,23 @@ psycho_attach(device_t dev)
 			    INTMAP_ENABLE(INTMAP_VEC(sc->sc_ign, n),
 			    PCPU_GET(mid)));
 #endif
-			if (intr_controller_register(INTMAP_VEC(sc->sc_ign, n),
-			    &psycho_ic, pica) != 0)
-				panic("%s: could not register interrupt "
-				    "controller for INO %d", __func__, n);
+			i = intr_controller_register(INTMAP_VEC(sc->sc_ign, n),
+			    &psycho_ic, pica);
+			if (i != 0)
+				device_printf(dev, "could not register "
+				    "interrupt controller for INO %d (%d)\n",
+				    n, i);
 		}
 
-		if (sc->sc_mode == PSYCHO_MODE_PSYCHO) {
-			/* Initialize the counter-timer. */
+		if (sc->sc_mode == PSYCHO_MODE_PSYCHO)
 			sparc64_counter_init(device_get_nameunit(dev),
 			    rman_get_bustag(sc->sc_mem_res),
 			    rman_get_bushandle(sc->sc_mem_res), PSR_TC0);
-		}
 
 		/*
 		 * Set up IOMMU and PCI configuration if we're the first
-		 * of a pair of Psycho's to arrive here.
+		 * of a pair of Psychos to arrive here or a Hummingbird
+		 * or Sabre.
 		 *
 		 * We should calculate a TSB size based on amount of RAM
 		 * and number of bus controllers and number and type of
@@ -557,10 +561,10 @@ psycho_attach(device_t dev)
 		else
 			sc->sc_is->is_pmaxaddr =
 			    IOMMU_MAXADDR(PSYCHO_IOMMU_BITS);
-		sc->sc_is->is_sb[0] = 0;
-		sc->sc_is->is_sb[1] = 0;
+		sc->sc_is->is_sb[0] = sc->sc_is->is_sb[1] = 0;
 		if (OF_getproplen(node, "no-streaming-cache") < 0)
 			sc->sc_is->is_sb[0] = sc->sc_pcictl + PCR_STRBUF;
+		sc->sc_is->is_flags |= (rerun != 1) ? IOMMU_RERUN_DISABLE : 0;
 		psycho_iommu_init(sc, 3, dvmabase);
 	} else {
 		/* Just copy IOMMU state, config tag and address. */
@@ -695,12 +699,20 @@ psycho_set_intr(struct psycho_softc *sc,
 	rid = index;
 	sc->sc_irq_res[index] = bus_alloc_resource_any(sc->sc_dev, SYS_RES_IRQ,
 	    &rid, RF_ACTIVE);
+	if (sc->sc_irq_res[index] == NULL && intrmap >= PSR_POWER_INT_MAP) {
+		/*
+		 * These interrupts aren't mandatory and not available
+		 * with all controllers (not even Psychos).
+		 */
+		return;
+	}
 	if (sc->sc_irq_res[index] == NULL ||
 	    INTIGN(vec = rman_get_start(sc->sc_irq_res[index])) != sc->sc_ign ||
 	    INTVEC(PSYCHO_READ8(sc, intrmap)) != vec ||
 	    intr_vectors[vec].iv_ic != &psycho_ic ||
-	    bus_setup_intr(sc->sc_dev, sc->sc_irq_res[index], INTR_TYPE_MISC,
-	    filt, intr, sc, &sc->sc_ihand[index]) != 0)
+	    bus_setup_intr(sc->sc_dev, sc->sc_irq_res[index],
+	    INTR_TYPE_MISC | INTR_FAST, filt, intr, sc,
+	    &sc->sc_ihand[index]) != 0)
 		panic("%s: failed to set up interrupt %d", __func__, index);
 }
 
@@ -1066,9 +1078,9 @@ psycho_read_ivar(device_t dev, device_t 
 }
 
 static int
-psycho_dmasync(void *arg)
+psycho_dma_sync_stub(void *arg)
 {
-	struct psycho_dmasync *pds = arg;
+	struct psycho_dma_sync *pds = arg;
 
 	(void)PCIB_READ_CONFIG(pds->pds_ppb, pds->pds_bus, pds->pds_slot,
 	    pds->pds_func, PCIR_VENDOR, 2);
@@ -1126,7 +1138,7 @@ psycho_setup_intr(device_t dev, device_t
 	devclass_t pci_devclass;
 	device_t cdev, pdev, pcidev;
 	struct psycho_softc *sc;
-	struct psycho_dmasync *pds;
+	struct psycho_dma_sync *pds;
 	u_long vec;
 	int error;
 
@@ -1143,17 +1155,12 @@ psycho_setup_intr(device_t dev, device_t
 	}
 
 	/*
-	 * The Sabre-APB-combination has a bug where it does not drain
-	 * DMA write data for devices behind additional PCI-PCI bridges
-	 * underneath the APB PCI-PCI bridge.  The workaround is to do
-	 * a read on the farest PCI-PCI bridge followed by a read of the
-	 * PCI DMA write sync register of the Sabre.
-	 * XXX installing the wrapper for an affected device and the
-	 * actual workaround in psycho_dmasync() should be moved to
-	 * psycho(4)-specific bus_dma_tag_create() and bus_dmamap_sync()
-	 * methods, respectively, once DMA tag creation is newbus'ified,
-	 * so the workaround isn't only applied for interrupt handlers
-	 * but also for polling(4) callbacks.
+	 * The Sabre-APB-combination does not automatically flush DMA
+	 * write data for devices behind additional PCI-PCI bridges
+	 * underneath the APB PCI-PCI bridge.  The procedure for a
+	 * manual flush is to do a PIO read on the far side of the
+	 * farthest PCI-PCI bridge followed by a read of the PCI DMA
+	 * write sync register of the Sabre.
 	 */
 	if (sc->sc_mode == PSYCHO_MODE_SABRE) {
 		pds = malloc(sizeof(*pds), M_DEVBUF, M_NOWAIT | M_ZERO);
@@ -1192,20 +1199,20 @@ psycho_setup_intr(device_t dev, device_t
 			pds->pds_func = pci_get_function(pcidev);
 			if (bootverbose)
 				device_printf(dev, "installed DMA sync "
-				    "workaround for device %d.%d on bus %d\n",
+				    "wrapper for device %d.%d on bus %d\n",
 				    pds->pds_slot, pds->pds_func,
 				    pds->pds_bus);
 			if (intr == NULL) {
 				pds->pds_handler = filt;
 				error = bus_generic_setup_intr(dev, child,
-				    ires, flags, psycho_dmasync, intr, pds,
-				    cookiep);
+				    ires, flags, psycho_dma_sync_stub, intr,
+				    pds, cookiep);
 			} else {
 				pds->pds_handler = (driver_filter_t *)intr;
 				error = bus_generic_setup_intr(dev, child,
 				    ires, flags, filt,
-				    (driver_intr_t *)psycho_dmasync, pds,
-				    cookiep);
+				    (driver_intr_t *)psycho_dma_sync_stub,
+				    pds, cookiep);
 			}
 		} else
 			error = bus_generic_setup_intr(dev, child, ires,
@@ -1227,7 +1234,7 @@ psycho_teardown_intr(device_t dev, devic
     void *cookie)
 {
 	struct psycho_softc *sc;
-	struct psycho_dmasync *pds;
+	struct psycho_dma_sync *pds;
 	int error;
 
 	sc = device_get_softc(dev);
@@ -1315,8 +1322,8 @@ psycho_activate_resource(device_t bus, d
 		    type, rid, r));
 	if (type == SYS_RES_MEMORY) {
 		/*
-		 * Need to memory-map the device space, as some drivers depend
-		 * on the virtual address being set and useable.
+		 * Need to memory-map the device space, as some drivers
+		 * depend on the virtual address being set and usable.
 		 */
 		error = sparc64_bus_mem_map(rman_get_bustag(r),
 		    rman_get_bushandle(r), rman_get_size(r), 0, 0, &p);

Modified: stable/7/sys/sparc64/pci/psychovar.h
==============================================================================
--- stable/7/sys/sparc64/pci/psychovar.h	Sun Mar 22 21:31:02 2009	(r190289)
+++ stable/7/sys/sparc64/pci/psychovar.h	Sun Mar 22 21:38:24 2009	(r190290)
@@ -49,8 +49,8 @@ struct psycho_softc {
 
 	phandle_t			sc_node;	/* Firmware node */
 	u_int				sc_mode;
-#define	PSYCHO_MODE_SABRE	1
-#define	PSYCHO_MODE_PSYCHO	2
+#define	PSYCHO_MODE_SABRE		0
+#define	PSYCHO_MODE_PSYCHO		1
 
 	/* Bus A or B of a psycho pair? */
 	u_int				sc_half;
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
Comment 6 Marius Strobl freebsd_committer freebsd_triage 2009-03-22 21:56:39 UTC
State Changed
From-To: feedback->closed

close