Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F102803571
D43039.id136878.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
10 KB
Referenced Files
None
Subscribers
None
D43039.id136878.diff
View Options
diff --git a/sys/conf/files.arm64 b/sys/conf/files.arm64
--- a/sys/conf/files.arm64
+++ b/sys/conf/files.arm64
@@ -272,6 +272,8 @@
dev/firmware/arm/scmi.c optional fdt scmi
dev/firmware/arm/scmi_clk.c optional fdt scmi
+dev/firmware/arm/scmi_if.m optional fdt scmi
+dev/firmware/arm/scmi_mailbox.c optional fdt scmi
dev/firmware/arm/scmi_shmem.c optional fdt scmi
dev/gpio/pl061.c optional pl061 gpio
diff --git a/sys/dev/firmware/arm/scmi.h b/sys/dev/firmware/arm/scmi.h
--- a/sys/dev/firmware/arm/scmi.h
+++ b/sys/dev/firmware/arm/scmi.h
@@ -31,12 +31,21 @@
#ifndef _ARM64_SCMI_SCMI_H_
#define _ARM64_SCMI_SCMI_H_
+#include "scmi_if.h"
+
#define SCMI_LOCK(sc) mtx_lock(&(sc)->mtx)
#define SCMI_UNLOCK(sc) mtx_unlock(&(sc)->mtx)
#define SCMI_ASSERT_LOCKED(sc) mtx_assert(&(sc)->mtx, MA_OWNED)
#define dprintf(fmt, ...)
+struct scmi_softc {
+ struct simplebus_softc simplebus_sc;
+ device_t dev;
+ device_t tx_shmem;
+ struct mtx mtx;
+};
+
/* Shared Memory Transfer. */
struct scmi_smt_header {
uint32_t reserved;
@@ -71,7 +80,11 @@
uint32_t out_size;
};
+DECLARE_CLASS(scmi_driver);
+
+int scmi_attach(device_t dev);
int scmi_request(device_t dev, struct scmi_req *req);
+
void scmi_shmem_read(device_t dev, bus_size_t offset, void *buf,
bus_size_t len);
void scmi_shmem_write(device_t dev, bus_size_t offset, const void *buf,
diff --git a/sys/dev/firmware/arm/scmi.c b/sys/dev/firmware/arm/scmi.c
--- a/sys/dev/firmware/arm/scmi.c
+++ b/sys/dev/firmware/arm/scmi.c
@@ -47,15 +47,6 @@
#include "scmi.h"
#include "scmi_protocols.h"
-struct scmi_softc {
- struct simplebus_softc simplebus_sc;
- device_t dev;
- device_t tx_shmem;
- struct arm_doorbell *db;
- struct mtx mtx;
- int req_done;
-};
-
static device_t
scmi_get_shmem(struct scmi_softc *sc, int index)
{
@@ -90,26 +81,11 @@
return (dev);
}
-static void
-scmi_callback(void *arg)
-{
- struct scmi_softc *sc;
-
- sc = arg;
-
- dprintf("%s sc %p\n", __func__, sc);
-
- SCMI_LOCK(sc);
- sc->req_done = 1;
- wakeup(sc);
- SCMI_UNLOCK(sc);
-}
-
static int
scmi_request_locked(struct scmi_softc *sc, struct scmi_req *req)
{
struct scmi_smt_header hdr;
- int timeout;
+ int ret;
bzero(&hdr, sizeof(struct scmi_smt_header));
@@ -125,6 +101,7 @@
hdr.channel_status &= ~SCMI_SHMEM_CHAN_STAT_CHANNEL_FREE;
hdr.msg_header = req->protocol_id << SMT_HEADER_PROTOCOL_ID_S;
hdr.msg_header |= req->message_id << SMT_HEADER_MESSAGE_ID_S;
+ /* TODO: Allocate a token */
hdr.length = sizeof(hdr.msg_header) + req->in_size;
hdr.flags |= SCMI_SHMEM_FLAG_INTR_ENABLED;
@@ -135,31 +112,9 @@
scmi_shmem_write(sc->tx_shmem, SMT_HEADER_SIZE, req->in_buf,
req->in_size);
- sc->req_done = 0;
-
- /* Interrupt SCP firmware. */
- arm_doorbell_set(sc->db);
-
- timeout = 200;
-
- dprintf("%s: request\n", __func__);
-
- do {
- if (cold) {
- if (arm_doorbell_get(sc->db))
- break;
- DELAY(10000);
- } else {
- msleep(sc, &sc->mtx, 0, "scmi", hz / 10);
- if (sc->req_done)
- break;
- }
- } while (timeout--);
-
- if (timeout <= 0)
- return (-1);
-
- dprintf("%s: got reply, timeout %d\n", __func__, timeout);
+ ret = SCMI_XFER_MSG(sc->dev);
+ if (ret != 0)
+ return (ret);
/* Read header. */
scmi_shmem_read(sc->tx_shmem, 0, &hdr, SMT_HEADER_SIZE);
@@ -186,22 +141,7 @@
return (error);
}
-static int
-scmi_probe(device_t dev)
-{
-
- if (!ofw_bus_is_compatible(dev, "arm,scmi"))
- return (ENXIO);
-
- if (!ofw_bus_status_okay(dev))
- return (ENXIO);
-
- device_set_desc(dev, "ARM SCMI interface driver");
-
- return (BUS_PROBE_DEFAULT);
-}
-
-static int
+int
scmi_attach(device_t dev)
{
struct scmi_softc *sc;
@@ -221,16 +161,8 @@
return (ENXIO);
}
- sc->db = arm_doorbell_ofw_get(sc->dev, "tx");
- if (sc->db == NULL) {
- device_printf(dev, "Doorbell device not found.\n");
- return (ENXIO);
- }
-
mtx_init(&sc->mtx, device_get_nameunit(dev), "SCMI", MTX_DEF);
- arm_doorbell_set_handler(sc->db, scmi_callback, sc);
-
simplebus_init(dev, node);
/*
@@ -257,9 +189,9 @@
}
static device_method_t scmi_methods[] = {
- DEVMETHOD(device_probe, scmi_probe),
DEVMETHOD(device_attach, scmi_attach),
DEVMETHOD(device_detach, scmi_detach),
+
DEVMETHOD_END
};
diff --git a/sys/dev/firmware/arm/scmi_if.m b/sys/dev/firmware/arm/scmi_if.m
new file mode 100644
--- /dev/null
+++ b/sys/dev/firmware/arm/scmi_if.m
@@ -0,0 +1,32 @@
+#-
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2023 Arm Ltd
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice unmodified, this list of conditions, and the following
+# disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+INTERFACE scmi;
+
+METHOD int xfer_msg {
+ device_t dev;
+};
diff --git a/sys/dev/firmware/arm/scmi_mailbox.c b/sys/dev/firmware/arm/scmi_mailbox.c
new file mode 100644
--- /dev/null
+++ b/sys/dev/firmware/arm/scmi_mailbox.c
@@ -0,0 +1,178 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2022 Ruslan Bukin <br@bsdpad.com>
+ * Copyright (c) 2023 Arm Ltd
+ *
+ * This work was supported by Innovate UK project 105694, "Digital Security
+ * by Design (DSbD) Technology Platform Prototype".
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/cpu.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/module.h>
+#include <sys/mutex.h>
+
+#include <dev/clk/clk.h>
+#include <dev/fdt/simplebus.h>
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include "dev/mailbox/arm/arm_doorbell.h"
+
+#include "scmi.h"
+#include "scmi_protocols.h"
+
+struct scmi_mailbox_softc {
+ struct scmi_softc base;
+ struct arm_doorbell *db;
+ int req_done;
+};
+
+static void
+scmi_mailbox_callback(void *arg)
+{
+ struct scmi_mailbox_softc *sc;
+
+ sc = arg;
+
+ dprintf("%s sc %p\n", __func__, sc);
+
+ SCMI_LOCK(&sc->base);
+ sc->req_done = 1;
+ wakeup(sc);
+ SCMI_UNLOCK(&sc->base);
+}
+
+static int
+scmi_mailbox_xfer_msg(device_t dev)
+{
+ struct scmi_mailbox_softc *sc;
+ int timeout;
+
+ sc = device_get_softc(dev);
+ SCMI_ASSERT_LOCKED(&sc->base);
+
+ sc->req_done = 0;
+
+ /* Interrupt SCP firmware. */
+ arm_doorbell_set(sc->db);
+
+ timeout = 200;
+
+ dprintf("%s: request\n", __func__);
+
+ do {
+ if (cold) {
+ if (arm_doorbell_get(sc->db))
+ break;
+ DELAY(10000);
+ } else {
+ msleep(sc, &sc->base.mtx, 0, "scmi", hz / 10);
+ if (sc->req_done)
+ break;
+ }
+ } while (timeout--);
+
+ if (timeout <= 0)
+ return (-1);
+
+ dprintf("%s: got reply, timeout %d\n", __func__, timeout);
+
+ return (0);
+}
+
+static int
+scmi_mailbox_probe(device_t dev)
+{
+
+ if (!ofw_bus_is_compatible(dev, "arm,scmi"))
+ return (ENXIO);
+
+ if (!ofw_bus_status_okay(dev))
+ return (ENXIO);
+
+ device_set_desc(dev, "ARM SCMI interface driver");
+
+ return (BUS_PROBE_DEFAULT);
+}
+
+static int
+scmi_mailbox_attach(device_t dev)
+{
+ struct scmi_mailbox_softc *sc;
+ int ret;
+
+ sc = device_get_softc(dev);
+
+ /* TODO: Support other mailbox devices */
+ sc->db = arm_doorbell_ofw_get(dev, "tx");
+ if (sc->db == NULL) {
+ device_printf(dev, "Doorbell device not found.\n");
+ return (ENXIO);
+ }
+
+ arm_doorbell_set_handler(sc->db, scmi_mailbox_callback, sc);
+
+ ret = scmi_attach(dev);
+ if (ret != 0)
+ arm_doorbell_set_handler(sc->db, NULL, NULL);
+
+ return (ret);
+}
+
+static int
+scmi_mailbox_detach(device_t dev)
+{
+ struct scmi_mailbox_softc *sc;
+
+ sc = device_get_softc(dev);
+
+ arm_doorbell_set_handler(sc->db, NULL, NULL);
+
+ return (0);
+}
+
+static device_method_t scmi_mailbox_methods[] = {
+ DEVMETHOD(device_probe, scmi_mailbox_probe),
+ DEVMETHOD(device_attach, scmi_mailbox_attach),
+ DEVMETHOD(device_detach, scmi_mailbox_detach),
+
+ /* SCMI interface */
+ DEVMETHOD(scmi_xfer_msg, scmi_mailbox_xfer_msg),
+
+ DEVMETHOD_END
+};
+
+DEFINE_CLASS_1(scmi_mailbox, scmi_mailbox_driver, scmi_mailbox_methods,
+ sizeof(struct scmi_mailbox_softc), scmi_driver);
+
+DRIVER_MODULE(scmi_mailbox, simplebus, scmi_mailbox_driver, 0, 0);
+MODULE_VERSION(scmi_mailbox, 1);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Nov 18, 9:38 AM (13 h, 8 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
14695480
Default Alt Text
D43039.id136878.diff (10 KB)
Attached To
Mode
D43039: scmi: Split out the SCMI mailbox to a new file
Attached
Detach File
Event Timeline
Log In to Comment