Subject: Re: E250 support?
To: matthew green <mrg@eterna.com.au>
From: Mark Blackman <mark.blackman@netscalibur.co.uk>
List: port-sparc64
Date: 02/07/2001 09:11:03
Is it possible to build on a FreeBSD/i386 box or under Slowaris?

I can probably set up a NetBSD/i386 box if that helps.

Shall I just wait for your binary to download?

- Mark Blackman

> 
>    I have a possible fix.  Can you build kernels?
> 
> 
> actually, eeh and i discussed this and i have a change that should work.
> i've tested it on my U5 and i'll upload a GENERIC kernel shortly.  once
> it is verified to work on the 250, i'll commit to -current.
> 
> 
> .mrg.
> 
> 
> patch for pci_machdep.c for those interested.  it also fixes a bug
> where io/mem space weren't (force) enabled for devices without an
> "interrupts" property.
> 
> 
> Index: pci_machdep.c
> ===================================================================
> RCS file: /cvsroot/syssrc/sys/arch/sparc64/dev/pci_machdep.c,v
> retrieving revision 1.18
> diff -p -r1.18 pci_machdep.c
> *** pci_machdep.c	2001/01/19 21:25:19	1.18
> --- pci_machdep.c	2001/02/07 01:33:23
> *************** pci_attach_hook(parent, self, pba)
> *** 85,91 ****
>   	char *name, *devtype;
>   	u_int32_t hi, mid, lo, intr;
>   	u_int32_t dev, fn, bus;
> ! 	int node, i, n, *ip, *ap;
>   
>   	DPRINTF((SPDB_INTFIX|SPDB_INTMAP), ("\npci_attach_hook:"));
>   
> --- 85,91 ----
>   	char *name, *devtype;
>   	u_int32_t hi, mid, lo, intr;
>   	u_int32_t dev, fn, bus;
> ! 	int node, i, n, real_intr, *ip, *ap;
>   
>   	DPRINTF((SPDB_INTFIX|SPDB_INTMAP), ("\npci_attach_hook:"));
>   
> *************** pci_attach_hook(parent, self, pba)
> *** 144,152 ****
>   		/* if there isn't any "interrupts" then we don't care to fix it */
>   		ip = NULL;
>   		if (getprop(node, "interrupts", sizeof(int), &n, (void **)&ip))
> ! 			continue;
>   		DPRINTF(SPDB_INTFIX, (" got interrupts"));
> ! 		
>   		/* and if there isn't an "assigned-addresses" we can't find b/d/f */
>   		if (getprop(node, "assigned-addresses", sizeof(int), &n,
>   		    (void **)&ap))
> --- 144,152 ----
>   		/* if there isn't any "interrupts" then we don't care to fix it */
>   		ip = NULL;
>   		if (getprop(node, "interrupts", sizeof(int), &n, (void **)&ip))
> ! 			goto enable_iomem;
>   		DPRINTF(SPDB_INTFIX, (" got interrupts"));
> ! 
>   		/* and if there isn't an "assigned-addresses" we can't find b/d/f */
>   		if (getprop(node, "assigned-addresses", sizeof(int), &n,
>   		    (void **)&ap))
> *************** pci_attach_hook(parent, self, pba)
> *** 167,172 ****
> --- 167,179 ----
>   
>   		tag = pci_make_tag(pc, bus, dev, fn);
>   
> + 		/* if "interrupts" <= 4, we must do the fixup, otherwise, it's done */
> + 		if (*ip > 5) {
> + 			real_intr = *ip;
> + 			i = -1;
> + 			goto found_intr;
> + 		}
> + 
>   		DPRINTF(SPDB_INTFIX, ("; tag %08x\n\t; reg: hi %x mid %x lo %x intr %x", tag, pr->phys_hi, pr->phys_
> mid, pr->phys_lo, *ip));
>   		DPRINTF(SPDB_INTFIX, ("\n\t; intmapmask: hi %x mid %x lo %x intr %x", pp->pp_intmapmask.phys_hi, pp-
> >pp_intmapmask.phys_mid,
>   										      pp->pp_intmapmask.phys_lo, pp-
> >pp_intmapmask.intr));
> *************** pci_attach_hook(parent, self, pba)
> *** 179,229 ****
>   		DPRINTF(SPDB_INTFIX, ("\n\t; after: hi %x mid %x lo %x intr %x", hi, mid, lo, intr));
>   
>   		for (i = 0; i < pp->pp_nintmap; i++) {
> ! 			DPRINTF(SPDB_INTFIX, ("\n\t\tmatching for: hi %x mid %x lo %x intr %x", pp->pp_intmap[i].phy
> s_hi, pp->pp_intmap[i].phys_mid,
> ! 												pp->pp_intmap[i].phy
> s_lo, pp->pp_intmap[i].intr));
>   
>   			if (pp->pp_intmap[i].phys_hi != hi ||
>   			    pp->pp_intmap[i].phys_mid != mid ||
>   			    pp->pp_intmap[i].phys_lo != lo ||
> ! 			    pp->pp_intmap[i].intr != intr)
>   				continue;
> ! 			DPRINTF(SPDB_INTFIX, ("... BINGO! ..."));
> ! 			
> ! 		bingo:
>   			/*
>   			 * OK!  we found match.  pull out the old interrupt
>   			 * register, patch in the new value, and put it back.
>   			 */
>   			intr = pci_conf_read(pc, tag, PCI_INTERRUPT_REG);
> ! 			DPRINTF(SPDB_INTFIX, ("\n\t    ; read %x from intreg", intr));
> ! 
> ! 			intr = (intr & ~PCI_INTERRUPT_LINE_MASK) |
> ! 			       (pp->pp_intmap[i].child_intr & PCI_INTERRUPT_LINE_MASK);
> ! 			DPRINTF((SPDB_INTFIX|SPDB_INTMAP), ("\n\t    ; gonna write %x to intreg", intr));
>   			pci_conf_write(pc, tag, PCI_INTERRUPT_REG, intr);
> ! 			DPRINTF((SPDB_INTFIX|SPDB_INTMAP), ("\n\t    ; reread %x from intreg", intr));
>   			break;
> - 		}
> - 		if (i == pp->pp_nintmap) {
> - 			/*
> - 			 * Not matched by parent interrupt map. If the
> - 			 * interrupt property has the INTMAP_OBIO bit
> - 			 * set, assume the PROM has (wrongly) supplied it
> - 			 * in the parent's bus format, rather than as a
> - 			 * PCI interrupt line number.
> - 			 *
> - 			 * This seems to be an issue only with the
> - 			 * psycho host-to-pci bridge.
> - 			 */
> - 			if (pp->pp_sc->sc_mode == PSYCHO_MODE_PSYCHO &&
> - 			    (*ip & INTMAP_OBIO) != 0) {
> - 				DPRINTF((SPDB_INTFIX|SPDB_INTMAP),
> - 		("\n\t; PSYCHO: no match but obio interrupt in parent format"));
> - 
> - 				i = -1; goto bingo; /* XXX - hackish.. */
> - 			}
>   		}
>   
>   		/* enable mem & dma if not already */
>   		pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG,
>   			PCI_COMMAND_MEM_ENABLE|PCI_COMMAND_MASTER_ENABLE|PCI_COMMAND_IO_ENABLE);
> --- 186,223 ----
>   		DPRINTF(SPDB_INTFIX, ("\n\t; after: hi %x mid %x lo %x intr %x", hi, mid, lo, intr));
>   
>   		for (i = 0; i < pp->pp_nintmap; i++) {
> ! 			DPRINTF(SPDB_INTFIX, ("\n\t\tmatching for: hi %x mid %x lo %x intr %x child_intr %x", pp->pp
> _intmap[i].phys_hi, pp->pp_intmap[i].phys_mid,
> ! 												pp->pp_intmap[i].phy
> s_lo, pp->pp_intmap[i].intr, pp->pp_intmap[i].child_intr));
>   
>   			if (pp->pp_intmap[i].phys_hi != hi ||
>   			    pp->pp_intmap[i].phys_mid != mid ||
>   			    pp->pp_intmap[i].phys_lo != lo ||
> ! 			    (pp->pp_intmap[i].intr != intr && pp->pp_intmap[i].child_intr != intr))
>   				continue;
> ! 
> ! 			if (pp->pp_intmap[i].child_intr == intr)
> ! 				DPRINTF(SPDB_INTFIX, ("... BINGO! found it in child_intr ..."));
> ! 			else
> ! 				DPRINTF(SPDB_INTFIX, ("... BINGO! found it in intr ..."));
> ! 			real_intr = pp->pp_intmap[i].child_intr;
> ! 
> ! 		found_intr:
>   			/*
>   			 * OK!  we found match.  pull out the old interrupt
>   			 * register, patch in the new value, and put it back.
>   			 */
>   			intr = pci_conf_read(pc, tag, PCI_INTERRUPT_REG);
> ! 			DPRINTF(SPDB_INTFIX, ("\t    ; read %x from intreg\n", intr));
> ! 			intr = (intr & ~PCI_INTERRUPT_LINE_MASK) | (real_intr & PCI_INTERRUPT_LINE_MASK);
> ! 			DPRINTF((SPDB_INTFIX|SPDB_INTMAP), ("\t    ; gonna write %x to intreg\n", intr));
>   			pci_conf_write(pc, tag, PCI_INTERRUPT_REG, intr);
> ! 			DPRINTF((SPDB_INTFIX|SPDB_INTMAP), ("\t    ; reread %x from intreg\n", intr));
>   			break;
>   		}
> + 		if (i == pp->pp_nintmap)
> + 			printf("%s: could not find interrupts vector!", self->dv_xname);
>   
> + enable_iomem:
>   		/* enable mem & dma if not already */
>   		pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG,
>   			PCI_COMMAND_MEM_ENABLE|PCI_COMMAND_MASTER_ENABLE|PCI_COMMAND_IO_ENABLE);