1/*	$OpenBSD: acpihve.c,v 1.4 2022/04/06 18:59:27 naddy Exp $	*/
2
3/*
4 * Copyright (c) 2017 Jonathan Gray <jsg@openbsd.org>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19#include <sys/param.h>
20#include <sys/systm.h>
21#include <sys/device.h>
22
23#include <dev/acpi/acpireg.h>
24#include <dev/acpi/acpivar.h>
25
26int	 acpihve_match(struct device *, void *, void *);
27void	 acpihve_attach(struct device *, struct device *, void *);
28
29struct acpi_oem0 {
30	struct acpi_table_header	hdr;
31	uint32_t			entropy[16];
32} __packed;
33
34struct acpihve_softc {
35	struct device			sc_dev;
36};
37
38const struct cfattach acpihve_ca = {
39	sizeof(struct acpihve_softc), acpihve_match, acpihve_attach
40};
41
42struct cfdriver acpihve_cd = {
43	NULL, "acpihve", DV_DULL
44};
45
46int	 acpihve_attached;
47
48int
49acpihve_match(struct device *parent, void *match, void *aux)
50{
51	struct acpi_attach_args *aaa = aux;
52	struct acpi_table_header *hdr;
53
54	/*
55	 * If we do not have a table, it is not us; attach only once
56	 */
57	if (acpihve_attached || aaa->aaa_table == NULL)
58		return (0);
59
60	hdr = (struct acpi_table_header *)aaa->aaa_table;
61	if (memcmp(hdr->signature, "OEM0", 4) != 0 ||
62	    memcmp(hdr->oemid, "VRTUAL", 6) != 0 ||
63	    memcmp(hdr->oemtableid, "MICROSFT", 8) != 0)
64		return (0);
65
66	return (1);
67}
68
69void
70acpihve_attach(struct device *parent, struct device *self, void *aux)
71{
72	struct acpi_attach_args *aaa = aux;
73	struct acpi_oem0 *oem0 = (struct acpi_oem0 *)aaa->aaa_table;
74	int i;
75
76	acpihve_attached++;
77
78	if (oem0->hdr.length != sizeof(*oem0)) {
79		printf(": unexpected table length %u\n", oem0->hdr.length);
80		return;
81	}
82
83	/* 64 bytes of entropy from OEM0 table */
84	for (i = 0; i < nitems(oem0->entropy); i++)
85		enqueue_randomness(oem0->entropy[i]);
86
87	printf("\n");
88}
89