From 5575003f0465e84c4ce141c26facf09728dd0629 Mon Sep 17 00:00:00 2001 From: kettenis Date: Sat, 18 Dec 2021 13:33:52 +0000 Subject: [PATCH] Add aplmbox(4), a driver for the mailbox that provides a communication channel with additional cores integrated on Apple SoCs. ok patrick@ --- sys/arch/arm64/dev/aplmbox.c | 192 +++++++++++++++++++++++++++++++++++ sys/arch/arm64/dev/aplmbox.h | 21 ++++ 2 files changed, 213 insertions(+) create mode 100644 sys/arch/arm64/dev/aplmbox.c create mode 100644 sys/arch/arm64/dev/aplmbox.h diff --git a/sys/arch/arm64/dev/aplmbox.c b/sys/arch/arm64/dev/aplmbox.c new file mode 100644 index 00000000000..38f12628c13 --- /dev/null +++ b/sys/arch/arm64/dev/aplmbox.c @@ -0,0 +1,192 @@ +/* $OpenBSD: aplmbox.c,v 1.1 2021/12/18 13:33:52 kettenis Exp $ */ +/* + * Copyright (c) 2021 Mark Kettenis + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include + +#define MBOX_A2I_CTRL 0x110 +#define MBOX_A2I_CTRL_FULL (1 << 16) +#define MBOX_I2A_CTRL 0x114 +#define MBOX_I2A_CTRL_EMPTY (1 << 17) +#define MBOX_A2I_SEND0 0x800 +#define MBOX_A2I_SEND1 0x808 +#define MBOX_I2A_RECV0 0x830 +#define MBOX_I2A_RECV1 0x838 + +#define HREAD4(sc, reg) \ + (bus_space_read_4((sc)->sc_iot, (sc)->sc_ioh, (reg))) +#define HREAD8(sc, reg) \ + (bus_space_read_8((sc)->sc_iot, (sc)->sc_ioh, (reg))) +#define HWRITE4(sc, reg, val) \ + bus_space_write_4((sc)->sc_iot, (sc)->sc_ioh, (reg), (val)) +#define HWRITE8(sc, reg, val) \ + bus_space_write_8((sc)->sc_iot, (sc)->sc_ioh, (reg), (val)) + +struct aplmbox_softc { + struct device sc_dev; + bus_space_tag_t sc_iot; + bus_space_handle_t sc_ioh; + + void *sc_ih; + void (*sc_rx_callback)(void *); + void *sc_rx_arg; + + struct mbox_device sc_md; +}; + +int aplmbox_match(struct device *, void *, void *); +void aplmbox_attach(struct device *, struct device *, void *); + +const struct cfattach aplmbox_ca = { + sizeof (struct aplmbox_softc), aplmbox_match, aplmbox_attach +}; + +struct cfdriver aplmbox_cd = { + NULL, "aplmbox", DV_DULL +}; + +int aplmbox_intr(void *); +void *aplmbox_channel(void *, uint32_t *, struct mbox_client *); +int aplmbox_send(void *, const void *, size_t); +int aplmbox_recv(void *, void *, size_t); + +int +aplmbox_match(struct device *parent, void *match, void *aux) +{ + struct fdt_attach_args *faa = aux; + + return OF_is_compatible(faa->fa_node, "apple,asc-mailbox"); +} + +void +aplmbox_attach(struct device *parent, struct device *self, void *aux) +{ + struct aplmbox_softc *sc = (struct aplmbox_softc *)self; + struct fdt_attach_args *faa = aux; + int idx; + + if (faa->fa_nreg < 1) { + printf(": no registers\n"); + return; + } + + sc->sc_iot = faa->fa_iot; + if (bus_space_map(sc->sc_iot, faa->fa_reg[0].addr, + faa->fa_reg[0].size, 0, &sc->sc_ioh)) { + printf(": can't map registers\n"); + return; + } + + idx = OF_getindex(faa->fa_node, "recv-not-empty", "interrupt-names"); + if (idx > 0) { + sc->sc_ih = fdt_intr_establish_idx(faa->fa_node, idx, IPL_BIO, + aplmbox_intr, sc, sc->sc_dev.dv_xname); + } + + printf("\n"); + + sc->sc_md.md_node = faa->fa_node; + sc->sc_md.md_cookie = sc; + sc->sc_md.md_channel = aplmbox_channel; + sc->sc_md.md_send = aplmbox_send; + sc->sc_md.md_recv = aplmbox_recv; + mbox_register(&sc->sc_md); +} + +int +aplmbox_intr(void *arg) +{ + struct aplmbox_softc *sc = arg; + uint32_t ctrl; + + ctrl = HREAD4(sc, MBOX_I2A_CTRL); + if (ctrl & MBOX_I2A_CTRL_EMPTY) + return 0; + + if (sc->sc_rx_callback) { + sc->sc_rx_callback(sc->sc_rx_arg); + } else { + printf("%s: 0x%016llx 0x%016llx\n", sc->sc_dev.dv_xname, + HREAD8(sc, MBOX_I2A_RECV0), HREAD8(sc, MBOX_I2A_RECV1)); + } + + return 1; +} + +void * +aplmbox_channel(void *cookie, uint32_t *cells, struct mbox_client *mc) +{ + struct aplmbox_softc *sc = cookie; + + if (mc) { + sc->sc_rx_callback = mc->mc_rx_callback; + sc->sc_rx_arg = mc->mc_rx_arg; + } + + return sc; +} + +int +aplmbox_send(void *cookie, const void *data, size_t len) +{ + struct aplmbox_softc *sc = cookie; + const struct aplmbox_msg *msg = data; + uint32_t ctrl; + + if (len != sizeof(struct aplmbox_msg)) + return EINVAL; + + ctrl = HREAD4(sc, MBOX_A2I_CTRL); + if (ctrl & MBOX_A2I_CTRL_FULL) + return EBUSY; + + HWRITE8(sc, MBOX_A2I_SEND0, msg->data0); + HWRITE8(sc, MBOX_A2I_SEND1, msg->data1); + + return 0; +} + +int +aplmbox_recv(void *cookie, void *data, size_t len) +{ + struct aplmbox_softc *sc = cookie; + struct aplmbox_msg *msg = data; + uint32_t ctrl; + + if (len != sizeof(struct aplmbox_msg)) + return EINVAL; + + ctrl = HREAD4(sc, MBOX_I2A_CTRL); + if (ctrl & MBOX_I2A_CTRL_EMPTY) + return EAGAIN; + + msg->data0 = HREAD8(sc, MBOX_I2A_RECV0); + msg->data1 = HREAD8(sc, MBOX_I2A_RECV1); + + return 0; +} diff --git a/sys/arch/arm64/dev/aplmbox.h b/sys/arch/arm64/dev/aplmbox.h new file mode 100644 index 00000000000..3bb8c64672e --- /dev/null +++ b/sys/arch/arm64/dev/aplmbox.h @@ -0,0 +1,21 @@ +/* $OpenBSD: aplmbox.h,v 1.1 2021/12/18 13:33:52 kettenis Exp $ */ +/* + * Copyright (c) 2021 Mark Kettenis + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +struct aplmbox_msg { + uint64_t data0; + uint32_t data1; +}; -- 2.20.1