2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
4 * Copyright (c) 2021 Beckhoff Automation GmbH & Co. KG
5 * Author: Corvin Köhne <c.koehne@beckhoff.com>
11 #include <machine/vmm.h>
19 #include "acpi_device.h"
22 * List entry to enumerate all resources used by an ACPI device.
24 * @param chain Used to chain multiple elements together.
25 * @param type Type of the ACPI resource.
26 * @param data Data of the ACPI resource.
28 struct acpi_resource_list_entry {
29 SLIST_ENTRY(acpi_resource_list_entry) chain;
31 ACPI_RESOURCE_DATA data;
35 * Holds information about an ACPI device.
37 * @param vm_ctx VM context the ACPI device was created in.
38 * @param emul Device emulation struct. It contains some information like the
39 name of the ACPI device and some device specific functions.
40 * @param crs Current resources used by the ACPI device.
44 const struct acpi_device_emul *emul;
45 SLIST_HEAD(acpi_resource_list, acpi_resource_list_entry) crs;
49 acpi_device_create(struct acpi_device **const new_dev,
50 struct vmctx *const vm_ctx, const struct acpi_device_emul *const emul)
52 assert(new_dev != NULL);
53 assert(vm_ctx != NULL);
56 struct acpi_device *const dev = calloc(1, sizeof(*dev));
63 SLIST_INIT(&dev->crs);
65 const int error = acpi_tables_add_device(dev);
67 acpi_device_destroy(dev);
77 acpi_device_destroy(struct acpi_device *const dev)
83 struct acpi_resource_list_entry *res;
84 while (!SLIST_EMPTY(&dev->crs)) {
85 res = SLIST_FIRST(&dev->crs);
86 SLIST_REMOVE_HEAD(&dev->crs, chain);
94 acpi_device_add_res_fixed_ioport(struct acpi_device *const dev,
95 const UINT16 port, const UINT8 length)
101 struct acpi_resource_list_entry *const res = calloc(1, sizeof(*res));
106 res->type = ACPI_RESOURCE_TYPE_FIXED_IO;
107 res->data.FixedIo.Address = port;
108 res->data.FixedIo.AddressLength = length;
110 SLIST_INSERT_HEAD(&dev->crs, res, chain);
116 acpi_device_add_res_fixed_memory32(struct acpi_device *const dev,
117 const UINT8 write_protected, const UINT32 address, const UINT32 length)
123 struct acpi_resource_list_entry *const res = calloc(1, sizeof(*res));
128 res->type = ACPI_RESOURCE_TYPE_FIXED_MEMORY32;
129 res->data.FixedMemory32.WriteProtect = write_protected;
130 res->data.FixedMemory32.Address = address;
131 res->data.FixedMemory32.AddressLength = length;
133 SLIST_INSERT_HEAD(&dev->crs, res, chain);
139 acpi_device_write_dsdt_crs(const struct acpi_device *const dev)
141 const struct acpi_resource_list_entry *res;
142 SLIST_FOREACH(res, &dev->crs, chain) {
144 case ACPI_RESOURCE_TYPE_FIXED_IO:
145 dsdt_fixed_ioport(res->data.FixedIo.Address,
146 res->data.FixedIo.AddressLength);
148 case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
149 dsdt_fixed_mem32(res->data.FixedMemory32.Address,
150 res->data.FixedMemory32.AddressLength);
160 acpi_device_write_dsdt(const struct acpi_device *const dev)
167 dsdt_line(" Scope (\\_SB)");
169 dsdt_line(" Device (%s)", dev->emul->name);
171 dsdt_line(" Name (_HID, \"%s\")", dev->emul->hid);
172 dsdt_line(" Name (_STA, 0x0F)");
173 dsdt_line(" Name (_CRS, ResourceTemplate ()");
176 acpi_device_write_dsdt_crs(dev);