Date: Fri, 30 May 2003 15:24:57 +0300 From: Marian Dobre <mari@onix.ro> To: Thomas Moestl <t.moestl@tu-bs.de> Cc: freebsd-sparc64@freebsd.org Subject: Re: PLEASE TEST: interrupt assignment patch Message-ID: <3ED74D99.7080308@onix.ro> References: <20030529113731.GB630@crow.dom2ip.de>
next in thread | previous in thread | raw e-mail | index | archive | help
Hello,
I can't compile the kernel after I applied the patch on my E450.
This is the error I'm getting.
rib/ipfilter -D_KERNEL -include opt_global.h -mcmodel=medlow
-msoft-float -fno-common -ffreestanding -Werror
/usr/src/sys/sparc64/pci/ofw_pci.c
/usr/src/sys/sparc64/pci/ofw_pci.c:76: conflicting types for
`ofw_pci_orb_callback'
/usr/src/sys/sparc64/pci/ofw_pci.h:74: previous declaration of
`ofw_pci_orb_callback'
/usr/src/sys/sparc64/pci/ofw_pci.c: In function `ofw_pci_orb_callback':
/usr/src/sys/sparc64/pci/ofw_pci.c:92: `slot' undeclared (first use in
this function)
/usr/src/sys/sparc64/pci/ofw_pci.c:92: (Each undeclared identifier is
reported only once
/usr/src/sys/sparc64/pci/ofw_pci.c:92: for each function it appears in.)
/usr/src/sys/sparc64/pci/ofw_pci.c:94: `found' undeclared (first use in
this function)
cc1: warnings being treated as errors
/usr/src/sys/sparc64/pci/ofw_pci.c: In function `ofw_pci_route_intr':
/usr/src/sys/sparc64/pci/ofw_pci.c:110: warning: passing arg 3 of
`ofw_bus_route_intr' from incompatible pointer type
*** Error code 1
Stop in /usr/obj/usr/src/sys/CUSTOM.
*** Error code 1
Stop in /usr/src.
*** Error code 1
Stop in /usr/src.
I'll try to remove the kernel sources and start fresh but I dont think
that will help.
Marian
Thomas Moestl wrote:
> Hi,
>
> I would like to get the attached patch into 5.1; although I am quite
> confident that it will not break anything, we need a good test coverage
> (i.e. testing on many different models) to make sure this is the case,
> since we are that close to a release.
>
> Therefore, I would very much appreciate if people could give this a
> spin on their machines and report back.
>
> The aim of the patch is to fix the interrupt assignment on e450s; it
> should not have any effect on other boxen. It has been tested so far
> on two e450s, a Blade 100 and an u60.
>
> Thanks,
> - Thomas
>
>
>
> ------------------------------------------------------------------------
>
> Index: ebus/ebus.c
> ===================================================================
> RCS file: /vol/ncvs/src/sys/sparc64/ebus/ebus.c,v
> retrieving revision 1.7
> diff -u -r1.7 ebus.c
> --- ebus/ebus.c 19 Feb 2003 05:47:44 -0000 1.7
> +++ ebus/ebus.c 23 May 2003 10:53:26 -0000
> @@ -112,7 +112,7 @@
> u_long, u_long, u_long, u_int);
> static struct resource_list *ebus_get_resource_list(device_t, device_t);
>
> -static struct ebus_devinfo *ebus_setup_dinfo(struct ebus_softc *,
> +static struct ebus_devinfo *ebus_setup_dinfo(device_t, struct ebus_softc *,
> phandle_t, char *);
> static void ebus_destroy_dinfo(struct ebus_devinfo *);
> static int ebus_print_res(struct ebus_devinfo *);
> @@ -200,7 +200,7 @@
> if ((OF_getprop_alloc(node, "name", 1, (void **)&cname)) == -1)
> continue;
>
> - if ((edi = ebus_setup_dinfo(sc, node, cname)) == NULL) {
> + if ((edi = ebus_setup_dinfo(dev, sc, node, cname)) == NULL) {
> device_printf(dev, "<%s>: incomplete\n", cname);
> free(cname, M_OFWPROP);
> continue;
> @@ -363,7 +363,8 @@
> }
>
> static struct ebus_devinfo *
> -ebus_setup_dinfo(struct ebus_softc *sc, phandle_t node, char *name)
> +ebus_setup_dinfo(device_t dev, struct ebus_softc *sc, phandle_t node,
> + char *name)
> {
> struct ebus_devinfo *edi;
> struct isa_regs *reg;
> @@ -398,7 +399,8 @@
> nintr = OF_getprop_alloc(node, "interrupts", sizeof(*intrs),
> (void **)&intrs);
> for (i = 0; i < nintr; i++) {
> - intr = ofw_bus_route_intr(node, intrs[i], ofw_pci_orb_callback);
> + intr = ofw_bus_route_intr(node, intrs[i], ofw_pci_orb_callback,
> + dev);
> if (intr == ORIR_NOTFOUND) {
> panic("ebus_setup_dinfo: could not map ebus "
> "interrupt %d", intrs[i]);
> Index: include/ofw_bus.h
> ===================================================================
> RCS file: /vol/ncvs/src/sys/sparc64/include/ofw_bus.h,v
> retrieving revision 1.3
> diff -u -r1.3 ofw_bus.h
> --- include/ofw_bus.h 7 Nov 2002 16:07:46 -0000 1.3
> +++ include/ofw_bus.h 23 May 2003 10:53:26 -0000
> @@ -32,8 +32,8 @@
> #define ORIR_NOTFOUND 0xffffffff
>
> typedef int obr_callback_t(phandle_t, u_int8_t *, int, u_int8_t *, int,
> - u_int8_t **, int *);
> + u_int8_t **, int *, void *);
>
> -u_int32_t ofw_bus_route_intr(phandle_t, int, obr_callback_t *);
> +u_int32_t ofw_bus_route_intr(phandle_t, int, obr_callback_t *, void *);
>
> #endif /* !_MACHINE_OFW_BUS_H_ */
> Index: isa/isa.c
> ===================================================================
> RCS file: /vol/ncvs/src/sys/sparc64/isa/isa.c,v
> retrieving revision 1.5
> diff -u -r1.5 isa.c
> --- isa/isa.c 7 Nov 2002 16:07:46 -0000 1.5
> +++ isa/isa.c 23 May 2003 10:53:26 -0000
> @@ -134,7 +134,7 @@
> if (ino > 7)
> panic("isa_init: XXX: ino too large");
> isa_ino[ino] = ofw_bus_route_intr(node, ino,
> - ofw_pci_orb_callback);
> + ofw_pci_orb_callback, dev);
> }
>
> for (nbr -= 1; nbr >= 0; nbr--) {
> Index: pci/ofw_pci.c
> ===================================================================
> RCS file: /vol/ncvs/src/sys/sparc64/pci/ofw_pci.c,v
> retrieving revision 1.10
> diff -u -r1.10 ofw_pci.c
> --- pci/ofw_pci.c 27 Mar 2003 02:01:59 -0000 1.10
> +++ pci/ofw_pci.c 27 May 2003 11:55:48 -0000
> @@ -46,44 +46,90 @@
>
> #include <sparc64/pci/ofw_pci.h>
>
> +#include <machine/bus.h>
> #include <machine/cache.h>
> #include <machine/iommureg.h>
> #include <machine/ofw_bus.h>
> #include <machine/ver.h>
>
> #include "pcib_if.h"
> +#include "sparcbus_if.h"
>
> u_int8_t pci_bus_cnt;
> phandle_t *pci_bus_map;
> int pci_bus_map_sz;
>
> -#define OPQ_NO_SWIZZLE 1
> +/* Do not swizzle on a PCI bus node with no interrupt-map propery. */
> +#define OPQ_NO_SWIZZLE 1
> +/*
> + * INOs < 255 are really intpin numbers; use a driver method to figure out
> + * the real INO.
> + */
> +#define OPQ_INO_CALLBACK 2
> +/*
> + * Do not map EBus interrupts at PCI buses, but assume that they are fully
> + * specified already.
> + */
> +#define OPQ_EBUS_NOMAP 4
> +
> static struct ofw_pci_quirk {
> char *opq_model;
> int opq_quirks;
> } ofw_pci_quirks[] = {
> - { "SUNW,Ultra-4", OPQ_NO_SWIZZLE },
> - { "SUNW,Ultra-1-Engine", OPQ_NO_SWIZZLE },
> + { "SUNW,Ultra-4", OPQ_INO_CALLBACK | OPQ_EBUS_NOMAP },
> + { "SUNW,Ultra-1-Engine", OPQ_NO_SWIZZLE },
> };
> #define OPQ_NENT (sizeof(ofw_pci_quirks) / sizeof(ofw_pci_quirks[0]))
>
> static int pci_quirks;
>
> #define OFW_PCI_PCIBUS "pci"
> +#define OFW_PCI_EBUS "ebus"
> #define PCI_BUS_MAP_INC 10
>
> int
> ofw_pci_orb_callback(phandle_t node, u_int8_t *pintptr, int pintsz,
> - u_int8_t *pregptr, int pregsz, u_int8_t **rintr, int *terminate)
> + u_int8_t *pregptr, int pregsz, u_int8_t **rintr, int *terminate,
> + void *cookie)
> {
> + device_t dev = cookie;
> struct ofw_pci_register preg;
> u_int32_t pintr, intr;
> + u_int slot;
> char type[32];
> + int found = 0;
>
> - if (pintsz != sizeof(u_int32_t))
> + if ((pci_quirks & OPQ_EBUS_NOMAP) != 0 &&
> + OF_getprop(node, "name", type, sizeof(type)) != -1 &&
> + strcmp(type, OFW_PCI_EBUS) == 0) {
> + *terminate = 1;
> + return (-1);
> + }
> + if (pintsz != sizeof(u_int32_t) || pregsz < sizeof(preg))
> return (-1);
> bcopy(pintptr, &pintr, sizeof(pintr));
> - if ((pci_quirks & OPQ_NO_SWIZZLE) == 0 && pregsz >= sizeof(preg) &&
> + bcopy(pregptr, &preg, sizeof(preg));
> + slot = OFW_PCI_PHYS_HI_DEVICE(preg.phys_hi);
> +
> + if ((pci_quirks & OPQ_INO_CALLBACK) != 0 && pintr <= 255) {
> + /*
> + * The e450 has no interrupt maps at all, and it usually has
> + * full interrupt numbers, including IGN, in the interrupt
> + * properties. There is one exception, however: the property
> + * values for external PCI devices seem to always be below 255
> + * and describe the interrupt pin to be used on the slot, while
> + * we have to figure out the base INO by looking at the slot
> + * number (which we do using a sparcbus method).
> + *
> + * Of course, there is an exception to that nice rule:
> + * in the ebus case, the interrupt property has the correct
> + * INO (but without IGN). This is dealt with above.
> + */
> + intr = SPARCBUS_GUESS_INO(dev, node, slot, pintr);
> + found = intr != 255;
> + *terminate = found;
> + }
> + if (!found && (pci_quirks & OPQ_NO_SWIZZLE) == 0 &&
> OF_getprop(node, "device_type", type, sizeof(type)) != -1 &&
> strcmp(type, OFW_PCI_PCIBUS) == 0 && pintr >= 1 && pintr <= 4) {
> /*
> @@ -91,29 +137,31 @@
> * PCI bridges without interrupt maps, where we apparently must
> * do the PCI swizzle and continue to map on at the parent.
> */
> - bcopy(pregptr, &preg, sizeof(preg));
> - intr = (OFW_PCI_PHYS_HI_DEVICE(preg.phys_hi) + pintr + 3) %
> - 4 + 1;
> + intr = (slot + pintr + 3) % 4 + 1;
> + *terminate = 0;
> + found = 1;
> + }
> +
> + if (found) {
> *rintr = malloc(sizeof(intr), M_OFWPROP, M_WAITOK);
> bcopy(&intr, *rintr, sizeof(intr));
> - *terminate = 0;
> return (sizeof(intr));
> - }
> - return (-1);
> + } else
> + return (-1);
> }
>
> -u_int32_t
> -ofw_pci_route_intr(phandle_t node, u_int32_t ign)
> +static u_int32_t
> +ofw_pci_route_intr(device_t dev, phandle_t node, u_int32_t ign)
> {
> u_int32_t rv;
>
> - rv = ofw_bus_route_intr(node, ORIP_NOINT, ofw_pci_orb_callback);
> + rv = ofw_bus_route_intr(node, ORIP_NOINT, ofw_pci_orb_callback, dev);
> if (rv == ORIR_NOTFOUND)
> return (255);
> /*
> - * Some machines (notably the SPARCengine Ultra AX) have no mappings
> - * at all, but use complete interrupt vector number including the IGN.
> - * Catch this case and remove the IGN.
> + * Some machines (notably the SPARCengine Ultra AX and the e450) have
> + * no mappings at all, but use complete interrupt vector number
> + * including the IGN. Catch this case and remove the IGN.
> */
> if (rv > ign)
> rv -= ign;
> @@ -273,7 +321,7 @@
> }
>
> /* Initialize the intline registers. */
> - if ((intr = ofw_pci_route_intr(node, ign)) != 255) {
> + if ((intr = ofw_pci_route_intr(dev, node, ign)) != 255) {
> #ifdef OFW_PCI_DEBUG
> device_printf(dev, "%s: mapping intr for "
> "%d/%d/%d to %d (preset was %d)\n",
> Index: pci/ofw_pci.h
> ===================================================================
> RCS file: /vol/ncvs/src/sys/sparc64/pci/ofw_pci.h,v
> retrieving revision 1.4
> diff -u -r1.4 ofw_pci.h
> --- pci/ofw_pci.h 7 Nov 2002 16:07:46 -0000 1.4
> +++ pci/ofw_pci.h 23 May 2003 10:53:26 -0000
> @@ -71,7 +71,6 @@
> struct ofw_pci_bdesc *obd_super;
> };
>
> -u_int32_t ofw_pci_route_intr(phandle_t, u_int32_t);
> obr_callback_t ofw_pci_orb_callback;
> u_int8_t ofw_pci_alloc_busno(phandle_t);
> ofw_pci_binit_t ofw_pci_binit;
> Index: pci/psycho.c
> ===================================================================
> RCS file: /vol/ncvs/src/sys/sparc64/pci/psycho.c,v
> retrieving revision 1.32
> diff -u -r1.32 psycho.c
> --- pci/psycho.c 2 May 2003 01:21:36 -0000 1.32
> +++ pci/psycho.c 23 May 2003 10:53:26 -0000
> @@ -144,6 +144,7 @@
> int);
> static int psycho_route_interrupt(device_t, device_t, int);
> static int psycho_intr_pending(device_t, int);
> +static u_int32_t psycho_guess_ino(device_t, phandle_t, u_int, u_int);
> static bus_space_handle_t psycho_get_bus_handle(device_t dev, enum sbbt_id id,
> bus_space_handle_t childhdl, bus_space_tag_t *tag);
>
> @@ -170,6 +171,7 @@
>
> /* sparcbus interface */
> DEVMETHOD(sparcbus_intr_pending, psycho_intr_pending),
> + DEVMETHOD(sparcbus_guess_ino, psycho_guess_ino),
> DEVMETHOD(sparcbus_get_bus_handle, psycho_get_bus_handle),
>
> { 0, 0 }
> @@ -339,7 +341,6 @@
> struct upa_regs *reg;
> struct ofw_pci_bdesc obd;
> struct psycho_desc *desc;
> - vm_paddr_t pcictl_offs;
> phandle_t node;
> u_int64_t csr;
> u_long mlen;
> @@ -377,13 +378,25 @@
> panic("psycho_attach: %d not enough registers", nreg);
> sc->sc_basepaddr = (vm_paddr_t)UPA_REG_PHYS(®[2]);
> mlen = UPA_REG_SIZE(®[2]);
> - pcictl_offs = UPA_REG_PHYS(®[0]);
> + sc->sc_pcictl = UPA_REG_PHYS(®[0]) - sc->sc_basepaddr;
> + switch (sc->sc_pcictl) {
> + case PSR_PCICTL0:
> + sc->sc_half = 0;
> + break;
> + case PSR_PCICTL1:
> + sc->sc_half = 1;
> + break;
> + default:
> + panic("psycho_attach: bogus pci control register "
> + "location");
> + }
> } else {
> if (nreg <= 0)
> panic("psycho_attach: %d not enough registers", nreg);
> sc->sc_basepaddr = (vm_paddr_t)UPA_REG_PHYS(®[0]);
> mlen = UPA_REG_SIZE(reg);
> - pcictl_offs = sc->sc_basepaddr + PSR_PCICTL0;
> + sc->sc_pcictl = PSR_PCICTL0;
> + sc->sc_half = 0;
> }
>
> /*
> @@ -418,17 +431,14 @@
> sc->sc_bustag = osc->sc_bustag;
> sc->sc_bushandle = osc->sc_bushandle;
> }
> - if (pcictl_offs < sc->sc_basepaddr)
> - panic("psycho_attach: bogus pci control register location");
> - sc->sc_pcictl = pcictl_offs - sc->sc_basepaddr;
> csr = PSYCHO_READ8(sc, PSR_CS);
> sc->sc_ign = 0x7c0; /* APB IGN is always 0x7c */
> if (sc->sc_mode == PSYCHO_MODE_PSYCHO)
> sc->sc_ign = PSYCHO_GCSR_IGN(csr) << 6;
>
> - device_printf(dev, "%s, impl %d, version %d, ign %#x\n",
> + device_printf(dev, "%s, impl %d, version %d, ign %#x, bus %c\n",
> desc->pd_name, (int)PSYCHO_GCSR_IMPL(csr),
> - (int)PSYCHO_GCSR_VERS(csr), sc->sc_ign);
> + (int)PSYCHO_GCSR_VERS(csr), sc->sc_ign, 'A' + sc->sc_half);
>
> /*
> * Setup the PCI control register
> @@ -1275,6 +1285,31 @@
> return (0);
> }
> return (diag != 0);
> +}
> +
> +static u_int32_t
> +psycho_guess_ino(device_t dev, phandle_t node, u_int slot, u_int pin)
> +{
> + struct psycho_softc *sc = (struct psycho_softc *)device_get_softc(dev);
> + bus_addr_t intrmap;
> +
> + /*
> + * If this is not for one of our direct children (i.e. we are mapping
> + * at our node), tell the interrupt mapper to go on - we need the
> + * slot number of the device or it's topmost parent bridge to guess
> + * the INO.
> + */
> + if (node != sc->sc_node)
> + return (255);
> + /*
> + * Actually guess the INO. We always assume that this is a non-OBIO
> + * device, and use from the slot number to determine it.
> + * We only need to do this on e450s, it seems; here, the slot numbers
> + * for bus A are one-based, while those for bus B seemingly have an
> + * offset of 2 (hence the factor of 3 below).
> + */
> + intrmap = PSR_PCIA0_INT_MAP + 8 * (slot - 1 + 3 * sc->sc_half);
> + return (INTINO(PSYCHO_READ8(sc, intrmap)) + pin - 1);
> }
>
> static bus_space_handle_t
> Index: pci/psychovar.h
> ===================================================================
> RCS file: /vol/ncvs/src/sys/sparc64/pci/psychovar.h,v
> retrieving revision 1.7
> diff -u -r1.7 psychovar.h
> --- pci/psychovar.h 8 Apr 2003 06:35:08 -0000 1.7
> +++ pci/psychovar.h 23 May 2003 10:53:26 -0000
> @@ -61,6 +61,9 @@
> #define PSYCHO_MODE_SABRE 1
> #define PSYCHO_MODE_PSYCHO 2
>
> + /* Bus A or B of a psycho pair? */
> + int sc_half;
> +
> struct iommu_state *sc_is;
> u_int32_t sc_dvmabase;
>
> Index: sparc64/ofw_bus.c
> ===================================================================
> RCS file: /vol/ncvs/src/sys/sparc64/sparc64/ofw_bus.c,v
> retrieving revision 1.5
> diff -u -r1.5 ofw_bus.c
> --- sparc64/ofw_bus.c 19 Feb 2003 05:47:45 -0000 1.5
> +++ sparc64/ofw_bus.c 23 May 2003 10:53:26 -0000
> @@ -160,7 +160,7 @@
> * This should work for all bus systems.
> */
> u_int32_t
> -ofw_bus_route_intr(phandle_t node, int intrp, obr_callback_t *cb)
> +ofw_bus_route_intr(phandle_t node, int intrp, obr_callback_t *cb, void *cookie)
> {
> u_int8_t *reg, *intr, *tintr, *imap, *imapmsk;
> phandle_t parent;
> @@ -201,7 +201,7 @@
> */
> if (cb != NULL) {
> tisz = cb(parent, intr, isz, reg, regsz, &tintr,
> - &found);
> + &found, cookie);
> if (tisz != -1) {
> isz = tisz;
> free(intr, M_OFWPROP);
> Index: sparc64/sparcbus_if.m
> ===================================================================
> RCS file: /vol/ncvs/src/sys/sparc64/sparc64/sparcbus_if.m,v
> retrieving revision 1.1
> diff -u -r1.1 sparcbus_if.m
> --- sparc64/sparcbus_if.m 9 Nov 2001 20:43:44 -0000 1.1
> +++ sparc64/sparcbus_if.m 23 May 2003 10:53:26 -0000
> @@ -26,6 +26,8 @@
> #include <sys/bus.h>
> #include <machine/bus.h>
>
> +#include <dev/ofw/openfirm.h>
> +
> INTERFACE sparcbus;
>
> HEADER {
> @@ -37,10 +39,6 @@
> };
>
> CODE {
> - static int sparcbus_default_intr_pending(device_t, int);
> - static bus_space_handle_t sparcbus_default_get_bus_handle(device_t,
> - enum sbbt_id, bus_space_handle_t childhdl, bus_space_tag_t *tag);
> -
> static int
> sparcbus_default_intr_pending(device_t dev, int intr)
> {
> @@ -48,6 +46,15 @@
> return (SPARCBUS_INTR_PENDING(device_get_parent(dev), intr));
> }
>
> + static u_int32_t
> + sparcbus_default_guess_ino(device_t dev, phandle_t node, u_int slot,
> + u_int pin)
> + {
> +
> + return (SPARCBUS_GUESS_INO(device_get_parent(dev), node, slot,
> + pin));
> + }
> +
> static bus_space_handle_t
> sparcbus_default_get_bus_handle(device_t dev, enum sbbt_id id,
> bus_space_handle_t childhdl, bus_space_tag_t *tag)
> @@ -63,6 +70,17 @@
> device_t dev;
> int intr;
> } DEFAULT sparcbus_default_intr_pending;
> +
> +# Let the bus driver guess the INO of the device at the given slot and intpin
> +# on the bus described by the node if it could not be determined from the
> +# firmware properties. Returns 255 if no INO could be found (mapping will
> +# continue at the parent), or the desired INO.
> +METHOD u_int32_t guess_ino {
> + device_t dev;
> + phandle_t node;
> + u_int slot;
> + u_int pin;
> +} DEFAULT sparcbus_default_guess_ino;
>
> # Get the bustag for the root bus. This is needed for ISA old-stlye
> # in[bwl]()/out[bwl]() support, where no tag retrieved from a resource is
>
>
> ------------------------------------------------------------------------
>
> _______________________________________________
> freebsd-sparc64@freebsd.org mailing list
> http://lists.freebsd.org/mailman/listinfo/freebsd-sparc64
> To unsubscribe, send any mail to "freebsd-sparc64-unsubscribe@freebsd.org"
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?3ED74D99.7080308>
