Module Name: src Committed By: palle Date: Tue May 10 19:24:00 UTC 2016
Modified Files: src/sys/arch/sparc64/dev: fhc.c psycho.c pyro.c sbus.c schizo.c vpci.c src/sys/arch/sparc64/include: cpu.h src/sys/arch/sparc64/sparc64: genassym.cf intr.c locore.s Log Message: sun4v: make device interrupts work. Introduce a new intrhand_alloc() function for allocation of interrupt handlers and adapt to this. Parts from OpenBSD. ok martin@ To generate a diff of this commit: cvs rdiff -u -r1.3 -r1.4 src/sys/arch/sparc64/dev/fhc.c cvs rdiff -u -r1.123 -r1.124 src/sys/arch/sparc64/dev/psycho.c cvs rdiff -u -r1.16 -r1.17 src/sys/arch/sparc64/dev/pyro.c cvs rdiff -u -r1.93 -r1.94 src/sys/arch/sparc64/dev/sbus.c cvs rdiff -u -r1.35 -r1.36 src/sys/arch/sparc64/dev/schizo.c cvs rdiff -u -r1.6 -r1.7 src/sys/arch/sparc64/dev/vpci.c cvs rdiff -u -r1.118 -r1.119 src/sys/arch/sparc64/include/cpu.h cvs rdiff -u -r1.76 -r1.77 src/sys/arch/sparc64/sparc64/genassym.cf cvs rdiff -u -r1.67 -r1.68 src/sys/arch/sparc64/sparc64/intr.c cvs rdiff -u -r1.390 -r1.391 src/sys/arch/sparc64/sparc64/locore.s Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/sparc64/dev/fhc.c diff -u src/sys/arch/sparc64/dev/fhc.c:1.3 src/sys/arch/sparc64/dev/fhc.c:1.4 --- src/sys/arch/sparc64/dev/fhc.c:1.3 Sun Mar 18 05:26:58 2012 +++ src/sys/arch/sparc64/dev/fhc.c Tue May 10 19:23:59 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: fhc.c,v 1.3 2012/03/18 05:26:58 mrg Exp $ */ +/* $NetBSD: fhc.c,v 1.4 2016/05/10 19:23:59 palle Exp $ */ /* $OpenBSD: fhc.c,v 1.17 2010/11/11 17:58:23 miod Exp $ */ /* @@ -28,7 +28,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: fhc.c,v 1.3 2012/03/18 05:26:58 mrg Exp $"); +__KERNEL_RCSID(0, "$NetBSD: fhc.c,v 1.4 2016/05/10 19:23:59 palle Exp $"); #include <sys/types.h> #include <sys/param.h> @@ -251,10 +251,7 @@ fhc_intr_establish(bus_space_tag_t t, in vec = ((sc->sc_ign << INTMAP_IGN_SHIFT) & INTMAP_IGN) | INTINO(ihandle); - ih = (struct intrhand *) - malloc(sizeof(struct intrhand), M_DEVBUF, M_NOWAIT); - if (ih == NULL) - return (NULL); + ih = intrhand_alloc(); ih->ih_ivec = ihandle; Index: src/sys/arch/sparc64/dev/psycho.c diff -u src/sys/arch/sparc64/dev/psycho.c:1.123 src/sys/arch/sparc64/dev/psycho.c:1.124 --- src/sys/arch/sparc64/dev/psycho.c:1.123 Fri Nov 27 00:36:58 2015 +++ src/sys/arch/sparc64/dev/psycho.c Tue May 10 19:23:59 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: psycho.c,v 1.123 2015/11/27 00:36:58 mrg Exp $ */ +/* $NetBSD: psycho.c,v 1.124 2016/05/10 19:23:59 palle Exp $ */ /* * Copyright (c) 1999, 2000 Matthew R. Green @@ -55,7 +55,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: psycho.c,v 1.123 2015/11/27 00:36:58 mrg Exp $"); +__KERNEL_RCSID(0, "$NetBSD: psycho.c,v 1.124 2016/05/10 19:23:59 palle Exp $"); #include "opt_ddb.h" @@ -707,8 +707,7 @@ psycho_set_intr(struct psycho_softc *sc, { struct intrhand *ih; - ih = (struct intrhand *)malloc(sizeof(struct intrhand), - M_DEVBUF, M_NOWAIT); + ih = intrhand_alloc(); ih->ih_arg = sc; ih->ih_map = mapper; ih->ih_clr = clearer; @@ -1273,9 +1272,7 @@ psycho_intr_establish(bus_space_tag_t t, int ino; long vec = INTVEC(ihandle); - ih = malloc(sizeof(struct intrhand), M_DEVBUF, M_NOWAIT); - if (ih == NULL) - return (NULL); + ih = intrhand_alloc(); ih->ih_ivec = ihandle; Index: src/sys/arch/sparc64/dev/pyro.c diff -u src/sys/arch/sparc64/dev/pyro.c:1.16 src/sys/arch/sparc64/dev/pyro.c:1.17 --- src/sys/arch/sparc64/dev/pyro.c:1.16 Fri Oct 2 05:22:52 2015 +++ src/sys/arch/sparc64/dev/pyro.c Tue May 10 19:23:59 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: pyro.c,v 1.16 2015/10/02 05:22:52 msaitoh Exp $ */ +/* $NetBSD: pyro.c,v 1.17 2016/05/10 19:23:59 palle Exp $ */ /* from: $OpenBSD: pyro.c,v 1.20 2010/12/05 15:15:14 kettenis Exp $ */ /* @@ -31,7 +31,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: pyro.c,v 1.16 2015/10/02 05:22:52 msaitoh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: pyro.c,v 1.17 2016/05/10 19:23:59 palle Exp $"); #include <sys/param.h> #include <sys/device.h> @@ -580,9 +580,7 @@ pyro_intr_establish(bus_space_tag_t t, i ino |= INTVEC(ihandle); - ih = malloc(sizeof *ih, M_DEVBUF, M_NOWAIT); - if (ih == NULL) - return (NULL); + ih = intrhand_alloc(); /* Register the map and clear intr registers */ ih->ih_map = intrmapptr; Index: src/sys/arch/sparc64/dev/sbus.c diff -u src/sys/arch/sparc64/dev/sbus.c:1.93 src/sys/arch/sparc64/dev/sbus.c:1.94 --- src/sys/arch/sparc64/dev/sbus.c:1.93 Mon Jan 30 04:25:15 2012 +++ src/sys/arch/sparc64/dev/sbus.c Tue May 10 19:23:59 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: sbus.c,v 1.93 2012/01/30 04:25:15 mrg Exp $ */ +/* $NetBSD: sbus.c,v 1.94 2016/05/10 19:23:59 palle Exp $ */ /* * Copyright (c) 1999-2002 Eduardo Horvath @@ -34,7 +34,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: sbus.c,v 1.93 2012/01/30 04:25:15 mrg Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sbus.c,v 1.94 2016/05/10 19:23:59 palle Exp $"); #include "opt_ddb.h" @@ -254,8 +254,7 @@ sbus_attach(device_t parent, device_t se iommu_init(name, &sc->sc_is, 0, -1); /* Enable the over temp intr */ - ih = (struct intrhand *) - malloc(sizeof(struct intrhand), M_DEVBUF, M_NOWAIT); + ih = intrhand_alloc(); ih->ih_map = &sc->sc_sysio->therm_int_map; ih->ih_clr = NULL; /* &sc->sc_sysio->therm_clr_int; */ ih->ih_fun = sbus_overtemp; @@ -508,10 +507,7 @@ sbus_intr_establish(bus_space_tag_t t, i int ipl; long vec = pri; - ih = (struct intrhand *) - malloc(sizeof(struct intrhand), M_DEVBUF, M_NOWAIT); - if (ih == NULL) - return (NULL); + ih = intrhand_alloc(); if ((vec & SBUS_INTR_COMPAT) != 0) ipl = vec & ~SBUS_INTR_COMPAT; Index: src/sys/arch/sparc64/dev/schizo.c diff -u src/sys/arch/sparc64/dev/schizo.c:1.35 src/sys/arch/sparc64/dev/schizo.c:1.36 --- src/sys/arch/sparc64/dev/schizo.c:1.35 Fri Nov 27 09:34:36 2015 +++ src/sys/arch/sparc64/dev/schizo.c Tue May 10 19:23:59 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: schizo.c,v 1.35 2015/11/27 09:34:36 martin Exp $ */ +/* $NetBSD: schizo.c,v 1.36 2016/05/10 19:23:59 palle Exp $ */ /* $OpenBSD: schizo.c,v 1.55 2008/08/18 20:29:37 brad Exp $ */ /* @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: schizo.c,v 1.35 2015/11/27 09:34:36 martin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: schizo.c,v 1.36 2016/05/10 19:23:59 palle Exp $"); #include <sys/param.h> #include <sys/device.h> @@ -588,10 +588,8 @@ schizo_set_intr(struct schizo_softc *sc, DPRINTF(SDB_INTR, (" mapoff %" PRIx64 " clroff %" PRIx64 "\n", mapoff, clroff)); - ih = (struct intrhand *) - kmem_alloc(sizeof(struct intrhand), KM_NOSLEEP); - if (ih == NULL) - return; + ih = intrhand_alloc(); + ih->ih_arg = arg; intrregs = (uintptr_t)bus_space_vaddr(pbm->sp_regt, pbm->sp_intrh); ih->ih_map = (uint64_t *)(uintptr_t)(intrregs + mapoff); @@ -815,9 +813,7 @@ schizo_intr_establish(bus_space_tag_t t, vec = INTVEC(ihandle); ino = INTINO(vec); - ih = kmem_alloc(sizeof *ih, KM_NOSLEEP); - if (ih == NULL) - return (NULL); + ih = intrhand_alloc(); DPRINTF(SDB_INTR, ("\n%s: ihandle %x level %d fn %p arg %p\n", __func__, ihandle, level, handler, arg)); Index: src/sys/arch/sparc64/dev/vpci.c diff -u src/sys/arch/sparc64/dev/vpci.c:1.6 src/sys/arch/sparc64/dev/vpci.c:1.7 --- src/sys/arch/sparc64/dev/vpci.c:1.6 Fri Nov 27 13:51:57 2015 +++ src/sys/arch/sparc64/dev/vpci.c Tue May 10 19:23:59 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: vpci.c,v 1.6 2015/11/27 13:51:57 joerg Exp $ */ +/* $NetBSD: vpci.c,v 1.7 2016/05/10 19:23:59 palle Exp $ */ /* * Copyright (c) 2015 Palle Lyckegaard * All rights reserved. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: vpci.c,v 1.6 2015/11/27 13:51:57 joerg Exp $"); +__KERNEL_RCSID(0, "$NetBSD: vpci.c,v 1.7 2016/05/10 19:23:59 palle Exp $"); #include <sys/param.h> #include <sys/device.h> @@ -114,7 +114,7 @@ void vpci_conf_write(pci_chipset_tag_t, static void * vpci_pci_intr_establish(pci_chipset_tag_t pc, pci_intr_handle_t ih, int level, int (*func)(void *), void *arg); - +void vpci_intr_ack(struct intrhand *); int vpci_intr_map(const struct pci_attach_args *, pci_intr_handle_t *); int vpci_bus_map(bus_space_tag_t, bus_addr_t, bus_size_t, int, vaddr_t, bus_space_handle_t *); @@ -596,9 +596,7 @@ vpci_intr_establish(bus_space_tag_t t, i ino |= INTVEC(ihandle); DPRINTF(VDB_INTR, ("%s: ih %lx; level %d ino %#x\n", __func__, (u_long)ihandle, level, ino)); - ih = malloc(sizeof *ih, M_DEVBUF, M_NOWAIT); - if (ih == NULL) - return (NULL); + ih = intrhand_alloc(); ih->ih_ivec = ihandle; ih->ih_fun = handler; @@ -606,12 +604,44 @@ vpci_intr_establish(bus_space_tag_t t, i ih->ih_pil = level; ih->ih_number = ino; ih->ih_pending = 0; - + ih->ih_ack = vpci_intr_ack; intr_establish(ih->ih_pil, level != IPL_VM, ih); + uint64_t sysino = INTVEC(ihandle); + DPRINTF(VDB_INTR, ("vpci_intr_establish(): sysino 0x%lx\n", sysino)); + + int err; + + err = hv_intr_settarget(sysino, cpus->ci_cpuid); + if (err != H_EOK) + printf("hv_intr_settarget(%lu, %u) failed - err = %d\n", + (long unsigned int)sysino, cpus->ci_cpuid, err); + + /* Clear pending interrupts. */ + err = hv_intr_setstate(sysino, INTR_IDLE); + if (err != H_EOK) + printf("hv_intr_setstate(%lu, INTR_IDLE) failed - err = %d\n", + (long unsigned int)sysino, err); + + err = hv_intr_setenabled(sysino, INTR_ENABLED); + if (err != H_EOK) + printf("hv_intr_setenabled(%lu) failed - err = %d\n", + (long unsigned int)sysino, err); + + DPRINTF(VDB_INTR, ("%s() returning %p\n", __func__, ih)); return (ih); } +void +vpci_intr_ack(struct intrhand *ih) +{ + int err; + err = hv_intr_setstate(ih->ih_number, INTR_IDLE); + if (err != H_EOK) + panic("%s(%u, INTR_IDLE) failed - err = %d\n", + __func__, ih->ih_number, err); +} + static void * vpci_pci_intr_establish(pci_chipset_tag_t pc, pci_intr_handle_t ih, int level, int (*func)(void *), void *arg) Index: src/sys/arch/sparc64/include/cpu.h diff -u src/sys/arch/sparc64/include/cpu.h:1.118 src/sys/arch/sparc64/include/cpu.h:1.119 --- src/sys/arch/sparc64/include/cpu.h:1.118 Mon Sep 7 20:00:49 2015 +++ src/sys/arch/sparc64/include/cpu.h Tue May 10 19:24:00 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: cpu.h,v 1.118 2015/09/07 20:00:49 palle Exp $ */ +/* $NetBSD: cpu.h,v 1.119 2016/05/10 19:24:00 palle Exp $ */ /* * Copyright (c) 1992, 1993 @@ -361,6 +361,7 @@ struct intrhand { struct intrhand *ih_pending; /* interrupt queued */ volatile uint64_t *ih_map; /* Interrupt map reg */ volatile uint64_t *ih_clr; /* clear interrupt reg */ + void (*ih_ack)(struct intrhand *); /* ack interrupt function */ struct evcnt ih_cnt; /* counter for vmstat */ uint32_t ih_ivec; char ih_name[32]; /* name for the above */ @@ -372,6 +373,7 @@ void intr_establish(int level, bool mpsa void *sparc_softintr_establish(int, int (*)(void *), void *); void sparc_softintr_schedule(void *); void sparc_softintr_disestablish(void *); +struct intrhand *intrhand_alloc(void); /* cpu.c */ int cpu_myid(void); Index: src/sys/arch/sparc64/sparc64/genassym.cf diff -u src/sys/arch/sparc64/sparc64/genassym.cf:1.76 src/sys/arch/sparc64/sparc64/genassym.cf:1.77 --- src/sys/arch/sparc64/sparc64/genassym.cf:1.76 Wed Apr 1 18:38:30 2015 +++ src/sys/arch/sparc64/sparc64/genassym.cf Tue May 10 19:24:00 2016 @@ -1,4 +1,4 @@ -# $NetBSD: genassym.cf,v 1.76 2015/04/01 18:38:30 palle Exp $ +# $NetBSD: genassym.cf,v 1.77 2016/05/10 19:24:00 palle Exp $ # # Copyright (c) 1997 The NetBSD Foundation, Inc. @@ -170,6 +170,7 @@ define CI_TSB_IMMU offsetof(struct cpu_i define CI_MMFSA offsetof(struct cpu_info, ci_mmfsa) define CI_TSB_DESC offsetof(struct cpu_info, ci_tsb_desc) define CI_CPUMQ offsetof(struct cpu_info, ci_cpumq) +define CI_DEVMQ offsetof(struct cpu_info, ci_devmq) ifdef MULTIPROCESSOR define CI_IPIEVC offsetof(struct cpu_info, ci_ipi_evcnt[0].ev_count) endif @@ -254,6 +255,7 @@ define IH_PEND offsetof(struct intrhand define IH_NEXT offsetof(struct intrhand, ih_next) define IH_MAP offsetof(struct intrhand, ih_map) define IH_CLR offsetof(struct intrhand, ih_clr) +define IH_ACK offsetof(struct intrhand, ih_ack) define IH_CNT offsetof(struct intrhand, ih_cnt) # mbuf fields of import Index: src/sys/arch/sparc64/sparc64/intr.c diff -u src/sys/arch/sparc64/sparc64/intr.c:1.67 src/sys/arch/sparc64/sparc64/intr.c:1.68 --- src/sys/arch/sparc64/sparc64/intr.c:1.67 Sat Aug 11 21:50:09 2012 +++ src/sys/arch/sparc64/sparc64/intr.c Tue May 10 19:24:00 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: intr.c,v 1.67 2012/08/11 21:50:09 mrg Exp $ */ +/* $NetBSD: intr.c,v 1.68 2016/05/10 19:24:00 palle Exp $ */ /* * Copyright (c) 1992, 1993 @@ -41,7 +41,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: intr.c,v 1.67 2012/08/11 21:50:09 mrg Exp $"); +__KERNEL_RCSID(0, "$NetBSD: intr.c,v 1.68 2016/05/10 19:24:00 palle Exp $"); #include "opt_ddb.h" #include "opt_multiprocessor.h" @@ -49,6 +49,7 @@ __KERNEL_RCSID(0, "$NetBSD: intr.c,v 1.6 #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> +#include <sys/kmem.h> #include <sys/malloc.h> #include <dev/cons.h> @@ -170,6 +171,21 @@ intr_biglock_wrapper(void *vp) #endif /* + * Allocate memory for interrupt handler. + * The allocated memory is initialized with zeros so + * e.g. pointers in the intrhand structure are properly initialized. + * A valid pointer is always returned by the function. + */ +struct intrhand* +intrhand_alloc(void) +{ + struct intrhand *ih = kmem_zalloc(sizeof(struct intrhand), KM_NOSLEEP); + if (ih == NULL) + panic("%s: failed to allocate intrhand", __func__); + return ih; +} + +/* * Attach an interrupt handler to the vector chain for the given level. * This is not possible if it has been taken away as a fast vector. */ @@ -247,9 +263,7 @@ intr_establish(int level, bool mpsafe, s ("intr_establish: intr reused %x\n", ih->ih_number)); if (q->ih_fun != intr_list_handler) { - nih = (struct intrhand *) - malloc(sizeof(struct intrhand), - M_DEVBUF, M_NOWAIT); + nih = intrhand_alloc(); /* Point the old IH at the new handler */ *nih = *q; nih->ih_next = NULL; @@ -284,10 +298,7 @@ sparc_softintr_establish(int pil, int (* { struct intrhand *ih; - ih = malloc(sizeof(struct intrhand), M_DEVBUF, M_NOWAIT|M_ZERO); - if (ih == NULL) - panic("could not allocate softint interrupt handler"); - + ih = intrhand_alloc(); ih->ih_fun = fun; ih->ih_pil = pil; ih->ih_arg = arg; Index: src/sys/arch/sparc64/sparc64/locore.s diff -u src/sys/arch/sparc64/sparc64/locore.s:1.390 src/sys/arch/sparc64/sparc64/locore.s:1.391 --- src/sys/arch/sparc64/sparc64/locore.s:1.390 Wed Mar 9 12:20:20 2016 +++ src/sys/arch/sparc64/sparc64/locore.s Tue May 10 19:24:00 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: locore.s,v 1.390 2016/03/09 12:20:20 nakayama Exp $ */ +/* $NetBSD: locore.s,v 1.391 2016/05/10 19:24:00 palle Exp $ */ /* * Copyright (c) 2006-2010 Matthew R. Green @@ -1071,7 +1071,8 @@ _C_LABEL(trapbase_sun4v): HARDINT4V(15) ! 0x04f = level 15 interrupt sun4v_trap_entry 44 ! 0x050-0x07b VTRAP(T_CPU_MONDO, sun4v_cpu_mondo) ! 0x07c = cpu mondo - sun4v_trap_entry 3 ! 0x07d-0x07f + VTRAP(T_DEV_MONDO, sun4v_dev_mondo) ! 0x07d = dev mondo + sun4v_trap_entry 2 ! 0x07e-0x07f SPILL64(uspill8_sun4vt0,ASI_AIUS) ! 0x080 spill_0_normal -- used to save user windows in user mode SPILL32(uspill4_sun4vt0,ASI_AIUS) ! 0x084 spill_1_normal SPILLBOTH(uspill8_sun4vt0,uspill4_sun4vt0,ASI_AIUS) ! 0x088 spill_2_normal @@ -3592,6 +3593,8 @@ ret_from_intr_vector: nop ! XXX spitfire bug? sun4v_cpu_mondo: +! XXX Rework this when a UP kernel works - crash for now + sir mov 0x3c0, %g1 ! CPU Mondo Queue Head ldxa [%g1] ASI_QUEUE, %g2 ! fetch index value for head set CPUINFO_VA, %g3 @@ -3616,7 +3619,45 @@ sun4v_cpu_mondo: retry NOTREACHED - +sun4v_dev_mondo: + mov 0x3d0, %g1 ! Dev Mondo Queue Head + ldxa [%g1] ASI_QUEUE, %g2 ! fetch index value + mov 0x3d8, %g1 ! Dev Mondo Queue Tail + ldxa [%g1] ASI_QUEUE, %g4 ! fetch index value + cmp %g2, %g4 ! head = queue? + bne,pt %xcc, 2f ! unsually not the case + nop + retry ! unlikely, ingnore interrupt +2: + set CPUINFO_VA, %g3 ! fetch cpuinfo pa + LDPTR [%g3 + CI_PADDR], %g3 ! fetch intstack pa + set CPUINFO_VA-INTSTACK, %g4 ! offset to cpuinfo + add %g4, %g3, %g3 ! %g3 is now cpuifo + add %g3, CI_DEVMQ, %g3 ! calc offset to devmq + ldxa [%g3] ASI_PHYS_CACHED, %g3 ! fetch address of devmq + ldxa [%g3 + %g2] ASI_PHYS_CACHED, %g5 ! + add %g2, 64, %g2 ! each element is 64 bytes + and %g2, 0x7ff, %g2 ! assume 32 elements + mov 0x3d0, %g1 ! Dev Mondo Queue Head + stxa %g2, [%g1] ASI_QUEUE ! ajust head index value + membar #Sync + + cmp %g5, MAXINTNUM ! out of bounds? + bgeu,pn %xcc, 2f + nop ! no just continue + + sethi %hi(_C_LABEL(intrlev)), %g3 + or %g3, %lo(_C_LABEL(intrlev)), %g3 + sllx %g5, 3, %g5 ! Calculate entry number + ldx [%g3 + %g5], %g5 ! We have a pointer to the handler +1: + brnz,pt %g5, setup_sparcintr ! branch if valid handle + nop + + ba,a 3b ! log if invalid handle + nop +2: + sir ! out of bounds - crash /* * Ultra1 and Ultra2 CPUs use soft interrupts for everything. What we do * on a soft interrupt, is we should check which bits in SOFTINT(%asr22) @@ -3910,6 +3951,12 @@ sparc_intr_retry: stx %g0, [%l1] ! Clear intr source membar #Sync ! Should not be needed 0: + ldx [%l2 + IH_ACK], %l1 ! ih->ih_ack + brz,pn %l1, 1f + nop + jmpl %l1, %o7 ! (*ih->ih_ack)(ih) + mov %l2, %o0 +1: cmp %l7, -1 bne,pn CCCR, 2b ! 'Nother? mov %l7, %l2