Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F96868024
D40803.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
3 KB
Referenced Files
None
Subscribers
None
D40803.diff
View Options
diff --git a/tools/tools/bhyve/Makefile b/tools/tools/bhyve/Makefile
new file mode 100644
--- /dev/null
+++ b/tools/tools/bhyve/Makefile
@@ -0,0 +1,8 @@
+PROGS= fwctl_fetch
+MAN=
+BINDIR?= /usr/local/bin
+
+# fwctl_fetch: fetch the value of fwctl nodes from a guest
+LIBADD.fwctl_fetch+= util
+
+.include <bsd.progs.mk>
diff --git a/tools/tools/bhyve/fwctl_fetch.c b/tools/tools/bhyve/fwctl_fetch.c
new file mode 100644
--- /dev/null
+++ b/tools/tools/bhyve/fwctl_fetch.c
@@ -0,0 +1,137 @@
+/*-
+ * Copyright (c) 2023 John Baldwin <jhb@FreeBSD.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <sys/param.h>
+#include <err.h>
+#include <fcntl.h>
+#include <libutil.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <machine/cpufunc.h>
+
+#define OP_GET 3
+#define OP_GET_LEN 4
+
+/* I/O ports */
+#define FWCTL_OUT 0x510
+#define FWCTL_IN 0x511
+
+static void
+reset_fwctl(void)
+{
+ char buf[4];
+
+ outw(FWCTL_OUT, 0);
+ for (u_int i = 0; i < 4; i++)
+ buf[i] = inb(FWCTL_IN);
+ if (memcmp(buf, "BHYV", 4) != 0)
+ errx(1, "Signature mismatch: %.4s", buf);
+}
+
+static void
+send_node_name(const char *name)
+{
+ uint32_t value;
+ size_t len;
+
+ len = strlen(name) + 1;
+ while (len > 4) {
+ memcpy(&value, name, 4);
+ outl(FWCTL_OUT, value);
+ name += 4;
+ len -= 4;
+ }
+
+ if (len > 0) {
+ value = 0;
+ memcpy(&value, name, len);
+ outl(FWCTL_OUT, value);
+ }
+}
+
+static void
+fwctl_op(uint32_t op, uint32_t id, const char *name, void *buf, size_t len)
+{
+ char *cp;
+ uint32_t value, rsplen;
+
+ /* Length */
+ outl(FWCTL_OUT, 12 + strlen(name) + 1);
+
+ /* Operation */
+ outl(FWCTL_OUT, op);
+
+ /* Transaction ID */
+ outl(FWCTL_OUT, id);
+
+ send_node_name(name);
+
+ /* Length */
+ rsplen = inl(FWCTL_IN);
+
+ /* If there is an error, the response will have no payload. */
+ if (rsplen < 4 * sizeof(value))
+ errx(1, "Invalid response length (%u): %u", id, rsplen);
+
+ /* Operation */
+ value = inl(FWCTL_IN);
+ if (value != op)
+ errx(1, "Invalid response type (%u): %u", id, value);
+
+ /* Transaction ID */
+ value = inl(FWCTL_IN);
+ if (value != id)
+ errx(1, "Invalid response ID (%u): %u", id, value);
+
+ /* Error */
+ value = inl(FWCTL_IN);
+ if (value != 0)
+ errx(1, "Error from op %u (%u): %u", op, id, value);
+
+ /* If there wasn't an error, require payload length to match */
+ if (rsplen != 4 * sizeof(value) + len)
+ errx(1, "Response payload length mismatch (%u): %zu vs %zu", id,
+ rsplen - 4 * sizeof(value), len);
+
+ cp = buf;
+ while (len > 0) {
+ value = inl(FWCTL_IN);
+ memcpy(cp, &value, 4);
+ cp += 4;
+ len -= 4;
+ }
+}
+
+int
+main(int ac, char **av)
+{
+ char *p;
+ size_t len, buflen, len2;
+
+ if (ac != 2)
+ errx(1, "Need node name");
+
+ if (open("/dev/io", O_RDWR) == -1)
+ err(1, "Failed to open /dev/io");
+
+ reset_fwctl();
+
+ fwctl_op(OP_GET_LEN, 1, av[1], &len, sizeof(len));
+ if (len == 0)
+ errx(1, "Node has length of 0");
+
+ /* Buffer includes embedded length followed by value. */
+ buflen = sizeof(size_t) + roundup2(len, 4);
+ p = malloc(buflen);
+ fwctl_op(OP_GET, 2, av[1], p, buflen);
+ memcpy(&len2, p, sizeof(len2));
+ if (len2 != len)
+ errx(1, "Length mismatch: %zu vs %zu", len, len2);
+ hexdump(p + sizeof(len2), len, NULL, 0);
+
+ return (0);
+}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Sep 28, 12:14 AM (21 h, 50 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
12955054
Default Alt Text
D40803.diff (3 KB)
Attached To
Mode
D40803: fwctl_fetch: A small test utility for the fwctl bhyve device.
Attached
Detach File
Event Timeline
Log In to Comment