xref: /netbsd-src/sys/arch/sparc64/dev/ebus_mainbus.c (revision cdc507f0d27576e5c4f30629a5cfe9e1f5271dbe)
1*cdc507f0Sandvar /*	$NetBSD: ebus_mainbus.c,v 1.23 2022/05/24 20:50:19 andvar Exp $	*/
25b208c27Smrg /*	$OpenBSD: ebus_mainbus.c,v 1.7 2010/11/11 17:58:23 miod Exp $	*/
35b208c27Smrg 
45b208c27Smrg /*
55b208c27Smrg  * Copyright (c) 2007 Mark Kettenis
65b208c27Smrg  *
75b208c27Smrg  * Permission to use, copy, modify, and distribute this software for any
85b208c27Smrg  * purpose with or without fee is hereby granted, provided that the above
95b208c27Smrg  * copyright notice and this permission notice appear in all copies.
105b208c27Smrg  *
115b208c27Smrg  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
125b208c27Smrg  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
135b208c27Smrg  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
145b208c27Smrg  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
155b208c27Smrg  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
165b208c27Smrg  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
175b208c27Smrg  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
185b208c27Smrg  */
195b208c27Smrg 
20f72d1cdaSmrg #include <sys/cdefs.h>
21*cdc507f0Sandvar __KERNEL_RCSID(0, "$NetBSD: ebus_mainbus.c,v 1.23 2022/05/24 20:50:19 andvar Exp $");
22f72d1cdaSmrg 
235b208c27Smrg #ifdef DEBUG
245b208c27Smrg #define	EDB_PROM	0x01
255b208c27Smrg #define EDB_CHILD	0x02
265b208c27Smrg #define	EDB_INTRMAP	0x04
275b208c27Smrg #define EDB_BUSMAP	0x08
285b208c27Smrg #define EDB_BUSDMA	0x10
295b208c27Smrg #define EDB_INTR	0x20
305b208c27Smrg extern int ebus_debug;
315b208c27Smrg #define DPRINTF(l, s)   do { if (ebus_debug & l) printf s; } while (0)
325b208c27Smrg #else
335b208c27Smrg #define DPRINTF(l, s)
345b208c27Smrg #endif
355b208c27Smrg 
365b208c27Smrg #include <sys/param.h>
375b208c27Smrg #include <sys/conf.h>
385b208c27Smrg #include <sys/device.h>
395b208c27Smrg #include <sys/errno.h>
405b208c27Smrg #include <sys/extent.h>
41fc256c4aSthorpej #include <sys/kmem.h>
425b208c27Smrg #include <sys/systm.h>
435b208c27Smrg #include <sys/time.h>
445b208c27Smrg 
455b208c27Smrg #define _SPARC_BUS_DMA_PRIVATE
46b6584574Sdyoung #include <sys/bus.h>
475b208c27Smrg #include <machine/autoconf.h>
485b208c27Smrg #include <machine/openfirm.h>
495b208c27Smrg 
505b208c27Smrg #include <dev/pci/pcivar.h>
515b208c27Smrg 
525b208c27Smrg #include <sparc64/dev/iommureg.h>
53a1b3c3f0Smrg #include <sparc64/dev/iommuvar.h>
545b208c27Smrg #include <sparc64/dev/pyrovar.h>
55a1b3c3f0Smrg #include <dev/ebus/ebusreg.h>
56a1b3c3f0Smrg #include <dev/ebus/ebusvar.h>
57a1b3c3f0Smrg #include <sparc64/dev/ebusvar.h>
585b208c27Smrg 
5955c42a93Spalle #include "ioconf.h"
60f1503a8dSpalle 
61d92ab1d4Schristos int	ebus_mainbus_match(device_t, cfdata_t, void *);
62d92ab1d4Schristos void	ebus_mainbus_attach(device_t, device_t, void *);
635b208c27Smrg 
64d92ab1d4Schristos CFATTACH_DECL_NEW(ebus_mainbus, sizeof(struct ebus_softc),
65a1b3c3f0Smrg     ebus_mainbus_match, ebus_mainbus_attach, NULL, NULL);
665b208c27Smrg 
6710a9f073Smrg static int ebus_mainbus_bus_map(bus_space_tag_t, bus_addr_t, bus_size_t, int,
68a1b3c3f0Smrg 	vaddr_t, bus_space_handle_t *);
6910a9f073Smrg static void *ebus_mainbus_intr_establish(bus_space_tag_t, int, int,
70a1b3c3f0Smrg 	int (*)(void *), void *, void (*)(void));
7110a9f073Smrg static bus_space_tag_t ebus_mainbus_alloc_bus_tag(struct ebus_softc *,
7210a9f073Smrg 	bus_space_tag_t, int);
7310a9f073Smrg #ifdef SUN4V
74418e019bSpalle #if 0
75418e019bSpalle XXX
7610a9f073Smrg static void ebus_mainbus_intr_ack(struct intrhand *);
7710a9f073Smrg #endif
78418e019bSpalle #endif
795b208c27Smrg int
ebus_mainbus_match(device_t parent,cfdata_t cf,void * aux)80cbab9cadSchs ebus_mainbus_match(device_t parent, cfdata_t cf, void *aux)
815b208c27Smrg {
825b208c27Smrg 	struct mainbus_attach_args *ma = aux;
835b208c27Smrg 
845b208c27Smrg 	if (strcmp(ma->ma_name, "ebus") == 0)
855b208c27Smrg 		return (1);
865b208c27Smrg 	return (0);
875b208c27Smrg }
885b208c27Smrg 
895b208c27Smrg void
ebus_mainbus_attach(device_t parent,device_t self,void * aux)90cbab9cadSchs ebus_mainbus_attach(device_t parent, device_t self, void *aux)
915b208c27Smrg {
92d92ab1d4Schristos 	struct ebus_softc *sc = device_private(self);
935b208c27Smrg 	struct mainbus_attach_args *ma = aux;
945b208c27Smrg 	struct ebus_attach_args eba;
955b208c27Smrg 	struct ebus_interrupt_map_mask *immp;
965b208c27Smrg 	int node, nmapmask, error;
975b208c27Smrg 	struct pyro_softc *psc;
98f1503a8dSpalle 	int i, j;
995b208c27Smrg 
100d92ab1d4Schristos 	sc->sc_dev = self;
1015b208c27Smrg 
1025b208c27Smrg 	printf("\n");
1035b208c27Smrg 
10410a9f073Smrg 	sc->sc_memtag = ebus_mainbus_alloc_bus_tag(sc, ma->ma_bustag,
10510a9f073Smrg 						   PCI_MEMORY_BUS_SPACE);
10610a9f073Smrg 	sc->sc_iotag = ebus_mainbus_alloc_bus_tag(sc, ma->ma_bustag,
10710a9f073Smrg 						  PCI_IO_BUS_SPACE);
108a1b3c3f0Smrg 	sc->sc_childbustag = sc->sc_memtag;
109a1b3c3f0Smrg 	sc->sc_dmatag = ma->ma_dmatag;
1105b208c27Smrg 
111f1503a8dSpalle 	sc->sc_node = node = ma->ma_node;
112f1503a8dSpalle 
1135b208c27Smrg 	/*
1145b208c27Smrg 	 * fill in our softc with information from the prom
1155b208c27Smrg 	 */
1165b208c27Smrg 	sc->sc_intmap = NULL;
1175b208c27Smrg 	sc->sc_range = NULL;
118a1b3c3f0Smrg 	error = prom_getprop(node, "interrupt-map",
1195b208c27Smrg 			sizeof(struct ebus_interrupt_map),
1205b208c27Smrg 			&sc->sc_nintmap, (void **)&sc->sc_intmap);
1215b208c27Smrg 	switch (error) {
1225b208c27Smrg 	case 0:
1235b208c27Smrg 		immp = &sc->sc_intmapmask;
12410a9f073Smrg 		nmapmask = 1;
125a1b3c3f0Smrg 		error = prom_getprop(node, "interrupt-map-mask",
1265b208c27Smrg 			    sizeof(struct ebus_interrupt_map_mask), &nmapmask,
1275b208c27Smrg 			    (void **)&immp);
1285b208c27Smrg 		if (error)
12910a9f073Smrg 			panic("could not get ebus interrupt-map-mask: error %d",
13010a9f073Smrg 			      error);
1315b208c27Smrg 		if (nmapmask != 1)
1325b208c27Smrg 			panic("ebus interrupt-map-mask is broken");
1335b208c27Smrg 		break;
1345b208c27Smrg 	case ENOENT:
1355b208c27Smrg 		break;
1365b208c27Smrg 	default:
1375b208c27Smrg 		panic("ebus interrupt-map: error %d", error);
1385b208c27Smrg 		break;
1395b208c27Smrg 	}
1405b208c27Smrg 
141f1503a8dSpalle 	/*
142f1503a8dSpalle 	 * Ebus interrupts may be connected to any of the PCI Express
143f1503a8dSpalle 	 * leafs.  Here we add the appropriate IGN to the interrupt
144*cdc507f0Sandvar 	 * mappings such that we can use it to distinguish between
145f1503a8dSpalle 	 * interrupts connected to PCIE-A and PCIE-B.
146f1503a8dSpalle 	 */
147f1503a8dSpalle 	for (i = 0; i < sc->sc_nintmap; i++) {
148f1503a8dSpalle 		for (j = 0; j < pyro_cd.cd_ndevs; j++) {
14955c42a93Spalle 			device_t dt = device_lookup(&pyro_cd, j);
150f1503a8dSpalle 			psc = device_private(dt);
151f1503a8dSpalle 			if (psc && psc->sc_node == sc->sc_intmap[i].cnode) {
152f1503a8dSpalle 				sc->sc_intmap[i].cintr |= psc->sc_ign;
153f1503a8dSpalle 				break;
154f1503a8dSpalle 			}
155f1503a8dSpalle 		}
156f1503a8dSpalle 	}
157f1503a8dSpalle 
158a1b3c3f0Smrg 	error = prom_getprop(node, "ranges", sizeof(struct ebus_mainbus_ranges),
1595b208c27Smrg 	    &sc->sc_nrange, (void **)&sc->sc_range);
1605b208c27Smrg 	if (error)
1615b208c27Smrg 		panic("ebus ranges: error %d", error);
1625b208c27Smrg 
1635b208c27Smrg 	/*
1645b208c27Smrg 	 * now attach all our children
1655b208c27Smrg 	 */
1665b208c27Smrg 	DPRINTF(EDB_CHILD, ("ebus node %08x, searching children...\n", node));
1673944ff70Sthorpej 	devhandle_t selfh = device_handle(self);
1685b208c27Smrg 	for (node = firstchild(node); node; node = nextsibling(node)) {
1695b208c27Smrg 		if (ebus_setup_attach_args(sc, node, &eba) != 0) {
1705b208c27Smrg 			DPRINTF(EDB_CHILD,
1715b208c27Smrg 			    ("ebus_mainbus_attach: %s: incomplete\n",
172a1b3c3f0Smrg 			    prom_getpropstring(node, "name")));
1735b208c27Smrg 			continue;
1745b208c27Smrg 		} else {
1755b208c27Smrg 			DPRINTF(EDB_CHILD, ("- found child `%s', attaching\n",
1765b208c27Smrg 			    eba.ea_name));
17765c738d1Sthorpej 			(void)config_found(self, &eba, ebus_print,
1783944ff70Sthorpej 			    CFARGS(.devhandle = prom_node_to_devhandle(selfh,
1793944ff70Sthorpej 								       node)));
1805b208c27Smrg 		}
1815b208c27Smrg 		ebus_destroy_attach_args(&eba);
1825b208c27Smrg 	}
1835b208c27Smrg }
1845b208c27Smrg 
18510a9f073Smrg static bus_space_tag_t
ebus_mainbus_alloc_bus_tag(struct ebus_softc * sc,bus_space_tag_t parent,int type)18610a9f073Smrg ebus_mainbus_alloc_bus_tag(struct ebus_softc *sc,
18710a9f073Smrg 			   bus_space_tag_t parent,
18810a9f073Smrg 			   int type)
1895b208c27Smrg {
1905b208c27Smrg 	struct sparc_bus_space_tag *bt;
1915b208c27Smrg 
192fc256c4aSthorpej 	bt = kmem_zalloc(sizeof(*bt), KM_SLEEP);
1935b208c27Smrg 	bt->cookie = sc;
1945b208c27Smrg 	bt->parent = parent;
195a1b3c3f0Smrg 	bt->type = type;
1965b208c27Smrg 	bt->sparc_bus_map = ebus_mainbus_bus_map;
197a1b3c3f0Smrg 	bt->sparc_bus_mmap = ebus_bus_mmap;
1985b208c27Smrg 	bt->sparc_intr_establish = ebus_mainbus_intr_establish;
1995b208c27Smrg 
2005b208c27Smrg 	return (bt);
2015b208c27Smrg }
2025b208c27Smrg 
2035b208c27Smrg int
ebus_mainbus_bus_map(bus_space_tag_t t,bus_addr_t offset,bus_size_t size,int flags,vaddr_t va,bus_space_handle_t * hp)204a1b3c3f0Smrg ebus_mainbus_bus_map(bus_space_tag_t t, bus_addr_t offset, bus_size_t size,
205a1b3c3f0Smrg 	int flags, vaddr_t va, bus_space_handle_t *hp)
2065b208c27Smrg {
2075b208c27Smrg 	struct ebus_softc *sc = t->cookie;
2085b208c27Smrg 	struct ebus_mainbus_ranges *range;
2095b208c27Smrg 	bus_addr_t hi, lo;
2108fc5f922Smartin 	int i;
2118fc5f922Smartin #if 0
2128fc5f922Smartin 	int ss;
2138fc5f922Smartin #endif
2145b208c27Smrg 
2155b208c27Smrg 	DPRINTF(EDB_BUSMAP,
2165b208c27Smrg 	    ("\n_ebus_mainbus_bus_map: off %016llx sz %x flags %d",
2175b208c27Smrg 	    (unsigned long long)offset, (int)size, (int)flags));
2185b208c27Smrg 
2195b208c27Smrg 	if (t->parent == 0 || t->parent->sparc_bus_map == 0) {
2205b208c27Smrg 		printf("\n_ebus_mainbus_bus_map: invalid parent");
2215b208c27Smrg 		return (EINVAL);
2225b208c27Smrg 	}
2235b208c27Smrg 
2245b208c27Smrg 	t = t->parent;
2255b208c27Smrg 
2265b208c27Smrg 	hi = offset >> 32UL;
2275b208c27Smrg 	lo = offset & 0xffffffff;
2285b208c27Smrg 	range = (struct ebus_mainbus_ranges *)sc->sc_range;
2295b208c27Smrg 
2305b208c27Smrg 	DPRINTF(EDB_BUSMAP, (" (hi %08x lo %08x)", (u_int)hi, (u_int)lo));
2315b208c27Smrg 	for (i = 0; i < sc->sc_nrange; i++) {
2325b208c27Smrg 		bus_addr_t addr;
2335b208c27Smrg 
2345b208c27Smrg 		if (hi != range[i].child_hi)
2355b208c27Smrg 			continue;
2365b208c27Smrg 		if (lo < range[i].child_lo ||
2375b208c27Smrg 		    (lo + size) > (range[i].child_lo + range[i].size))
2385b208c27Smrg 			continue;
2395b208c27Smrg 
240a1b3c3f0Smrg #if 0
241a1b3c3f0Smrg 		/* Isolate address space and find the right tag */
242a1b3c3f0Smrg 		ss = (range[i].phys_hi>>24)&3;
243a1b3c3f0Smrg 		switch (ss) {
244a1b3c3f0Smrg 		case 1:	/* I/O space */
245a1b3c3f0Smrg 			t = sc->sc_iotag;
246a1b3c3f0Smrg 			break;
247a1b3c3f0Smrg 		case 2:	/* Memory space */
248a1b3c3f0Smrg 			t = sc->sc_memtag;
249a1b3c3f0Smrg 			break;
250a1b3c3f0Smrg 		case 0:	/* Config space */
251a1b3c3f0Smrg 		case 3:	/* 64-bit Memory space */
252a1b3c3f0Smrg 		default: /* WTF? */
253a1b3c3f0Smrg 			/* We don't handle these */
254a1b3c3f0Smrg 			panic("ebus_mainbus_bus_map: illegal space %x", ss);
255a1b3c3f0Smrg 			break;
256a1b3c3f0Smrg 		}
257a1b3c3f0Smrg #endif
258a1b3c3f0Smrg 
2595b208c27Smrg 		addr = ((bus_addr_t)range[i].phys_hi << 32UL) |
2605b208c27Smrg 				    range[i].phys_lo;
2615b208c27Smrg 		addr += lo;
2625b208c27Smrg 		DPRINTF(EDB_BUSMAP,
2635b208c27Smrg 		    ("\n_ebus_mainbus_bus_map: paddr offset %qx addr %qx\n",
2645b208c27Smrg 		    (unsigned long long)offset, (unsigned long long)addr));
265a1b3c3f0Smrg 		return (bus_space_map(t, addr, size, flags, hp));
2665b208c27Smrg 	}
2675b208c27Smrg 	DPRINTF(EDB_BUSMAP, (": FAILED\n"));
2685b208c27Smrg 	return (EINVAL);
2695b208c27Smrg }
2705b208c27Smrg 
27110a9f073Smrg static void *
ebus_mainbus_intr_establish(bus_space_tag_t t,int ihandle,int level,int (* handler)(void *),void * arg,void (* fastvec)(void))272a1b3c3f0Smrg ebus_mainbus_intr_establish(bus_space_tag_t t, int ihandle, int level,
273a1b3c3f0Smrg 	int (*handler)(void *), void *arg, void (*fastvec)(void) /* ignored */)
2745b208c27Smrg {
2755b208c27Smrg 	struct intrhand *ih = NULL;
2765b208c27Smrg 	volatile u_int64_t *intrmapptr = NULL, *intrclrptr = NULL;
277a1b3c3f0Smrg 	u_int64_t *imap, *iclr;
2785b208c27Smrg 	int ino;
2795b208c27Smrg 
280418e019bSpalle #if 0
281418e019bSpalle XXX
2825b208c27Smrg 	if (CPU_ISSUN4V) {
2835b208c27Smrg 		struct upa_reg reg;
2845b208c27Smrg 		u_int64_t devhandle, devino = INTINO(ihandle);
2855b208c27Smrg 		u_int64_t sysino;
2865b208c27Smrg 		int node = -1;
2875b208c27Smrg 		int i, err;
2885b208c27Smrg 
2895b208c27Smrg 		for (i = 0; i < sc->sc_nintmap; i++) {
2905b208c27Smrg 			if (sc->sc_intmap[i].cintr == ihandle) {
2915b208c27Smrg 				node = sc->sc_intmap[i].cnode;
2925b208c27Smrg 				break;
2935b208c27Smrg 			}
2945b208c27Smrg 		}
2955b208c27Smrg 		if (node == -1)
2965b208c27Smrg 			return (NULL);
2975b208c27Smrg 
2985b208c27Smrg 		if (OF_getprop(node, "reg", &reg, sizeof(reg)) != sizeof(reg))
2995b208c27Smrg 			return (NULL);
3005b208c27Smrg 		devhandle = (reg.ur_paddr >> 32) & 0x0fffffff;
3015b208c27Smrg 
3025b208c27Smrg 		err = hv_intr_devino_to_sysino(devhandle, devino, &sysino);
3035b208c27Smrg 		if (err != H_EOK)
3045b208c27Smrg 			return (NULL);
3055b208c27Smrg 
3065b208c27Smrg 		KASSERT(sysino == INTVEC(sysino));
3075b208c27Smrg 		ih = bus_intr_allocate(t0, handler, arg, sysino, level,
3085b208c27Smrg 		    NULL, NULL, what);
3095b208c27Smrg 		if (ih == NULL)
3105b208c27Smrg 			return (NULL);
3115b208c27Smrg 
3125b208c27Smrg 		intr_establish(ih->ih_pil, ih);
3135b208c27Smrg 		ih->ih_ack = ebus_mainbus_intr_ack;
3145b208c27Smrg 
3155b208c27Smrg 		err = hv_intr_settarget(sysino, cpus->ci_upaid);
3165b208c27Smrg 		if (err != H_EOK)
3175b208c27Smrg 			return (NULL);
3185b208c27Smrg 
3195b208c27Smrg 		/* Clear pending interrupts. */
3205b208c27Smrg 		err = hv_intr_setstate(sysino, INTR_IDLE);
3215b208c27Smrg 		if (err != H_EOK)
3225b208c27Smrg 			return (NULL);
3235b208c27Smrg 
3245b208c27Smrg 		err = hv_intr_setenabled(sysino, INTR_ENABLED);
3255b208c27Smrg 		if (err != H_EOK)
3265b208c27Smrg 			return (NULL);
3275b208c27Smrg 
3285b208c27Smrg 		return (ih);
3295b208c27Smrg 	}
3305b208c27Smrg #endif
331f1503a8dSpalle 
3325b208c27Smrg 	ino = INTINO(ihandle);
3335b208c27Smrg 
334f1503a8dSpalle 	struct pyro_softc *psc = NULL;
335f1503a8dSpalle 	int i;
336f1503a8dSpalle 
337f1503a8dSpalle 	for (i = 0; i < pyro_cd.cd_ndevs; i++) {
33855c42a93Spalle 		device_t dt = device_lookup(&pyro_cd, i);
339f1503a8dSpalle 		psc = device_private(dt);
340f1503a8dSpalle 		if (psc && psc->sc_ign == INTIGN(ihandle)) {
341f1503a8dSpalle 			break;
342f1503a8dSpalle 		}
343f1503a8dSpalle 	}
344f1503a8dSpalle 	if (psc == NULL)
345f1503a8dSpalle 		return (NULL);
346f1503a8dSpalle 
347f1503a8dSpalle 	imap = (uint64_t *)((uintptr_t)bus_space_vaddr(psc->sc_bustag, psc->sc_csrh) + 0x1000);
348f1503a8dSpalle 	iclr = (uint64_t *)((uintptr_t)bus_space_vaddr(psc->sc_bustag, psc->sc_csrh) + 0x1400);
3495b208c27Smrg 	intrmapptr = &imap[ino];
3505b208c27Smrg 	intrclrptr = &iclr[ino];
3515b208c27Smrg 	ino |= INTVEC(ihandle);
3525b208c27Smrg 
35378ba29b0Snakayama 	ih = intrhand_alloc();
3545b208c27Smrg 
355a1b3c3f0Smrg 	/* Register the map and clear intr registers */
356a1b3c3f0Smrg 	ih->ih_map = intrmapptr;
357a1b3c3f0Smrg 	ih->ih_clr = intrclrptr;
358a1b3c3f0Smrg 
359ab82fc7eSmrg 	ih->ih_ivec = ihandle;
360a1b3c3f0Smrg 	ih->ih_fun = handler;
361a1b3c3f0Smrg 	ih->ih_arg = arg;
362a1b3c3f0Smrg 	ih->ih_pil = level;
363a1b3c3f0Smrg 	ih->ih_number = ino;
36410a9f073Smrg 	ih->ih_pending = 0;
365a1b3c3f0Smrg 
366a1b3c3f0Smrg 	intr_establish(ih->ih_pil, level != IPL_VM, ih);
3675b208c27Smrg 
3685b208c27Smrg 	if (intrmapptr != NULL) {
369a1b3c3f0Smrg 		u_int64_t imapval;
3705b208c27Smrg 
371a1b3c3f0Smrg 		imapval = *intrmapptr;
372a1b3c3f0Smrg 		imapval |= (1LL << 6);
373a1b3c3f0Smrg 		imapval |= INTMAP_V;
374a1b3c3f0Smrg 		*intrmapptr = imapval;
375a1b3c3f0Smrg 		imapval = *intrmapptr;
376a1b3c3f0Smrg 		ih->ih_number |= imapval & INTMAP_INR;
3775b208c27Smrg 	}
3785b208c27Smrg 
3795b208c27Smrg 	return (ih);
3805b208c27Smrg }
3815b208c27Smrg 
3825b208c27Smrg #ifdef SUN4V
383418e019bSpalle #if 0
384418e019bSpalle XXX
38510a9f073Smrg static void
3865b208c27Smrg ebus_mainbus_intr_ack(struct intrhand *ih)
3875b208c27Smrg {
3885b208c27Smrg 	hv_intr_setstate(ih->ih_number, INTR_IDLE);
3895b208c27Smrg }
390418e019bSpalle #endif
3915b208c27Smrg #endif
392