2 * Copyright (c) 2023 John Baldwin <jhb@FreeBSD.org>
4 * SPDX-License-Identifier: BSD-2-Clause
8 * Fetch the value of fwctl nodes from a guest.
10 * Usage: fwctl_fetch <node>
13 #include <sys/param.h>
20 #include <machine/cpufunc.h>
26 #define FWCTL_OUT 0x510
27 #define FWCTL_IN 0x511
35 for (u_int i = 0; i < 4; i++)
36 buf[i] = inb(FWCTL_IN);
37 if (memcmp(buf, "BHYV", 4) != 0)
38 errx(1, "Signature mismatch: %.4s", buf);
42 send_node_name(const char *name)
47 len = strlen(name) + 1;
49 memcpy(&value, name, 4);
50 outl(FWCTL_OUT, value);
57 memcpy(&value, name, len);
58 outl(FWCTL_OUT, value);
63 fwctl_op(uint32_t op, uint32_t id, const char *name, void *buf, size_t len)
66 uint32_t value, rsplen;
69 outl(FWCTL_OUT, 12 + strlen(name) + 1);
80 rsplen = inl(FWCTL_IN);
82 /* If there is an error, the response will have no payload. */
83 if (rsplen < 4 * sizeof(value))
84 errx(1, "Invalid response length (%u): %u", id, rsplen);
87 value = inl(FWCTL_IN);
89 errx(1, "Invalid response type (%u): %u", id, value);
92 value = inl(FWCTL_IN);
94 errx(1, "Invalid response ID (%u): %u", id, value);
97 value = inl(FWCTL_IN);
99 errx(1, "Error from op %u (%u): %u", op, id, value);
101 /* If there wasn't an error, require payload length to match */
102 if (rsplen != 4 * sizeof(value) + len)
103 errx(1, "Response payload length mismatch (%u): %zu vs %zu", id,
104 rsplen - 4 * sizeof(value), len);
108 value = inl(FWCTL_IN);
109 memcpy(cp, &value, 4);
116 main(int ac, char **av)
119 size_t len, buflen, len2;
122 errx(1, "Need node name");
124 if (open("/dev/io", O_RDWR) == -1)
125 err(1, "Failed to open /dev/io");
129 fwctl_op(OP_GET_LEN, 1, av[1], &len, sizeof(len));
131 errx(1, "Node has length of 0");
133 /* Buffer includes embedded length followed by value. */
134 buflen = sizeof(size_t) + roundup2(len, 4);
136 fwctl_op(OP_GET, 2, av[1], p, buflen);
137 memcpy(&len2, p, sizeof(len2));
139 errx(1, "Length mismatch: %zu vs %zu", len, len2);
140 hexdump(p + sizeof(len2), len, NULL, 0);