-/* $OpenBSD: vbus.c,v 1.8 2015/09/27 11:29:20 kettenis Exp $ */
+/* $OpenBSD: vbus.c,v 1.9 2017/12/06 16:20:53 kettenis Exp $ */
/*
* Copyright (c) 2008 Mark Kettenis
*
struct device sc_dv;
bus_space_tag_t sc_bustag;
bus_dma_tag_t sc_dmatag;
+
+ uint64_t sc_devhandle;
};
int vbus_cmp_cells(int *, int *, int *, int);
sc->sc_bustag = vbus_alloc_bus_tag(sc, ma->ma_bustag);
sc->sc_dmatag = ma->ma_dmatag;
+ sc->sc_devhandle = (ma->ma_reg[0].ur_paddr >> 32) & 0x0fffffff;
printf("\n");
for (node = OF_child(ma->ma_node); node; node = OF_peer(node)) {
getprop(node, "reg", sizeof(*reg), &nreg, (void **)®);
devhandle = reg[0] & 0x0fffffff;
- err = hv_intr_devino_to_sysino(devhandle, devino, sysino);
+ err = sun4v_intr_devino_to_sysino(devhandle, devino, sysino);
if (err != H_EOK)
return (-1);
vbus_intr_establish(bus_space_tag_t t, bus_space_tag_t t0, int ihandle,
int level, int flags, int (*handler)(void *), void *arg, const char *what)
{
+ struct vbus_softc *sc = t->cookie;
+ uint64_t devhandle = sc->sc_devhandle;
uint64_t sysino = INTVEC(ihandle);
struct intrhand *ih;
int err;
if (flags & BUS_INTR_ESTABLISH_MPSAFE)
ih->ih_mpsafe = 1;
+ err = sun4v_intr_setcookie(devhandle, sysino, (vaddr_t)ih);
+ if (err != H_EOK)
+ return (NULL);
+
intr_establish(ih->ih_pil, ih);
ih->ih_ack = vbus_intr_ack;
- err = hv_intr_settarget(sysino, ih->ih_cpu->ci_upaid);
+ err = sun4v_intr_settarget(devhandle, sysino, ih->ih_cpu->ci_upaid);
if (err != H_EOK)
return (NULL);
/* Clear pending interrupts. */
- err = hv_intr_setstate(sysino, INTR_IDLE);
+ err = sun4v_intr_setstate(devhandle, sysino, INTR_IDLE);
if (err != H_EOK)
return (NULL);
- err = hv_intr_setenabled(sysino, INTR_ENABLED);
+ err = sun4v_intr_setenabled(devhandle, sysino, INTR_ENABLED);
if (err != H_EOK)
return (NULL);
void
vbus_intr_ack(struct intrhand *ih)
{
- hv_intr_setstate(ih->ih_number, INTR_IDLE);
+ bus_space_tag_t t = ih->ih_bus;
+ struct vbus_softc *sc = t->cookie;
+ uint64_t devhandle = sc->sc_devhandle;
+
+ sun4v_intr_setstate(devhandle, ih->ih_number, INTR_IDLE);
}
bus_space_tag_t
-/* $OpenBSD: vpci.c,v 1.22 2017/12/05 21:04:32 kettenis Exp $ */
+/* $OpenBSD: vpci.c,v 1.23 2017/12/06 16:20:53 kettenis Exp $ */
/*
* Copyright (c) 2008 Mark Kettenis <kettenis@openbsd.org>
*
OF_getprop(sc->sc_node, "msi-eq-to-devino",
msi_eq_devino, sizeof(msi_eq_devino));
- err = hv_intr_devino_to_sysino(pbm->vp_devhandle,
+ err = sun4v_intr_devino_to_sysino(pbm->vp_devhandle,
msi_eq_devino[2], &sysino);
if (err != H_EOK)
goto disable_queue;
- if (vpci_intr_establish(sc->sc_bust, sc->sc_bust, sysino,
+ if (vpci_intr_establish(pbm->vp_memt, pbm->vp_memt, sysino,
IPL_HIGH, 0, vpci_msi_eq_intr, pbm, sc->sc_dv.dv_xname) == NULL)
goto disable_queue;
int err;
if (*ihp != (pci_intr_handle_t)-1) {
- err = hv_intr_devino_to_sysino(devhandle, devino, &sysino);
+ err = sun4v_intr_devino_to_sysino(devhandle, devino, &sysino);
if (err != H_EOK)
return (-1);
int level, int flags, int (*handler)(void *), void *arg, const char *what)
{
struct vpci_pbm *pbm = t->cookie;
+ uint64_t devhandle = pbm->vp_devhandle;
uint64_t sysino = INTVEC(ihandle);
struct intrhand *ih;
int err;
return (ih);
}
+ err = sun4v_intr_setcookie(devhandle, sysino, (vaddr_t)ih);
+ if (err != H_EOK)
+ return (NULL);
+
intr_establish(ih->ih_pil, ih);
ih->ih_ack = vpci_intr_ack;
- err = hv_intr_settarget(sysino, ih->ih_cpu->ci_upaid);
+ err = sun4v_intr_settarget(devhandle, sysino, ih->ih_cpu->ci_upaid);
if (err != H_EOK)
return (NULL);
/* Clear pending interrupts. */
- err = hv_intr_setstate(sysino, INTR_IDLE);
+ err = sun4v_intr_setstate(devhandle, sysino, INTR_IDLE);
if (err != H_EOK)
return (NULL);
- err = hv_intr_setenabled(sysino, INTR_ENABLED);
+ err = sun4v_intr_setenabled(devhandle, sysino, INTR_ENABLED);
if (err != H_EOK)
return (NULL);
void
vpci_intr_ack(struct intrhand *ih)
{
- hv_intr_setstate(ih->ih_number, INTR_IDLE);
+ bus_space_tag_t t = ih->ih_bus;
+ struct vpci_pbm *pbm = t->cookie;
+ uint64_t devhandle = pbm->vp_devhandle;
+
+ sun4v_intr_setstate(devhandle, ih->ih_number, INTR_IDLE);
}
void
-/* $OpenBSD: hypervisor.h,v 1.15 2014/01/23 23:56:27 kettenis Exp $ */
+/* $OpenBSD: hypervisor.h,v 1.16 2017/12/06 16:20:53 kettenis Exp $ */
/*
* Copyright (c) 2008 Mark Kettenis
#define H_ENOMAP 14
#define H_ETOOMANY 15
#define H_ECHANNEL 16
+
+extern uint64_t sun4v_group_interrupt_major;
+
+int64_t sun4v_intr_devino_to_sysino(uint64_t, uint64_t, uint64_t *);
+int64_t sun4v_intr_setcookie(uint64_t, uint64_t, uint64_t);
+int64_t sun4v_intr_setenabled(uint64_t, uint64_t, uint64_t);
+int64_t sun4v_intr_setstate(uint64_t, uint64_t, uint64_t);
+int64_t sun4v_intr_settarget(uint64_t, uint64_t, uint64_t);
-/* $OpenBSD: autoconf.c,v 1.128 2017/04/30 16:45:45 mpi Exp $ */
+/* $OpenBSD: autoconf.c,v 1.129 2017/12/06 16:20:53 kettenis Exp $ */
/* $NetBSD: autoconf.c,v 1.51 2001/07/24 19:32:11 eeh Exp $ */
/*
#define __align32 __attribute__((__aligned__(32)))
char sun4v_soft_state_booting[] __align32 = "OpenBSD booting";
char sun4v_soft_state_running[] __align32 = "OpenBSD running";
+
+void sun4v_interrupt_init(void);
#endif
#ifdef DEBUG
if (CPU_ISSUN4V) {
sun4v_soft_state_init();
sun4v_set_soft_state(SIS_TRANSITION, sun4v_soft_state_booting);
+ sun4v_interrupt_init();
}
#endif
}
#ifdef SUN4V
+#define HSVC_GROUP_INTERRUPT 0x002
#define HSVC_GROUP_SOFT_STATE 0x003
int sun4v_soft_state_initialized = 0;
if (err != H_EOK)
printf("soft_state_set: %d\n", err);
}
+
+void
+sun4v_interrupt_init(void)
+{
+ uint64_t minor;
+
+ if (prom_set_sun4v_api_version(HSVC_GROUP_INTERRUPT, 3, 0, &minor))
+ return;
+
+ sun4v_group_interrupt_major = 3;
+}
+
#endif
void
-/* $OpenBSD: intr.c,v 1.56 2017/04/30 16:45:45 mpi Exp $ */
+/* $OpenBSD: intr.c,v 1.57 2017/12/06 16:20:53 kettenis Exp $ */
/* $NetBSD: intr.c,v 1.39 2001/07/19 23:38:11 eeh Exp $ */
/*
}
}
#endif
+
+#ifdef SUN4V
+
+#include <machine/hypervisor.h>
+
+uint64_t sun4v_group_interrupt_major;
+
+int64_t
+sun4v_intr_devino_to_sysino(uint64_t devhandle, uint64_t devino, uint64_t *ino)
+{
+ if (sun4v_group_interrupt_major < 3)
+ return hv_intr_devino_to_sysino(devhandle, devino, ino);
+
+ *ino = devino;
+ return H_EOK;
+}
+
+int64_t
+sun4v_intr_setcookie(uint64_t devhandle, uint64_t ino, uint64_t cookie_value)
+{
+ if (sun4v_group_interrupt_major < 3)
+ return H_EOK;
+
+ return hv_vintr_setcookie(devhandle, ino, cookie_value);
+}
+
+int64_t
+sun4v_intr_setenabled(uint64_t devhandle, uint64_t ino, uint64_t intr_enabled)
+{
+ if (sun4v_group_interrupt_major < 3)
+ return hv_intr_setenabled(ino, intr_enabled);
+
+ return hv_vintr_setenabled(devhandle, ino, intr_enabled);
+}
+
+int64_t
+sun4v_intr_setstate(uint64_t devhandle, uint64_t ino, uint64_t intr_state)
+{
+ if (sun4v_group_interrupt_major < 3)
+ return hv_intr_setstate(ino, intr_state);
+
+ return hv_vintr_setstate(devhandle, ino, intr_state);
+}
+
+int64_t
+sun4v_intr_settarget(uint64_t devhandle, uint64_t ino, uint64_t cpuid)
+{
+ if (sun4v_group_interrupt_major < 3)
+ return hv_intr_settarget(ino, cpuid);
+
+ return hv_vintr_settarget(devhandle, ino, cpuid);
+}
+
+#endif