[wip][qemu][edu] Introduce a QEMU Edu Driver
The QEMU Edu device is a device used for educational purposes. The
spec for the device can be found at the following url:
https://github.com/qemu/qemu/blob/master/docs/specs/edu.txt
This CL introduces the following:
+ A Driver for the QEMU Edu Device
+ Supports the Factorial and Liveness Check Functions
+ Reports Device Version Number via Inspect
- Does not support IRQ or DMA as of yet
- Does not have an accompanying test as of yet
+ A FIDL interface to interact with the device
+ An eductl command line utility to issue commands against
the device.
Change-Id: I1e387a9e1157ba27540d0ce0e924e69f40742403
diff --git a/build/drivers/all_drivers_list.txt b/build/drivers/all_drivers_list.txt
index 1d2a6dd..2d6f556 100644
--- a/build/drivers/all_drivers_list.txt
+++ b/build/drivers/all_drivers_list.txt
@@ -143,6 +143,7 @@
//src/devices/misc/drivers/compat:v1_test
//src/devices/misc/drivers/cpu-trace:cpu-trace-driver
//src/devices/misc/drivers/packaged:lib
+//src/devices/misc/drivers/qemu-edu:driver
//src/devices/misc/drivers/test-parent:test-parent-sys_driver
//src/devices/misc/drivers/test:test-driver
//src/devices/misc/drivers/virtio-rng:virtio_rng-driver
diff --git a/src/devices/bind/fuchsia.pci/fuchsia.pci.bind b/src/devices/bind/fuchsia.pci/fuchsia.pci.bind
index 0ee924d..a58ce03 100644
--- a/src/devices/bind/fuchsia.pci/fuchsia.pci.bind
+++ b/src/devices/bind/fuchsia.pci/fuchsia.pci.bind
@@ -18,6 +18,7 @@
BROADCOM = 0x14e4,
ATHEROS = 0x168c,
INTEL = 0x8086,
+ QEMU_TEST = 0x1234,
};
extend uint fuchsia.BIND_PCI_DID {
@@ -41,6 +42,7 @@
RTL8111 = 0x8168,
INTEL_SPT_SPI0 = 0x9d29,
GOOGLE_GRAPHICS_ADAPTER = 0xa002,
+ QEMU_EDU = 0x11e8,
};
extend uint fuchsia.BIND_PCI_CLASS {
diff --git a/src/devices/misc/bin/BUILD.gn b/src/devices/misc/bin/BUILD.gn
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/devices/misc/bin/BUILD.gn
diff --git a/src/devices/misc/drivers/qemu-edu/BUILD.gn b/src/devices/misc/drivers/qemu-edu/BUILD.gn
new file mode 100644
index 0000000..ce361e1
--- /dev/null
+++ b/src/devices/misc/drivers/qemu-edu/BUILD.gn
@@ -0,0 +1,43 @@
+# Copyright 2022 The Fuchsia Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//build/bind/bind.gni")
+import("//build/components.gni")
+import("//build/drivers.gni")
+
+driver_bind_rules("qemu_edu_bind") {
+ rules = "qemu-edu.bind"
+ header_output = "qemu_edu_bind.h"
+ tests = "bind_tests.json"
+ deps = [ "//src/devices/bind/fuchsia.pci" ]
+}
+
+common_deps = [
+ ":qemu_edu_bind",
+ "//src/devices/lib/driver",
+ "//src/lib/ddktl",
+ "//zircon/system/ulib/inspect",
+]
+
+fuchsia_driver("driver") {
+ output_name = "qemu-edu"
+ deps = common_deps
+ sources = [ "qemu-edu.cc" ]
+}
+
+fuchsia_driver_component("driver_component") {
+ component_name = "qemu-edu"
+ deps = [ ":driver" ]
+ info = "driver-info.json"
+}
+
+fuchsia_driver_package("qemu-edu") {
+ package_name = "qemu-edu"
+ driver_components = [ ":driver_component" ]
+}
+
+group("tests") {
+ testonly = true
+ deps = [ ":qemu_edu_bind_test" ]
+}
diff --git a/src/devices/misc/drivers/qemu-edu/bind_tests.json b/src/devices/misc/drivers/qemu-edu/bind_tests.json
new file mode 100644
index 0000000..a4873ef
--- /dev/null
+++ b/src/devices/misc/drivers/qemu-edu/bind_tests.json
@@ -0,0 +1,43 @@
+[
+ {
+ "device": {
+ "fuchsia.BIND_PROTOCOL": "fuchsia.bluetooth.BIND_PROTOCOL.DEVICE"
+ },
+ "expected": "abort",
+ "name": "Protocol"
+ },
+ {
+ "device": {
+ "fuchsia.BIND_COMPOSITE": "1",
+ "fuchsia.BIND_PCI_DID": "fuchsia.pci.BIND_PCI_DID.QEMU_EDU",
+ "fuchsia.BIND_PCI_VID": "fuchsia.pci.BIND_PCI_VID.QEMU_TEST",
+ "fuchsia.BIND_PROTOCOL": "fuchsia.pci.BIND_PROTOCOL.DEVICE"
+ },
+ "expected": "match",
+ "name": "Qemu EDU"
+ },
+ {
+ "device": {
+ "fuchsia.BIND_PCI_DID": "fuchsia.pci.BIND_PCI_DID.QEMU_EDU",
+ "fuchsia.BIND_PCI_VID": "fuchsia.pci.BIND_PCI_VID.QEMU_TEST"
+ },
+ "expected": "abort",
+ "name": "Missing Protocol"
+ },
+ {
+ "device": {
+ "fuchsia.BIND_PCI_DID": "fuchsia.pci.BIND_PCI_DID.QEMU_EDU",
+ "fuchsia.BIND_PROTOCOL": "fuchsia.pci.BIND_PROTOCOL.DEVICE"
+ },
+ "expected": "abort",
+ "name": "Missing PCI VID"
+ },
+ {
+ "device": {
+ "fuchsia.BIND_PCI_VID": "fuchsia.pci.BIND_PCI_VID.QEMU_TEST",
+ "fuchsia.BIND_PROTOCOL": "fuchsia.pci.BIND_PROTOCOL.DEVICE"
+ },
+ "expected": "abort",
+ "name": "Missing PCI DID"
+ }
+]
diff --git a/src/devices/misc/drivers/qemu-edu/driver-info.json b/src/devices/misc/drivers/qemu-edu/driver-info.json
new file mode 100644
index 0000000..b40b202
--- /dev/null
+++ b/src/devices/misc/drivers/qemu-edu/driver-info.json
@@ -0,0 +1,9 @@
+{
+ "short_description": "QEMU Edu Device Driver",
+ "manufacturer": "QEMU",
+ "families": [],
+ "models": [],
+ "areas": [
+ "Misc"
+ ]
+}
diff --git a/src/devices/misc/drivers/qemu-edu/qemu-edu.bind b/src/devices/misc/drivers/qemu-edu/qemu-edu.bind
new file mode 100644
index 0000000..62bbfab
--- /dev/null
+++ b/src/devices/misc/drivers/qemu-edu/qemu-edu.bind
@@ -0,0 +1,10 @@
+// Copyright 2022 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+using fuchsia.pci;
+
+fuchsia.BIND_PROTOCOL == fuchsia.pci.BIND_PROTOCOL.DEVICE;
+fuchsia.BIND_PCI_VID == fuchsia.pci.BIND_PCI_VID.QEMU_TEST;
+fuchsia.BIND_PCI_DID == fuchsia.pci.BIND_PCI_DID.QEMU_EDU;
+//fuchsia.BIND_COMPOSITE == 1;
diff --git a/src/devices/misc/drivers/qemu-edu/qemu-edu.cc b/src/devices/misc/drivers/qemu-edu/qemu-edu.cc
new file mode 100644
index 0000000..77eea6d
--- /dev/null
+++ b/src/devices/misc/drivers/qemu-edu/qemu-edu.cc
@@ -0,0 +1,40 @@
+// Copyright 2022 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "qemu-edu.h"
+
+#include <lib/ddk/driver.h>
+
+#include "src/devices/misc/drivers/qemu-edu/qemu_edu_bind.h"
+
+namespace qemu_edu {
+
+zx_status_t QemuEduDevice::Create(void* ctx, zx_device_t* parent) {
+ auto dev = std::make_unique<QemuEduDevice>(parent);
+
+ zx_status_t status = dev->DdkAdd(ddk::DeviceAddArgs("qemu-edu")
+ .set_flags(DEVICE_ADD_NON_BINDABLE)
+ .set_inspect_vmo(dev->inspector_.DuplicateVmo()));
+
+ if (status != ZX_OK) {
+ zxlogf(ERROR, "ddk add failed, st = %d", status);
+ return status;
+ }
+
+ __UNUSED auto ptr = dev.release();
+
+ return ZX_OK;
+}
+
+static zx_driver_ops_t driver_ops = []() {
+ zx_driver_ops_t ops = {};
+ ops.version = DRIVER_OPS_VERSION;
+ ops.bind = QemuEduDevice::Create;
+ return ops;
+}();
+
+} // namespace qemu_edu
+
+// clang-format off
+ZIRCON_DRIVER(qemu-edu, qemu_edu::driver_ops, "zircon", "0.1");
diff --git a/src/devices/misc/drivers/qemu-edu/qemu-edu.h b/src/devices/misc/drivers/qemu-edu/qemu-edu.h
new file mode 100644
index 0000000..de25a2c
--- /dev/null
+++ b/src/devices/misc/drivers/qemu-edu/qemu-edu.h
@@ -0,0 +1,35 @@
+// Copyright 2022 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+#ifndef SRC_DEVICES_MISC_DRIVERS_QEMU_EDU_QEMU_EDU_H_
+#define SRC_DEVICES_MISC_DRIVERS_QEMU_EDU_QEMU_EDU_H_
+
+#include <lib/inspect/cpp/inspector.h>
+
+#include <ddktl/device.h>
+
+namespace qemu_edu {
+
+class QemuEduDevice;
+using DeviceType =
+ ddk::Device<QemuEduDevice>;
+
+class QemuEduDevice : public DeviceType {
+ public:
+ QemuEduDevice(zx_device_t* device) : DeviceType(device) {}
+
+ // Implement DDK Device Ops
+ static zx_status_t Create(void* ctx, zx_device_t* parent);
+ void DdkRelease() { delete this; }
+
+ protected:
+ inspect::Inspector inspector_;
+ inspect::Node edu_info_ = inspector_.GetRoot().CreateChild("qemu_edu_device");
+
+ private:
+ std::mutex lock_;
+};
+
+} // namespace qemu_edu
+
+#endif // SRC_DEVICES_MISC_DRIVERS_QEMU_EDU_QEMU_EDU_H_