summaryrefslogtreecommitdiffstats
path: root/qemu/hw/acpi
diff options
context:
space:
mode:
Diffstat (limited to 'qemu/hw/acpi')
-rw-r--r--qemu/hw/acpi/Makefile.objs8
-rw-r--r--qemu/hw/acpi/acpi_interface.c16
-rw-r--r--qemu/hw/acpi/aml-build.c1565
-rw-r--r--qemu/hw/acpi/bios-linker-loader.c240
-rw-r--r--qemu/hw/acpi/core.c717
-rw-r--r--qemu/hw/acpi/cpu_hotplug.c79
-rw-r--r--qemu/hw/acpi/cpu_hotplug_acpi_table.c136
-rw-r--r--qemu/hw/acpi/ich9.c477
-rw-r--r--qemu/hw/acpi/memory_hotplug.c312
-rw-r--r--qemu/hw/acpi/memory_hotplug_acpi_table.c262
-rw-r--r--qemu/hw/acpi/nvdimm.c706
-rw-r--r--qemu/hw/acpi/pcihp.c336
-rw-r--r--qemu/hw/acpi/piix4.c645
-rw-r--r--qemu/hw/acpi/tco.c265
14 files changed, 0 insertions, 5764 deletions
diff --git a/qemu/hw/acpi/Makefile.objs b/qemu/hw/acpi/Makefile.objs
deleted file mode 100644
index faee86c5c..000000000
--- a/qemu/hw/acpi/Makefile.objs
+++ /dev/null
@@ -1,8 +0,0 @@
-common-obj-$(CONFIG_ACPI_X86) += core.o piix4.o pcihp.o
-common-obj-$(CONFIG_ACPI_X86_ICH) += ich9.o tco.o
-common-obj-$(CONFIG_ACPI_CPU_HOTPLUG) += cpu_hotplug.o cpu_hotplug_acpi_table.o
-common-obj-$(CONFIG_ACPI_MEMORY_HOTPLUG) += memory_hotplug.o memory_hotplug_acpi_table.o
-obj-$(CONFIG_ACPI_NVDIMM) += nvdimm.o
-common-obj-$(CONFIG_ACPI) += acpi_interface.o
-common-obj-$(CONFIG_ACPI) += bios-linker-loader.o
-common-obj-$(CONFIG_ACPI) += aml-build.o
diff --git a/qemu/hw/acpi/acpi_interface.c b/qemu/hw/acpi/acpi_interface.c
deleted file mode 100644
index d82131326..000000000
--- a/qemu/hw/acpi/acpi_interface.c
+++ /dev/null
@@ -1,16 +0,0 @@
-#include "qemu/osdep.h"
-#include "hw/acpi/acpi_dev_interface.h"
-#include "qemu/module.h"
-
-static void register_types(void)
-{
- static const TypeInfo acpi_dev_if_info = {
- .name = TYPE_ACPI_DEVICE_IF,
- .parent = TYPE_INTERFACE,
- .class_size = sizeof(AcpiDeviceIfClass),
- };
-
- type_register_static(&acpi_dev_if_info);
-}
-
-type_init(register_types)
diff --git a/qemu/hw/acpi/aml-build.c b/qemu/hw/acpi/aml-build.c
deleted file mode 100644
index ab89ca638..000000000
--- a/qemu/hw/acpi/aml-build.c
+++ /dev/null
@@ -1,1565 +0,0 @@
-/* Support for generating ACPI tables and passing them to Guests
- *
- * Copyright (C) 2015 Red Hat Inc
- *
- * Author: Michael S. Tsirkin <mst@redhat.com>
- * Author: Igor Mammedov <imammedo@redhat.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "qemu/osdep.h"
-#include <glib/gprintf.h>
-#include "hw/acpi/aml-build.h"
-#include "qemu/bswap.h"
-#include "qemu/bitops.h"
-#include "hw/acpi/bios-linker-loader.h"
-
-static GArray *build_alloc_array(void)
-{
- return g_array_new(false, true /* clear */, 1);
-}
-
-static void build_free_array(GArray *array)
-{
- g_array_free(array, true);
-}
-
-static void build_prepend_byte(GArray *array, uint8_t val)
-{
- g_array_prepend_val(array, val);
-}
-
-static void build_append_byte(GArray *array, uint8_t val)
-{
- g_array_append_val(array, val);
-}
-
-static void build_append_array(GArray *array, GArray *val)
-{
- g_array_append_vals(array, val->data, val->len);
-}
-
-#define ACPI_NAMESEG_LEN 4
-
-static void
-build_append_nameseg(GArray *array, const char *seg)
-{
- int len;
-
- len = strlen(seg);
- assert(len <= ACPI_NAMESEG_LEN);
-
- g_array_append_vals(array, seg, len);
- /* Pad up to ACPI_NAMESEG_LEN characters if necessary. */
- g_array_append_vals(array, "____", ACPI_NAMESEG_LEN - len);
-}
-
-static void GCC_FMT_ATTR(2, 0)
-build_append_namestringv(GArray *array, const char *format, va_list ap)
-{
- char *s;
- char **segs;
- char **segs_iter;
- int seg_count = 0;
-
- s = g_strdup_vprintf(format, ap);
- segs = g_strsplit(s, ".", 0);
- g_free(s);
-
- /* count segments */
- segs_iter = segs;
- while (*segs_iter) {
- ++segs_iter;
- ++seg_count;
- }
- /*
- * ACPI 5.0 spec: 20.2.2 Name Objects Encoding:
- * "SegCount can be from 1 to 255"
- */
- assert(seg_count > 0 && seg_count <= 255);
-
- /* handle RootPath || PrefixPath */
- s = *segs;
- while (*s == '\\' || *s == '^') {
- build_append_byte(array, *s);
- ++s;
- }
-
- switch (seg_count) {
- case 1:
- if (!*s) {
- build_append_byte(array, 0x00); /* NullName */
- } else {
- build_append_nameseg(array, s);
- }
- break;
-
- case 2:
- build_append_byte(array, 0x2E); /* DualNamePrefix */
- build_append_nameseg(array, s);
- build_append_nameseg(array, segs[1]);
- break;
- default:
- build_append_byte(array, 0x2F); /* MultiNamePrefix */
- build_append_byte(array, seg_count);
-
- /* handle the 1st segment manually due to prefix/root path */
- build_append_nameseg(array, s);
-
- /* add the rest of segments */
- segs_iter = segs + 1;
- while (*segs_iter) {
- build_append_nameseg(array, *segs_iter);
- ++segs_iter;
- }
- break;
- }
- g_strfreev(segs);
-}
-
-GCC_FMT_ATTR(2, 3)
-static void build_append_namestring(GArray *array, const char *format, ...)
-{
- va_list ap;
-
- va_start(ap, format);
- build_append_namestringv(array, format, ap);
- va_end(ap);
-}
-
-/* 5.4 Definition Block Encoding */
-enum {
- PACKAGE_LENGTH_1BYTE_SHIFT = 6, /* Up to 63 - use extra 2 bits. */
- PACKAGE_LENGTH_2BYTE_SHIFT = 4,
- PACKAGE_LENGTH_3BYTE_SHIFT = 12,
- PACKAGE_LENGTH_4BYTE_SHIFT = 20,
-};
-
-static void
-build_prepend_package_length(GArray *package, unsigned length, bool incl_self)
-{
- uint8_t byte;
- unsigned length_bytes;
-
- if (length + 1 < (1 << PACKAGE_LENGTH_1BYTE_SHIFT)) {
- length_bytes = 1;
- } else if (length + 2 < (1 << PACKAGE_LENGTH_3BYTE_SHIFT)) {
- length_bytes = 2;
- } else if (length + 3 < (1 << PACKAGE_LENGTH_4BYTE_SHIFT)) {
- length_bytes = 3;
- } else {
- length_bytes = 4;
- }
-
- /*
- * NamedField uses PkgLength encoding but it doesn't include length
- * of PkgLength itself.
- */
- if (incl_self) {
- /*
- * PkgLength is the length of the inclusive length of the data
- * and PkgLength's length itself when used for terms with
- * explitit length.
- */
- length += length_bytes;
- }
-
- switch (length_bytes) {
- case 1:
- byte = length;
- build_prepend_byte(package, byte);
- return;
- case 4:
- byte = length >> PACKAGE_LENGTH_4BYTE_SHIFT;
- build_prepend_byte(package, byte);
- length &= (1 << PACKAGE_LENGTH_4BYTE_SHIFT) - 1;
- /* fall through */
- case 3:
- byte = length >> PACKAGE_LENGTH_3BYTE_SHIFT;
- build_prepend_byte(package, byte);
- length &= (1 << PACKAGE_LENGTH_3BYTE_SHIFT) - 1;
- /* fall through */
- case 2:
- byte = length >> PACKAGE_LENGTH_2BYTE_SHIFT;
- build_prepend_byte(package, byte);
- length &= (1 << PACKAGE_LENGTH_2BYTE_SHIFT) - 1;
- /* fall through */
- }
- /*
- * Most significant two bits of byte zero indicate how many following bytes
- * are in PkgLength encoding.
- */
- byte = ((length_bytes - 1) << PACKAGE_LENGTH_1BYTE_SHIFT) | length;
- build_prepend_byte(package, byte);
-}
-
-static void
-build_append_pkg_length(GArray *array, unsigned length, bool incl_self)
-{
- GArray *tmp = build_alloc_array();
-
- build_prepend_package_length(tmp, length, incl_self);
- build_append_array(array, tmp);
- build_free_array(tmp);
-}
-
-static void build_package(GArray *package, uint8_t op)
-{
- build_prepend_package_length(package, package->len, true);
- build_prepend_byte(package, op);
-}
-
-static void build_extop_package(GArray *package, uint8_t op)
-{
- build_package(package, op);
- build_prepend_byte(package, 0x5B); /* ExtOpPrefix */
-}
-
-static void build_append_int_noprefix(GArray *table, uint64_t value, int size)
-{
- int i;
-
- for (i = 0; i < size; ++i) {
- build_append_byte(table, value & 0xFF);
- value = value >> 8;
- }
-}
-
-static void build_append_int(GArray *table, uint64_t value)
-{
- if (value == 0x00) {
- build_append_byte(table, 0x00); /* ZeroOp */
- } else if (value == 0x01) {
- build_append_byte(table, 0x01); /* OneOp */
- } else if (value <= 0xFF) {
- build_append_byte(table, 0x0A); /* BytePrefix */
- build_append_int_noprefix(table, value, 1);
- } else if (value <= 0xFFFF) {
- build_append_byte(table, 0x0B); /* WordPrefix */
- build_append_int_noprefix(table, value, 2);
- } else if (value <= 0xFFFFFFFF) {
- build_append_byte(table, 0x0C); /* DWordPrefix */
- build_append_int_noprefix(table, value, 4);
- } else {
- build_append_byte(table, 0x0E); /* QWordPrefix */
- build_append_int_noprefix(table, value, 8);
- }
-}
-
-/*
- * Build NAME(XXXX, 0x00000000) where 0x00000000 is encoded as a dword,
- * and return the offset to 0x00000000 for runtime patching.
- *
- * Warning: runtime patching is best avoided. Only use this as
- * a replacement for DataTableRegion (for guests that don't
- * support it).
- */
-int
-build_append_named_dword(GArray *array, const char *name_format, ...)
-{
- int offset;
- va_list ap;
-
- build_append_byte(array, 0x08); /* NameOp */
- va_start(ap, name_format);
- build_append_namestringv(array, name_format, ap);
- va_end(ap);
-
- build_append_byte(array, 0x0C); /* DWordPrefix */
-
- offset = array->len;
- build_append_int_noprefix(array, 0x00000000, 4);
- assert(array->len == offset + 4);
-
- return offset;
-}
-
-static GPtrArray *alloc_list;
-
-static Aml *aml_alloc(void)
-{
- Aml *var = g_new0(typeof(*var), 1);
-
- g_ptr_array_add(alloc_list, var);
- var->block_flags = AML_NO_OPCODE;
- var->buf = build_alloc_array();
- return var;
-}
-
-static Aml *aml_opcode(uint8_t op)
-{
- Aml *var = aml_alloc();
-
- var->op = op;
- var->block_flags = AML_OPCODE;
- return var;
-}
-
-static Aml *aml_bundle(uint8_t op, AmlBlockFlags flags)
-{
- Aml *var = aml_alloc();
-
- var->op = op;
- var->block_flags = flags;
- return var;
-}
-
-static void aml_free(gpointer data, gpointer user_data)
-{
- Aml *var = data;
- build_free_array(var->buf);
- g_free(var);
-}
-
-Aml *init_aml_allocator(void)
-{
- Aml *var;
-
- assert(!alloc_list);
- alloc_list = g_ptr_array_new();
- var = aml_alloc();
- return var;
-}
-
-void free_aml_allocator(void)
-{
- g_ptr_array_foreach(alloc_list, aml_free, NULL);
- g_ptr_array_free(alloc_list, true);
- alloc_list = 0;
-}
-
-/* pack data with DefBuffer encoding */
-static void build_buffer(GArray *array, uint8_t op)
-{
- GArray *data = build_alloc_array();
-
- build_append_int(data, array->len);
- g_array_prepend_vals(array, data->data, data->len);
- build_free_array(data);
- build_package(array, op);
-}
-
-void aml_append(Aml *parent_ctx, Aml *child)
-{
- GArray *buf = build_alloc_array();
- build_append_array(buf, child->buf);
-
- switch (child->block_flags) {
- case AML_OPCODE:
- build_append_byte(parent_ctx->buf, child->op);
- break;
- case AML_EXT_PACKAGE:
- build_extop_package(buf, child->op);
- break;
- case AML_PACKAGE:
- build_package(buf, child->op);
- break;
- case AML_RES_TEMPLATE:
- build_append_byte(buf, 0x79); /* EndTag */
- /*
- * checksum operations are treated as succeeded if checksum
- * field is zero. [ACPI Spec 1.0b, 6.4.2.8 End Tag]
- */
- build_append_byte(buf, 0);
- /* fall through, to pack resources in buffer */
- case AML_BUFFER:
- build_buffer(buf, child->op);
- break;
- case AML_NO_OPCODE:
- break;
- default:
- assert(0);
- break;
- }
- build_append_array(parent_ctx->buf, buf);
- build_free_array(buf);
-}
-
-/* ACPI 1.0b: 16.2.5.1 Namespace Modifier Objects Encoding: DefScope */
-Aml *aml_scope(const char *name_format, ...)
-{
- va_list ap;
- Aml *var = aml_bundle(0x10 /* ScopeOp */, AML_PACKAGE);
- va_start(ap, name_format);
- build_append_namestringv(var->buf, name_format, ap);
- va_end(ap);
- return var;
-}
-
-/* ACPI 1.0b: 16.2.5.3 Type 1 Opcodes Encoding: DefReturn */
-Aml *aml_return(Aml *val)
-{
- Aml *var = aml_opcode(0xA4 /* ReturnOp */);
- aml_append(var, val);
- return var;
-}
-
-/*
- * ACPI 1.0b: 16.2.3 Data Objects Encoding:
- * encodes: ByteConst, WordConst, DWordConst, QWordConst, ZeroOp, OneOp
- */
-Aml *aml_int(const uint64_t val)
-{
- Aml *var = aml_alloc();
- build_append_int(var->buf, val);
- return var;
-}
-
-/*
- * helper to construct NameString, which returns Aml object
- * for using with aml_append or other aml_* terms
- */
-Aml *aml_name(const char *name_format, ...)
-{
- va_list ap;
- Aml *var = aml_alloc();
- va_start(ap, name_format);
- build_append_namestringv(var->buf, name_format, ap);
- va_end(ap);
- return var;
-}
-
-/* ACPI 1.0b: 16.2.5.1 Namespace Modifier Objects Encoding: DefName */
-Aml *aml_name_decl(const char *name, Aml *val)
-{
- Aml *var = aml_opcode(0x08 /* NameOp */);
- build_append_namestring(var->buf, "%s", name);
- aml_append(var, val);
- return var;
-}
-
-/* ACPI 1.0b: 16.2.6.1 Arg Objects Encoding */
-Aml *aml_arg(int pos)
-{
- Aml *var;
- uint8_t op = 0x68 /* ARG0 op */ + pos;
-
- assert(pos <= 6);
- var = aml_opcode(op);
- return var;
-}
-
-/* ACPI 2.0a: 17.2.4.4 Type 2 Opcodes Encoding: DefToInteger */
-Aml *aml_to_integer(Aml *arg)
-{
- Aml *var = aml_opcode(0x99 /* ToIntegerOp */);
- aml_append(var, arg);
- build_append_byte(var->buf, 0x00 /* NullNameOp */);
- return var;
-}
-
-/* ACPI 2.0a: 17.2.4.4 Type 2 Opcodes Encoding: DefToHexString */
-Aml *aml_to_hexstring(Aml *src, Aml *dst)
-{
- Aml *var = aml_opcode(0x98 /* ToHexStringOp */);
- aml_append(var, src);
- if (dst) {
- aml_append(var, dst);
- } else {
- build_append_byte(var->buf, 0x00 /* NullNameOp */);
- }
- return var;
-}
-
-/* ACPI 2.0a: 17.2.4.4 Type 2 Opcodes Encoding: DefToBuffer */
-Aml *aml_to_buffer(Aml *src, Aml *dst)
-{
- Aml *var = aml_opcode(0x96 /* ToBufferOp */);
- aml_append(var, src);
- if (dst) {
- aml_append(var, dst);
- } else {
- build_append_byte(var->buf, 0x00 /* NullNameOp */);
- }
- return var;
-}
-
-/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefStore */
-Aml *aml_store(Aml *val, Aml *target)
-{
- Aml *var = aml_opcode(0x70 /* StoreOp */);
- aml_append(var, val);
- aml_append(var, target);
- return var;
-}
-
-/**
- * build_opcode_2arg_dst:
- * @op: 1-byte opcode
- * @arg1: 1st operand
- * @arg2: 2nd operand
- * @dst: optional target to store to, set to NULL if it's not required
- *
- * An internal helper to compose AML terms that have
- * "Op Operand Operand Target"
- * pattern.
- *
- * Returns: The newly allocated and composed according to patter Aml object.
- */
-static Aml *
-build_opcode_2arg_dst(uint8_t op, Aml *arg1, Aml *arg2, Aml *dst)
-{
- Aml *var = aml_opcode(op);
- aml_append(var, arg1);
- aml_append(var, arg2);
- if (dst) {
- aml_append(var, dst);
- } else {
- build_append_byte(var->buf, 0x00 /* NullNameOp */);
- }
- return var;
-}
-
-/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefAnd */
-Aml *aml_and(Aml *arg1, Aml *arg2, Aml *dst)
-{
- return build_opcode_2arg_dst(0x7B /* AndOp */, arg1, arg2, dst);
-}
-
-/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefOr */
-Aml *aml_or(Aml *arg1, Aml *arg2, Aml *dst)
-{
- return build_opcode_2arg_dst(0x7D /* OrOp */, arg1, arg2, dst);
-}
-
-/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefLOr */
-Aml *aml_lor(Aml *arg1, Aml *arg2)
-{
- Aml *var = aml_opcode(0x91 /* LOrOp */);
- aml_append(var, arg1);
- aml_append(var, arg2);
- return var;
-}
-
-/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefShiftLeft */
-Aml *aml_shiftleft(Aml *arg1, Aml *count)
-{
- return build_opcode_2arg_dst(0x79 /* ShiftLeftOp */, arg1, count, NULL);
-}
-
-/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefShiftRight */
-Aml *aml_shiftright(Aml *arg1, Aml *count, Aml *dst)
-{
- return build_opcode_2arg_dst(0x7A /* ShiftRightOp */, arg1, count, dst);
-}
-
-/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefLLess */
-Aml *aml_lless(Aml *arg1, Aml *arg2)
-{
- Aml *var = aml_opcode(0x95 /* LLessOp */);
- aml_append(var, arg1);
- aml_append(var, arg2);
- return var;
-}
-
-/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefAdd */
-Aml *aml_add(Aml *arg1, Aml *arg2, Aml *dst)
-{
- return build_opcode_2arg_dst(0x72 /* AddOp */, arg1, arg2, dst);
-}
-
-/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefSubtract */
-Aml *aml_subtract(Aml *arg1, Aml *arg2, Aml *dst)
-{
- return build_opcode_2arg_dst(0x74 /* SubtractOp */, arg1, arg2, dst);
-}
-
-/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefIncrement */
-Aml *aml_increment(Aml *arg)
-{
- Aml *var = aml_opcode(0x75 /* IncrementOp */);
- aml_append(var, arg);
- return var;
-}
-
-/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefDecrement */
-Aml *aml_decrement(Aml *arg)
-{
- Aml *var = aml_opcode(0x76 /* DecrementOp */);
- aml_append(var, arg);
- return var;
-}
-
-/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefIndex */
-Aml *aml_index(Aml *arg1, Aml *idx)
-{
- return build_opcode_2arg_dst(0x88 /* IndexOp */, arg1, idx, NULL);
-}
-
-/* ACPI 1.0b: 16.2.5.3 Type 1 Opcodes Encoding: DefNotify */
-Aml *aml_notify(Aml *arg1, Aml *arg2)
-{
- Aml *var = aml_opcode(0x86 /* NotifyOp */);
- aml_append(var, arg1);
- aml_append(var, arg2);
- return var;
-}
-
-/* helper to call method with 1 argument */
-Aml *aml_call0(const char *method)
-{
- Aml *var = aml_alloc();
- build_append_namestring(var->buf, "%s", method);
- return var;
-}
-
-/* helper to call method with 1 argument */
-Aml *aml_call1(const char *method, Aml *arg1)
-{
- Aml *var = aml_alloc();
- build_append_namestring(var->buf, "%s", method);
- aml_append(var, arg1);
- return var;
-}
-
-/* helper to call method with 2 arguments */
-Aml *aml_call2(const char *method, Aml *arg1, Aml *arg2)
-{
- Aml *var = aml_alloc();
- build_append_namestring(var->buf, "%s", method);
- aml_append(var, arg1);
- aml_append(var, arg2);
- return var;
-}
-
-/* helper to call method with 3 arguments */
-Aml *aml_call3(const char *method, Aml *arg1, Aml *arg2, Aml *arg3)
-{
- Aml *var = aml_alloc();
- build_append_namestring(var->buf, "%s", method);
- aml_append(var, arg1);
- aml_append(var, arg2);
- aml_append(var, arg3);
- return var;
-}
-
-/* helper to call method with 4 arguments */
-Aml *aml_call4(const char *method, Aml *arg1, Aml *arg2, Aml *arg3, Aml *arg4)
-{
- Aml *var = aml_alloc();
- build_append_namestring(var->buf, "%s", method);
- aml_append(var, arg1);
- aml_append(var, arg2);
- aml_append(var, arg3);
- aml_append(var, arg4);
- return var;
-}
-
-/*
- * ACPI 5.0: 6.4.3.8.1 GPIO Connection Descriptor
- * Type 1, Large Item Name 0xC
- */
-
-static Aml *aml_gpio_connection(AmlGpioConnectionType type,
- AmlConsumerAndProducer con_and_pro,
- uint8_t flags, AmlPinConfig pin_config,
- uint16_t output_drive,
- uint16_t debounce_timeout,
- const uint32_t pin_list[], uint32_t pin_count,
- const char *resource_source_name,
- const uint8_t *vendor_data,
- uint16_t vendor_data_len)
-{
- Aml *var = aml_alloc();
- const uint16_t min_desc_len = 0x16;
- uint16_t resource_source_name_len, length;
- uint16_t pin_table_offset, resource_source_name_offset, vendor_data_offset;
- uint32_t i;
-
- assert(resource_source_name);
- resource_source_name_len = strlen(resource_source_name) + 1;
- length = min_desc_len + resource_source_name_len + vendor_data_len;
- pin_table_offset = min_desc_len + 1;
- resource_source_name_offset = pin_table_offset + pin_count * 2;
- vendor_data_offset = resource_source_name_offset + resource_source_name_len;
-
- build_append_byte(var->buf, 0x8C); /* GPIO Connection Descriptor */
- build_append_int_noprefix(var->buf, length, 2); /* Length */
- build_append_byte(var->buf, 1); /* Revision ID */
- build_append_byte(var->buf, type); /* GPIO Connection Type */
- /* General Flags (2 bytes) */
- build_append_int_noprefix(var->buf, con_and_pro, 2);
- /* Interrupt and IO Flags (2 bytes) */
- build_append_int_noprefix(var->buf, flags, 2);
- /* Pin Configuration 0 = Default 1 = Pull-up 2 = Pull-down 3 = No Pull */
- build_append_byte(var->buf, pin_config);
- /* Output Drive Strength (2 bytes) */
- build_append_int_noprefix(var->buf, output_drive, 2);
- /* Debounce Timeout (2 bytes) */
- build_append_int_noprefix(var->buf, debounce_timeout, 2);
- /* Pin Table Offset (2 bytes) */
- build_append_int_noprefix(var->buf, pin_table_offset, 2);
- build_append_byte(var->buf, 0); /* Resource Source Index */
- /* Resource Source Name Offset (2 bytes) */
- build_append_int_noprefix(var->buf, resource_source_name_offset, 2);
- /* Vendor Data Offset (2 bytes) */
- build_append_int_noprefix(var->buf, vendor_data_offset, 2);
- /* Vendor Data Length (2 bytes) */
- build_append_int_noprefix(var->buf, vendor_data_len, 2);
- /* Pin Number (2n bytes)*/
- for (i = 0; i < pin_count; i++) {
- build_append_int_noprefix(var->buf, pin_list[i], 2);
- }
-
- /* Resource Source Name */
- build_append_namestring(var->buf, "%s", resource_source_name);
- build_append_byte(var->buf, '\0');
-
- /* Vendor-defined Data */
- if (vendor_data != NULL) {
- g_array_append_vals(var->buf, vendor_data, vendor_data_len);
- }
-
- return var;
-}
-
-/*
- * ACPI 5.0: 19.5.53
- * GpioInt(GPIO Interrupt Connection Resource Descriptor Macro)
- */
-Aml *aml_gpio_int(AmlConsumerAndProducer con_and_pro,
- AmlLevelAndEdge edge_level,
- AmlActiveHighAndLow active_level, AmlShared shared,
- AmlPinConfig pin_config, uint16_t debounce_timeout,
- const uint32_t pin_list[], uint32_t pin_count,
- const char *resource_source_name,
- const uint8_t *vendor_data, uint16_t vendor_data_len)
-{
- uint8_t flags = edge_level | (active_level << 1) | (shared << 3);
-
- return aml_gpio_connection(AML_INTERRUPT_CONNECTION, con_and_pro, flags,
- pin_config, 0, debounce_timeout, pin_list,
- pin_count, resource_source_name, vendor_data,
- vendor_data_len);
-}
-
-/*
- * ACPI 1.0b: 6.4.3.4 32-Bit Fixed Location Memory Range Descriptor
- * (Type 1, Large Item Name 0x6)
- */
-Aml *aml_memory32_fixed(uint32_t addr, uint32_t size,
- AmlReadAndWrite read_and_write)
-{
- Aml *var = aml_alloc();
- build_append_byte(var->buf, 0x86); /* Memory32Fixed Resource Descriptor */
- build_append_byte(var->buf, 9); /* Length, bits[7:0] value = 9 */
- build_append_byte(var->buf, 0); /* Length, bits[15:8] value = 0 */
- build_append_byte(var->buf, read_and_write); /* Write status, 1 rw 0 ro */
-
- /* Range base address */
- build_append_byte(var->buf, extract32(addr, 0, 8)); /* bits[7:0] */
- build_append_byte(var->buf, extract32(addr, 8, 8)); /* bits[15:8] */
- build_append_byte(var->buf, extract32(addr, 16, 8)); /* bits[23:16] */
- build_append_byte(var->buf, extract32(addr, 24, 8)); /* bits[31:24] */
-
- /* Range length */
- build_append_byte(var->buf, extract32(size, 0, 8)); /* bits[7:0] */
- build_append_byte(var->buf, extract32(size, 8, 8)); /* bits[15:8] */
- build_append_byte(var->buf, extract32(size, 16, 8)); /* bits[23:16] */
- build_append_byte(var->buf, extract32(size, 24, 8)); /* bits[31:24] */
- return var;
-}
-
-/*
- * ACPI 5.0: 6.4.3.6 Extended Interrupt Descriptor
- * Type 1, Large Item Name 0x9
- */
-Aml *aml_interrupt(AmlConsumerAndProducer con_and_pro,
- AmlLevelAndEdge level_and_edge,
- AmlActiveHighAndLow high_and_low, AmlShared shared,
- uint32_t *irq_list, uint8_t irq_count)
-{
- int i;
- Aml *var = aml_alloc();
- uint8_t irq_flags = con_and_pro | (level_and_edge << 1)
- | (high_and_low << 2) | (shared << 3);
- const int header_bytes_in_len = 2;
- uint16_t len = header_bytes_in_len + irq_count * sizeof(uint32_t);
-
- assert(irq_count > 0);
-
- build_append_byte(var->buf, 0x89); /* Extended irq descriptor */
- build_append_byte(var->buf, len & 0xFF); /* Length, bits[7:0] */
- build_append_byte(var->buf, len >> 8); /* Length, bits[15:8] */
- build_append_byte(var->buf, irq_flags); /* Interrupt Vector Information. */
- build_append_byte(var->buf, irq_count); /* Interrupt table length */
-
- /* Interrupt Number List */
- for (i = 0; i < irq_count; i++) {
- build_append_int_noprefix(var->buf, irq_list[i], 4);
- }
- return var;
-}
-
-/* ACPI 1.0b: 6.4.2.5 I/O Port Descriptor */
-Aml *aml_io(AmlIODecode dec, uint16_t min_base, uint16_t max_base,
- uint8_t aln, uint8_t len)
-{
- Aml *var = aml_alloc();
- build_append_byte(var->buf, 0x47); /* IO port descriptor */
- build_append_byte(var->buf, dec);
- build_append_byte(var->buf, min_base & 0xff);
- build_append_byte(var->buf, (min_base >> 8) & 0xff);
- build_append_byte(var->buf, max_base & 0xff);
- build_append_byte(var->buf, (max_base >> 8) & 0xff);
- build_append_byte(var->buf, aln);
- build_append_byte(var->buf, len);
- return var;
-}
-
-/*
- * ACPI 1.0b: 6.4.2.1.1 ASL Macro for IRQ Descriptor
- *
- * More verbose description at:
- * ACPI 5.0: 19.5.64 IRQNoFlags (Interrupt Resource Descriptor Macro)
- * 6.4.2.1 IRQ Descriptor
- */
-Aml *aml_irq_no_flags(uint8_t irq)
-{
- uint16_t irq_mask;
- Aml *var = aml_alloc();
-
- assert(irq < 16);
- build_append_byte(var->buf, 0x22); /* IRQ descriptor 2 byte form */
-
- irq_mask = 1U << irq;
- build_append_byte(var->buf, irq_mask & 0xFF); /* IRQ mask bits[7:0] */
- build_append_byte(var->buf, irq_mask >> 8); /* IRQ mask bits[15:8] */
- return var;
-}
-
-/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefLNot */
-Aml *aml_lnot(Aml *arg)
-{
- Aml *var = aml_opcode(0x92 /* LNotOp */);
- aml_append(var, arg);
- return var;
-}
-
-/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefLEqual */
-Aml *aml_equal(Aml *arg1, Aml *arg2)
-{
- Aml *var = aml_opcode(0x93 /* LequalOp */);
- aml_append(var, arg1);
- aml_append(var, arg2);
- return var;
-}
-
-/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefLGreater */
-Aml *aml_lgreater(Aml *arg1, Aml *arg2)
-{
- Aml *var = aml_opcode(0x94 /* LGreaterOp */);
- aml_append(var, arg1);
- aml_append(var, arg2);
- return var;
-}
-
-/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefLGreaterEqual */
-Aml *aml_lgreater_equal(Aml *arg1, Aml *arg2)
-{
- /* LGreaterEqualOp := LNotOp LLessOp */
- Aml *var = aml_opcode(0x92 /* LNotOp */);
- build_append_byte(var->buf, 0x95 /* LLessOp */);
- aml_append(var, arg1);
- aml_append(var, arg2);
- return var;
-}
-
-/* ACPI 1.0b: 16.2.5.3 Type 1 Opcodes Encoding: DefIfElse */
-Aml *aml_if(Aml *predicate)
-{
- Aml *var = aml_bundle(0xA0 /* IfOp */, AML_PACKAGE);
- aml_append(var, predicate);
- return var;
-}
-
-/* ACPI 1.0b: 16.2.5.3 Type 1 Opcodes Encoding: DefElse */
-Aml *aml_else(void)
-{
- Aml *var = aml_bundle(0xA1 /* ElseOp */, AML_PACKAGE);
- return var;
-}
-
-/* ACPI 1.0b: 16.2.5.3 Type 1 Opcodes Encoding: DefWhile */
-Aml *aml_while(Aml *predicate)
-{
- Aml *var = aml_bundle(0xA2 /* WhileOp */, AML_PACKAGE);
- aml_append(var, predicate);
- return var;
-}
-
-/* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: DefMethod */
-Aml *aml_method(const char *name, int arg_count, AmlSerializeFlag sflag)
-{
- Aml *var = aml_bundle(0x14 /* MethodOp */, AML_PACKAGE);
- int methodflags;
-
- /*
- * MethodFlags:
- * bit 0-2: ArgCount (0-7)
- * bit 3: SerializeFlag
- * 0: NotSerialized
- * 1: Serialized
- * bit 4-7: reserved (must be 0)
- */
- assert(arg_count < 8);
- methodflags = arg_count | (sflag << 3);
-
- build_append_namestring(var->buf, "%s", name);
- build_append_byte(var->buf, methodflags); /* MethodFlags: ArgCount */
- return var;
-}
-
-/* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: DefDevice */
-Aml *aml_device(const char *name_format, ...)
-{
- va_list ap;
- Aml *var = aml_bundle(0x82 /* DeviceOp */, AML_EXT_PACKAGE);
- va_start(ap, name_format);
- build_append_namestringv(var->buf, name_format, ap);
- va_end(ap);
- return var;
-}
-
-/* ACPI 1.0b: 6.4.1 ASL Macros for Resource Descriptors */
-Aml *aml_resource_template(void)
-{
- /* ResourceTemplate is a buffer of Resources with EndTag at the end */
- Aml *var = aml_bundle(0x11 /* BufferOp */, AML_RES_TEMPLATE);
- return var;
-}
-
-/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefBuffer
- * Pass byte_list as NULL to request uninitialized buffer to reserve space.
- */
-Aml *aml_buffer(int buffer_size, uint8_t *byte_list)
-{
- int i;
- Aml *var = aml_bundle(0x11 /* BufferOp */, AML_BUFFER);
-
- for (i = 0; i < buffer_size; i++) {
- if (byte_list == NULL) {
- build_append_byte(var->buf, 0x0);
- } else {
- build_append_byte(var->buf, byte_list[i]);
- }
- }
-
- return var;
-}
-
-/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefPackage */
-Aml *aml_package(uint8_t num_elements)
-{
- Aml *var = aml_bundle(0x12 /* PackageOp */, AML_PACKAGE);
- build_append_byte(var->buf, num_elements);
- return var;
-}
-
-/* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: DefOpRegion */
-Aml *aml_operation_region(const char *name, AmlRegionSpace rs,
- Aml *offset, uint32_t len)
-{
- Aml *var = aml_alloc();
- build_append_byte(var->buf, 0x5B); /* ExtOpPrefix */
- build_append_byte(var->buf, 0x80); /* OpRegionOp */
- build_append_namestring(var->buf, "%s", name);
- build_append_byte(var->buf, rs);
- aml_append(var, offset);
- build_append_int(var->buf, len);
- return var;
-}
-
-/* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: NamedField */
-Aml *aml_named_field(const char *name, unsigned length)
-{
- Aml *var = aml_alloc();
- build_append_nameseg(var->buf, name);
- build_append_pkg_length(var->buf, length, false);
- return var;
-}
-
-/* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: ReservedField */
-Aml *aml_reserved_field(unsigned length)
-{
- Aml *var = aml_alloc();
- /* ReservedField := 0x00 PkgLength */
- build_append_byte(var->buf, 0x00);
- build_append_pkg_length(var->buf, length, false);
- return var;
-}
-
-/* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: DefField */
-Aml *aml_field(const char *name, AmlAccessType type, AmlLockRule lock,
- AmlUpdateRule rule)
-{
- Aml *var = aml_bundle(0x81 /* FieldOp */, AML_EXT_PACKAGE);
- uint8_t flags = rule << 5 | type;
-
- flags |= lock << 4; /* LockRule at 4 bit offset */
-
- build_append_namestring(var->buf, "%s", name);
- build_append_byte(var->buf, flags);
- return var;
-}
-
-static
-Aml *create_field_common(int opcode, Aml *srcbuf, Aml *index, const char *name)
-{
- Aml *var = aml_opcode(opcode);
- aml_append(var, srcbuf);
- aml_append(var, index);
- build_append_namestring(var->buf, "%s", name);
- return var;
-}
-
-/* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: DefCreateField */
-Aml *aml_create_field(Aml *srcbuf, Aml *bit_index, Aml *num_bits,
- const char *name)
-{
- Aml *var = aml_alloc();
- build_append_byte(var->buf, 0x5B); /* ExtOpPrefix */
- build_append_byte(var->buf, 0x13); /* CreateFieldOp */
- aml_append(var, srcbuf);
- aml_append(var, bit_index);
- aml_append(var, num_bits);
- build_append_namestring(var->buf, "%s", name);
- return var;
-}
-
-/* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: DefCreateDWordField */
-Aml *aml_create_dword_field(Aml *srcbuf, Aml *index, const char *name)
-{
- return create_field_common(0x8A /* CreateDWordFieldOp */,
- srcbuf, index, name);
-}
-
-/* ACPI 2.0a: 17.2.4.2 Named Objects Encoding: DefCreateQWordField */
-Aml *aml_create_qword_field(Aml *srcbuf, Aml *index, const char *name)
-{
- return create_field_common(0x8F /* CreateQWordFieldOp */,
- srcbuf, index, name);
-}
-
-/* ACPI 1.0b: 16.2.3 Data Objects Encoding: String */
-Aml *aml_string(const char *name_format, ...)
-{
- Aml *var = aml_opcode(0x0D /* StringPrefix */);
- va_list ap;
- char *s;
- int len;
-
- va_start(ap, name_format);
- len = g_vasprintf(&s, name_format, ap);
- va_end(ap);
-
- g_array_append_vals(var->buf, s, len + 1);
- g_free(s);
-
- return var;
-}
-
-/* ACPI 1.0b: 16.2.6.2 Local Objects Encoding */
-Aml *aml_local(int num)
-{
- Aml *var;
- uint8_t op = 0x60 /* Local0Op */ + num;
-
- assert(num <= 7);
- var = aml_opcode(op);
- return var;
-}
-
-/* ACPI 2.0a: 17.2.2 Data Objects Encoding: DefVarPackage */
-Aml *aml_varpackage(uint32_t num_elements)
-{
- Aml *var = aml_bundle(0x13 /* VarPackageOp */, AML_PACKAGE);
- build_append_int(var->buf, num_elements);
- return var;
-}
-
-/* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: DefProcessor */
-Aml *aml_processor(uint8_t proc_id, uint32_t pblk_addr, uint8_t pblk_len,
- const char *name_format, ...)
-{
- va_list ap;
- Aml *var = aml_bundle(0x83 /* ProcessorOp */, AML_EXT_PACKAGE);
- va_start(ap, name_format);
- build_append_namestringv(var->buf, name_format, ap);
- va_end(ap);
- build_append_byte(var->buf, proc_id); /* ProcID */
- build_append_int_noprefix(var->buf, pblk_addr, sizeof(pblk_addr));
- build_append_byte(var->buf, pblk_len); /* PblkLen */
- return var;
-}
-
-static uint8_t Hex2Digit(char c)
-{
- if (c >= 'A') {
- return c - 'A' + 10;
- }
-
- return c - '0';
-}
-
-/* ACPI 1.0b: 15.2.3.6.4.1 EISAID Macro - Convert EISA ID String To Integer */
-Aml *aml_eisaid(const char *str)
-{
- Aml *var = aml_alloc();
- uint32_t id;
-
- g_assert(strlen(str) == 7);
- id = (str[0] - 0x40) << 26 |
- (str[1] - 0x40) << 21 |
- (str[2] - 0x40) << 16 |
- Hex2Digit(str[3]) << 12 |
- Hex2Digit(str[4]) << 8 |
- Hex2Digit(str[5]) << 4 |
- Hex2Digit(str[6]);
-
- build_append_byte(var->buf, 0x0C); /* DWordPrefix */
- build_append_int_noprefix(var->buf, bswap32(id), sizeof(id));
- return var;
-}
-
-/* ACPI 1.0b: 6.4.3.5.5 Word Address Space Descriptor: bytes 3-5 */
-static Aml *aml_as_desc_header(AmlResourceType type, AmlMinFixed min_fixed,
- AmlMaxFixed max_fixed, AmlDecode dec,
- uint8_t type_flags)
-{
- uint8_t flags = max_fixed | min_fixed | dec;
- Aml *var = aml_alloc();
-
- build_append_byte(var->buf, type);
- build_append_byte(var->buf, flags);
- build_append_byte(var->buf, type_flags); /* Type Specific Flags */
- return var;
-}
-
-/* ACPI 1.0b: 6.4.3.5.5 Word Address Space Descriptor */
-static Aml *aml_word_as_desc(AmlResourceType type, AmlMinFixed min_fixed,
- AmlMaxFixed max_fixed, AmlDecode dec,
- uint16_t addr_gran, uint16_t addr_min,
- uint16_t addr_max, uint16_t addr_trans,
- uint16_t len, uint8_t type_flags)
-{
- Aml *var = aml_alloc();
-
- build_append_byte(var->buf, 0x88); /* Word Address Space Descriptor */
- /* minimum length since we do not encode optional fields */
- build_append_byte(var->buf, 0x0D);
- build_append_byte(var->buf, 0x0);
-
- aml_append(var,
- aml_as_desc_header(type, min_fixed, max_fixed, dec, type_flags));
- build_append_int_noprefix(var->buf, addr_gran, sizeof(addr_gran));
- build_append_int_noprefix(var->buf, addr_min, sizeof(addr_min));
- build_append_int_noprefix(var->buf, addr_max, sizeof(addr_max));
- build_append_int_noprefix(var->buf, addr_trans, sizeof(addr_trans));
- build_append_int_noprefix(var->buf, len, sizeof(len));
- return var;
-}
-
-/* ACPI 1.0b: 6.4.3.5.3 DWord Address Space Descriptor */
-static Aml *aml_dword_as_desc(AmlResourceType type, AmlMinFixed min_fixed,
- AmlMaxFixed max_fixed, AmlDecode dec,
- uint32_t addr_gran, uint32_t addr_min,
- uint32_t addr_max, uint32_t addr_trans,
- uint32_t len, uint8_t type_flags)
-{
- Aml *var = aml_alloc();
-
- build_append_byte(var->buf, 0x87); /* DWord Address Space Descriptor */
- /* minimum length since we do not encode optional fields */
- build_append_byte(var->buf, 23);
- build_append_byte(var->buf, 0x0);
-
-
- aml_append(var,
- aml_as_desc_header(type, min_fixed, max_fixed, dec, type_flags));
- build_append_int_noprefix(var->buf, addr_gran, sizeof(addr_gran));
- build_append_int_noprefix(var->buf, addr_min, sizeof(addr_min));
- build_append_int_noprefix(var->buf, addr_max, sizeof(addr_max));
- build_append_int_noprefix(var->buf, addr_trans, sizeof(addr_trans));
- build_append_int_noprefix(var->buf, len, sizeof(len));
- return var;
-}
-
-/* ACPI 1.0b: 6.4.3.5.1 QWord Address Space Descriptor */
-static Aml *aml_qword_as_desc(AmlResourceType type, AmlMinFixed min_fixed,
- AmlMaxFixed max_fixed, AmlDecode dec,
- uint64_t addr_gran, uint64_t addr_min,
- uint64_t addr_max, uint64_t addr_trans,
- uint64_t len, uint8_t type_flags)
-{
- Aml *var = aml_alloc();
-
- build_append_byte(var->buf, 0x8A); /* QWord Address Space Descriptor */
- /* minimum length since we do not encode optional fields */
- build_append_byte(var->buf, 0x2B);
- build_append_byte(var->buf, 0x0);
-
- aml_append(var,
- aml_as_desc_header(type, min_fixed, max_fixed, dec, type_flags));
- build_append_int_noprefix(var->buf, addr_gran, sizeof(addr_gran));
- build_append_int_noprefix(var->buf, addr_min, sizeof(addr_min));
- build_append_int_noprefix(var->buf, addr_max, sizeof(addr_max));
- build_append_int_noprefix(var->buf, addr_trans, sizeof(addr_trans));
- build_append_int_noprefix(var->buf, len, sizeof(len));
- return var;
-}
-
-/*
- * ACPI 1.0b: 6.4.3.5.6 ASL Macros for WORD Address Descriptor
- *
- * More verbose description at:
- * ACPI 5.0: 19.5.141 WordBusNumber (Word Bus Number Resource Descriptor Macro)
- */
-Aml *aml_word_bus_number(AmlMinFixed min_fixed, AmlMaxFixed max_fixed,
- AmlDecode dec, uint16_t addr_gran,
- uint16_t addr_min, uint16_t addr_max,
- uint16_t addr_trans, uint16_t len)
-
-{
- return aml_word_as_desc(AML_BUS_NUMBER_RANGE, min_fixed, max_fixed, dec,
- addr_gran, addr_min, addr_max, addr_trans, len, 0);
-}
-
-/*
- * ACPI 1.0b: 6.4.3.5.6 ASL Macros for WORD Address Descriptor
- *
- * More verbose description at:
- * ACPI 5.0: 19.5.142 WordIO (Word IO Resource Descriptor Macro)
- */
-Aml *aml_word_io(AmlMinFixed min_fixed, AmlMaxFixed max_fixed,
- AmlDecode dec, AmlISARanges isa_ranges,
- uint16_t addr_gran, uint16_t addr_min,
- uint16_t addr_max, uint16_t addr_trans,
- uint16_t len)
-
-{
- return aml_word_as_desc(AML_IO_RANGE, min_fixed, max_fixed, dec,
- addr_gran, addr_min, addr_max, addr_trans, len,
- isa_ranges);
-}
-
-/*
- * ACPI 1.0b: 6.4.3.5.4 ASL Macros for DWORD Address Descriptor
- *
- * More verbose description at:
- * ACPI 5.0: 19.5.33 DWordIO (DWord IO Resource Descriptor Macro)
- */
-Aml *aml_dword_io(AmlMinFixed min_fixed, AmlMaxFixed max_fixed,
- AmlDecode dec, AmlISARanges isa_ranges,
- uint32_t addr_gran, uint32_t addr_min,
- uint32_t addr_max, uint32_t addr_trans,
- uint32_t len)
-
-{
- return aml_dword_as_desc(AML_IO_RANGE, min_fixed, max_fixed, dec,
- addr_gran, addr_min, addr_max, addr_trans, len,
- isa_ranges);
-}
-
-/*
- * ACPI 1.0b: 6.4.3.5.4 ASL Macros for DWORD Address Space Descriptor
- *
- * More verbose description at:
- * ACPI 5.0: 19.5.34 DWordMemory (DWord Memory Resource Descriptor Macro)
- */
-Aml *aml_dword_memory(AmlDecode dec, AmlMinFixed min_fixed,
- AmlMaxFixed max_fixed, AmlCacheable cacheable,
- AmlReadAndWrite read_and_write,
- uint32_t addr_gran, uint32_t addr_min,
- uint32_t addr_max, uint32_t addr_trans,
- uint32_t len)
-{
- uint8_t flags = read_and_write | (cacheable << 1);
-
- return aml_dword_as_desc(AML_MEMORY_RANGE, min_fixed, max_fixed,
- dec, addr_gran, addr_min, addr_max,
- addr_trans, len, flags);
-}
-
-/*
- * ACPI 1.0b: 6.4.3.5.2 ASL Macros for QWORD Address Space Descriptor
- *
- * More verbose description at:
- * ACPI 5.0: 19.5.102 QWordMemory (QWord Memory Resource Descriptor Macro)
- */
-Aml *aml_qword_memory(AmlDecode dec, AmlMinFixed min_fixed,
- AmlMaxFixed max_fixed, AmlCacheable cacheable,
- AmlReadAndWrite read_and_write,
- uint64_t addr_gran, uint64_t addr_min,
- uint64_t addr_max, uint64_t addr_trans,
- uint64_t len)
-{
- uint8_t flags = read_and_write | (cacheable << 1);
-
- return aml_qword_as_desc(AML_MEMORY_RANGE, min_fixed, max_fixed,
- dec, addr_gran, addr_min, addr_max,
- addr_trans, len, flags);
-}
-
-/* ACPI 1.0b: 6.4.2.2 DMA Format/6.4.2.2.1 ASL Macro for DMA Descriptor */
-Aml *aml_dma(AmlDmaType typ, AmlDmaBusMaster bm, AmlTransferSize sz,
- uint8_t channel)
-{
- Aml *var = aml_alloc();
- uint8_t flags = sz | bm << 2 | typ << 5;
-
- assert(channel < 8);
- build_append_byte(var->buf, 0x2A); /* Byte 0: DMA Descriptor */
- build_append_byte(var->buf, 1U << channel); /* Byte 1: _DMA - DmaChannel */
- build_append_byte(var->buf, flags); /* Byte 2 */
- return var;
-}
-
-/* ACPI 1.0b: 16.2.5.3 Type 1 Opcodes Encoding: DefSleep */
-Aml *aml_sleep(uint64_t msec)
-{
- Aml *var = aml_alloc();
- build_append_byte(var->buf, 0x5B); /* ExtOpPrefix */
- build_append_byte(var->buf, 0x22); /* SleepOp */
- aml_append(var, aml_int(msec));
- return var;
-}
-
-static uint8_t Hex2Byte(const char *src)
-{
- int hi, lo;
-
- hi = Hex2Digit(src[0]);
- assert(hi >= 0);
- assert(hi <= 15);
-
- lo = Hex2Digit(src[1]);
- assert(lo >= 0);
- assert(lo <= 15);
- return (hi << 4) | lo;
-}
-
-/*
- * ACPI 3.0: 17.5.124 ToUUID (Convert String to UUID Macro)
- * e.g. UUID: aabbccdd-eeff-gghh-iijj-kkllmmnnoopp
- * call aml_touuid("aabbccdd-eeff-gghh-iijj-kkllmmnnoopp");
- */
-Aml *aml_touuid(const char *uuid)
-{
- Aml *var = aml_bundle(0x11 /* BufferOp */, AML_BUFFER);
-
- assert(strlen(uuid) == 36);
- assert(uuid[8] == '-');
- assert(uuid[13] == '-');
- assert(uuid[18] == '-');
- assert(uuid[23] == '-');
-
- build_append_byte(var->buf, Hex2Byte(uuid + 6)); /* dd - at offset 00 */
- build_append_byte(var->buf, Hex2Byte(uuid + 4)); /* cc - at offset 01 */
- build_append_byte(var->buf, Hex2Byte(uuid + 2)); /* bb - at offset 02 */
- build_append_byte(var->buf, Hex2Byte(uuid + 0)); /* aa - at offset 03 */
-
- build_append_byte(var->buf, Hex2Byte(uuid + 11)); /* ff - at offset 04 */
- build_append_byte(var->buf, Hex2Byte(uuid + 9)); /* ee - at offset 05 */
-
- build_append_byte(var->buf, Hex2Byte(uuid + 16)); /* hh - at offset 06 */
- build_append_byte(var->buf, Hex2Byte(uuid + 14)); /* gg - at offset 07 */
-
- build_append_byte(var->buf, Hex2Byte(uuid + 19)); /* ii - at offset 08 */
- build_append_byte(var->buf, Hex2Byte(uuid + 21)); /* jj - at offset 09 */
-
- build_append_byte(var->buf, Hex2Byte(uuid + 24)); /* kk - at offset 10 */
- build_append_byte(var->buf, Hex2Byte(uuid + 26)); /* ll - at offset 11 */
- build_append_byte(var->buf, Hex2Byte(uuid + 28)); /* mm - at offset 12 */
- build_append_byte(var->buf, Hex2Byte(uuid + 30)); /* nn - at offset 13 */
- build_append_byte(var->buf, Hex2Byte(uuid + 32)); /* oo - at offset 14 */
- build_append_byte(var->buf, Hex2Byte(uuid + 34)); /* pp - at offset 15 */
-
- return var;
-}
-
-/*
- * ACPI 2.0b: 16.2.3.6.4.3 Unicode Macro (Convert Ascii String To Unicode)
- */
-Aml *aml_unicode(const char *str)
-{
- int i = 0;
- Aml *var = aml_bundle(0x11 /* BufferOp */, AML_BUFFER);
-
- do {
- build_append_byte(var->buf, str[i]);
- build_append_byte(var->buf, 0);
- i++;
- } while (i <= strlen(str));
-
- return var;
-}
-
-/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefDerefOf */
-Aml *aml_derefof(Aml *arg)
-{
- Aml *var = aml_opcode(0x83 /* DerefOfOp */);
- aml_append(var, arg);
- return var;
-}
-
-/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefSizeOf */
-Aml *aml_sizeof(Aml *arg)
-{
- Aml *var = aml_opcode(0x87 /* SizeOfOp */);
- aml_append(var, arg);
- return var;
-}
-
-/* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: DefMutex */
-Aml *aml_mutex(const char *name, uint8_t sync_level)
-{
- Aml *var = aml_alloc();
- build_append_byte(var->buf, 0x5B); /* ExtOpPrefix */
- build_append_byte(var->buf, 0x01); /* MutexOp */
- build_append_namestring(var->buf, "%s", name);
- assert(!(sync_level & 0xF0));
- build_append_byte(var->buf, sync_level);
- return var;
-}
-
-/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefAcquire */
-Aml *aml_acquire(Aml *mutex, uint16_t timeout)
-{
- Aml *var = aml_alloc();
- build_append_byte(var->buf, 0x5B); /* ExtOpPrefix */
- build_append_byte(var->buf, 0x23); /* AcquireOp */
- aml_append(var, mutex);
- build_append_int_noprefix(var->buf, timeout, sizeof(timeout));
- return var;
-}
-
-/* ACPI 1.0b: 16.2.5.3 Type 1 Opcodes Encoding: DefRelease */
-Aml *aml_release(Aml *mutex)
-{
- Aml *var = aml_alloc();
- build_append_byte(var->buf, 0x5B); /* ExtOpPrefix */
- build_append_byte(var->buf, 0x27); /* ReleaseOp */
- aml_append(var, mutex);
- return var;
-}
-
-/* ACPI 1.0b: 16.2.5.1 Name Space Modifier Objects Encoding: DefAlias */
-Aml *aml_alias(const char *source_object, const char *alias_object)
-{
- Aml *var = aml_opcode(0x06 /* AliasOp */);
- aml_append(var, aml_name("%s", source_object));
- aml_append(var, aml_name("%s", alias_object));
- return var;
-}
-
-/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefConcat */
-Aml *aml_concatenate(Aml *source1, Aml *source2, Aml *target)
-{
- return build_opcode_2arg_dst(0x73 /* ConcatOp */, source1, source2,
- target);
-}
-
-void
-build_header(GArray *linker, GArray *table_data,
- AcpiTableHeader *h, const char *sig, int len, uint8_t rev,
- const char *oem_id, const char *oem_table_id)
-{
- memcpy(&h->signature, sig, 4);
- h->length = cpu_to_le32(len);
- h->revision = rev;
-
- if (oem_id) {
- strncpy((char *)h->oem_id, oem_id, sizeof h->oem_id);
- } else {
- memcpy(h->oem_id, ACPI_BUILD_APPNAME6, 6);
- }
-
- if (oem_table_id) {
- strncpy((char *)h->oem_table_id, oem_table_id, sizeof(h->oem_table_id));
- } else {
- memcpy(h->oem_table_id, ACPI_BUILD_APPNAME4, 4);
- memcpy(h->oem_table_id + 4, sig, 4);
- }
-
- h->oem_revision = cpu_to_le32(1);
- memcpy(h->asl_compiler_id, ACPI_BUILD_APPNAME4, 4);
- h->asl_compiler_revision = cpu_to_le32(1);
- h->checksum = 0;
- /* Checksum to be filled in by Guest linker */
- bios_linker_loader_add_checksum(linker, ACPI_BUILD_TABLE_FILE,
- table_data, h, len, &h->checksum);
-}
-
-void *acpi_data_push(GArray *table_data, unsigned size)
-{
- unsigned off = table_data->len;
- g_array_set_size(table_data, off + size);
- return table_data->data + off;
-}
-
-unsigned acpi_data_len(GArray *table)
-{
- assert(g_array_get_element_size(table) == 1);
- return table->len;
-}
-
-void acpi_add_table(GArray *table_offsets, GArray *table_data)
-{
- uint32_t offset = cpu_to_le32(table_data->len);
- g_array_append_val(table_offsets, offset);
-}
-
-void acpi_build_tables_init(AcpiBuildTables *tables)
-{
- tables->rsdp = g_array_new(false, true /* clear */, 1);
- tables->table_data = g_array_new(false, true /* clear */, 1);
- tables->tcpalog = g_array_new(false, true /* clear */, 1);
- tables->linker = bios_linker_loader_init();
-}
-
-void acpi_build_tables_cleanup(AcpiBuildTables *tables, bool mfre)
-{
- void *linker_data = bios_linker_loader_cleanup(tables->linker);
- g_free(linker_data);
- g_array_free(tables->rsdp, true);
- g_array_free(tables->table_data, true);
- g_array_free(tables->tcpalog, mfre);
-}
-
-/* Build rsdt table */
-void
-build_rsdt(GArray *table_data, GArray *linker, GArray *table_offsets,
- const char *oem_id, const char *oem_table_id)
-{
- AcpiRsdtDescriptorRev1 *rsdt;
- size_t rsdt_len;
- int i;
- const int table_data_len = (sizeof(uint32_t) * table_offsets->len);
-
- rsdt_len = sizeof(*rsdt) + table_data_len;
- rsdt = acpi_data_push(table_data, rsdt_len);
- memcpy(rsdt->table_offset_entry, table_offsets->data, table_data_len);
- for (i = 0; i < table_offsets->len; ++i) {
- /* rsdt->table_offset_entry to be filled by Guest linker */
- bios_linker_loader_add_pointer(linker,
- ACPI_BUILD_TABLE_FILE,
- ACPI_BUILD_TABLE_FILE,
- table_data, &rsdt->table_offset_entry[i],
- sizeof(uint32_t));
- }
- build_header(linker, table_data,
- (void *)rsdt, "RSDT", rsdt_len, 1, oem_id, oem_table_id);
-}
diff --git a/qemu/hw/acpi/bios-linker-loader.c b/qemu/hw/acpi/bios-linker-loader.c
deleted file mode 100644
index 5153ab151..000000000
--- a/qemu/hw/acpi/bios-linker-loader.c
+++ /dev/null
@@ -1,240 +0,0 @@
-/* Dynamic linker/loader of ACPI tables
- *
- * Copyright (C) 2013 Red Hat Inc
- *
- * Author: Michael S. Tsirkin <mst@redhat.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "qemu/osdep.h"
-#include "qemu-common.h"
-#include "hw/acpi/bios-linker-loader.h"
-#include "hw/nvram/fw_cfg.h"
-
-#include "qemu/bswap.h"
-
-/*
- * Linker/loader is a paravirtualized interface that passes commands to guest.
- * The commands can be used to request guest to
- * - allocate memory chunks and initialize them from QEMU FW CFG files
- * - link allocated chunks by storing pointer to one chunk into another
- * - calculate ACPI checksum of part of the chunk and store into same chunk
- */
-#define BIOS_LINKER_LOADER_FILESZ FW_CFG_MAX_FILE_PATH
-
-struct BiosLinkerLoaderEntry {
- uint32_t command;
- union {
- /*
- * COMMAND_ALLOCATE - allocate a table from @alloc.file
- * subject to @alloc.align alignment (must be power of 2)
- * and @alloc.zone (can be HIGH or FSEG) requirements.
- *
- * Must appear exactly once for each file, and before
- * this file is referenced by any other command.
- */
- struct {
- char file[BIOS_LINKER_LOADER_FILESZ];
- uint32_t align;
- uint8_t zone;
- } alloc;
-
- /*
- * COMMAND_ADD_POINTER - patch the table (originating from
- * @dest_file) at @pointer.offset, by adding a pointer to the table
- * originating from @src_file. 1,2,4 or 8 byte unsigned
- * addition is used depending on @pointer.size.
- */
- struct {
- char dest_file[BIOS_LINKER_LOADER_FILESZ];
- char src_file[BIOS_LINKER_LOADER_FILESZ];
- uint32_t offset;
- uint8_t size;
- } pointer;
-
- /*
- * COMMAND_ADD_CHECKSUM - calculate checksum of the range specified by
- * @cksum_start and @cksum_length fields,
- * and then add the value at @cksum.offset.
- * Checksum simply sums -X for each byte X in the range
- * using 8-bit math.
- */
- struct {
- char file[BIOS_LINKER_LOADER_FILESZ];
- uint32_t offset;
- uint32_t start;
- uint32_t length;
- } cksum;
-
- /* padding */
- char pad[124];
- };
-} QEMU_PACKED;
-typedef struct BiosLinkerLoaderEntry BiosLinkerLoaderEntry;
-
-enum {
- BIOS_LINKER_LOADER_COMMAND_ALLOCATE = 0x1,
- BIOS_LINKER_LOADER_COMMAND_ADD_POINTER = 0x2,
- BIOS_LINKER_LOADER_COMMAND_ADD_CHECKSUM = 0x3,
-};
-
-enum {
- BIOS_LINKER_LOADER_ALLOC_ZONE_HIGH = 0x1,
- BIOS_LINKER_LOADER_ALLOC_ZONE_FSEG = 0x2,
-};
-
-/*
- * bios_linker_loader_init: allocate a new linker file blob array.
- *
- * After initialization, linker commands can be added, and will
- * be stored in the array.
- */
-GArray *bios_linker_loader_init(void)
-{
- return g_array_new(false, true /* clear */, 1);
-}
-
-/* Free linker wrapper and return the linker array. */
-void *bios_linker_loader_cleanup(GArray *linker)
-{
- return g_array_free(linker, false);
-}
-
-/*
- * bios_linker_loader_alloc: ask guest to load file into guest memory.
- *
- * @linker: linker file blob array
- * @file: file to be loaded
- * @alloc_align: required minimal alignment in bytes. Must be a power of 2.
- * @alloc_fseg: request allocation in FSEG zone (useful for the RSDP ACPI table)
- *
- * Note: this command must precede any other linker command using this file.
- */
-void bios_linker_loader_alloc(GArray *linker,
- const char *file,
- uint32_t alloc_align,
- bool alloc_fseg)
-{
- BiosLinkerLoaderEntry entry;
-
- assert(!(alloc_align & (alloc_align - 1)));
-
- memset(&entry, 0, sizeof entry);
- strncpy(entry.alloc.file, file, sizeof entry.alloc.file - 1);
- entry.command = cpu_to_le32(BIOS_LINKER_LOADER_COMMAND_ALLOCATE);
- entry.alloc.align = cpu_to_le32(alloc_align);
- entry.alloc.zone = alloc_fseg ? BIOS_LINKER_LOADER_ALLOC_ZONE_FSEG :
- BIOS_LINKER_LOADER_ALLOC_ZONE_HIGH;
-
- /* Alloc entries must come first, so prepend them */
- g_array_prepend_vals(linker, &entry, sizeof entry);
-}
-
-/*
- * bios_linker_loader_add_checksum: ask guest to add checksum of file data
- * into (same) file at the specified pointer.
- *
- * Checksum calculation simply sums -X for each byte X in the range
- * using 8-bit math (i.e. ACPI checksum).
- *
- * @linker: linker file blob array
- * @file: file that includes the checksum to be calculated
- * and the data to be checksummed
- * @table: @file blob contents
- * @start, @size: range of data to checksum
- * @checksum: location of the checksum to be patched within file blob
- *
- * Notes:
- * - checksum byte initial value must have been pushed into @table
- * and reside at address @checksum.
- * - @size bytes must have been pushed into @table and reside at address
- * @start.
- * - Guest calculates checksum of specified range of data, result is added to
- * initial value at @checksum into copy of @file in Guest memory.
- * - Range might include the checksum itself.
- * - To avoid confusion, caller must always put 0x0 at @checksum.
- * - @file must be loaded into Guest memory using bios_linker_loader_alloc
- */
-void bios_linker_loader_add_checksum(GArray *linker, const char *file,
- GArray *table,
- void *start, unsigned size,
- uint8_t *checksum)
-{
- BiosLinkerLoaderEntry entry;
- ptrdiff_t checksum_offset = (gchar *)checksum - table->data;
- ptrdiff_t start_offset = (gchar *)start - table->data;
-
- assert(checksum_offset >= 0);
- assert(start_offset >= 0);
- assert(checksum_offset + 1 <= table->len);
- assert(start_offset + size <= table->len);
- assert(*checksum == 0x0);
-
- memset(&entry, 0, sizeof entry);
- strncpy(entry.cksum.file, file, sizeof entry.cksum.file - 1);
- entry.command = cpu_to_le32(BIOS_LINKER_LOADER_COMMAND_ADD_CHECKSUM);
- entry.cksum.offset = cpu_to_le32(checksum_offset);
- entry.cksum.start = cpu_to_le32(start_offset);
- entry.cksum.length = cpu_to_le32(size);
-
- g_array_append_vals(linker, &entry, sizeof entry);
-}
-
-/*
- * bios_linker_loader_add_pointer: ask guest to add address of source file
- * into destination file at the specified pointer.
- *
- * @linker: linker file blob array
- * @dest_file: destination file that must be changed
- * @src_file: source file who's address must be taken
- * @table: @dest_file blob contents array
- * @pointer: location of the pointer to be patched within destination file blob
- * @pointer_size: size of pointer to be patched, in bytes
- *
- * Notes:
- * - @pointer_size bytes must have been pushed into @table
- * and reside at address @pointer.
- * - Guest address is added to initial value at @pointer
- * into copy of @dest_file in Guest memory.
- * e.g. to get start of src_file in guest memory, put 0x0 there
- * to get address of a field at offset 0x10 in src_file, put 0x10 there
- * - Both @dest_file and @src_file must be
- * loaded into Guest memory using bios_linker_loader_alloc
- */
-void bios_linker_loader_add_pointer(GArray *linker,
- const char *dest_file,
- const char *src_file,
- GArray *table, void *pointer,
- uint8_t pointer_size)
-{
- BiosLinkerLoaderEntry entry;
- ptrdiff_t offset = (gchar *)pointer - table->data;
-
- assert(offset >= 0);
- assert(offset + pointer_size <= table->len);
-
- memset(&entry, 0, sizeof entry);
- strncpy(entry.pointer.dest_file, dest_file,
- sizeof entry.pointer.dest_file - 1);
- strncpy(entry.pointer.src_file, src_file,
- sizeof entry.pointer.src_file - 1);
- entry.command = cpu_to_le32(BIOS_LINKER_LOADER_COMMAND_ADD_POINTER);
- entry.pointer.offset = cpu_to_le32(offset);
- entry.pointer.size = pointer_size;
- assert(pointer_size == 1 || pointer_size == 2 ||
- pointer_size == 4 || pointer_size == 8);
-
- g_array_append_vals(linker, &entry, sizeof entry);
-}
diff --git a/qemu/hw/acpi/core.c b/qemu/hw/acpi/core.c
deleted file mode 100644
index 6a2f45214..000000000
--- a/qemu/hw/acpi/core.c
+++ /dev/null
@@ -1,717 +0,0 @@
-/*
- * ACPI implementation
- *
- * Copyright (c) 2006 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License version 2 as published by the Free Software Foundation.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see <http://www.gnu.org/licenses/>
- *
- * Contributions after 2012-01-13 are licensed under the terms of the
- * GNU GPL, version 2 or (at your option) any later version.
- */
-#include "qemu/osdep.h"
-#include "sysemu/sysemu.h"
-#include "hw/hw.h"
-#include "hw/i386/pc.h"
-#include "hw/acpi/acpi.h"
-#include "hw/nvram/fw_cfg.h"
-#include "qemu/config-file.h"
-#include "qapi/opts-visitor.h"
-#include "qapi-visit.h"
-#include "qapi-event.h"
-
-struct acpi_table_header {
- uint16_t _length; /* our length, not actual part of the hdr */
- /* allows easier parsing for fw_cfg clients */
- char sig[4]; /* ACPI signature (4 ASCII characters) */
- uint32_t length; /* Length of table, in bytes, including header */
- uint8_t revision; /* ACPI Specification minor version # */
- uint8_t checksum; /* To make sum of entire table == 0 */
- char oem_id[6]; /* OEM identification */
- char oem_table_id[8]; /* OEM table identification */
- uint32_t oem_revision; /* OEM revision number */
- char asl_compiler_id[4]; /* ASL compiler vendor ID */
- uint32_t asl_compiler_revision; /* ASL compiler revision number */
-} QEMU_PACKED;
-
-#define ACPI_TABLE_HDR_SIZE sizeof(struct acpi_table_header)
-#define ACPI_TABLE_PFX_SIZE sizeof(uint16_t) /* size of the extra prefix */
-
-static const char unsigned dfl_hdr[ACPI_TABLE_HDR_SIZE - ACPI_TABLE_PFX_SIZE] =
- "QEMU\0\0\0\0\1\0" /* sig (4), len(4), revno (1), csum (1) */
- "QEMUQEQEMUQEMU\1\0\0\0" /* OEM id (6), table (8), revno (4) */
- "QEMU\1\0\0\0" /* ASL compiler ID (4), version (4) */
- ;
-
-char unsigned *acpi_tables;
-size_t acpi_tables_len;
-
-static QemuOptsList qemu_acpi_opts = {
- .name = "acpi",
- .implied_opt_name = "data",
- .head = QTAILQ_HEAD_INITIALIZER(qemu_acpi_opts.head),
- .desc = { { 0 } } /* validated with OptsVisitor */
-};
-
-static void acpi_register_config(void)
-{
- qemu_add_opts(&qemu_acpi_opts);
-}
-
-opts_init(acpi_register_config);
-
-static int acpi_checksum(const uint8_t *data, int len)
-{
- int sum, i;
- sum = 0;
- for (i = 0; i < len; i++) {
- sum += data[i];
- }
- return (-sum) & 0xff;
-}
-
-
-/* Install a copy of the ACPI table specified in @blob.
- *
- * If @has_header is set, @blob starts with the System Description Table Header
- * structure. Otherwise, "dfl_hdr" is prepended. In any case, each header field
- * is optionally overwritten from @hdrs.
- *
- * It is valid to call this function with
- * (@blob == NULL && bloblen == 0 && !has_header).
- *
- * @hdrs->file and @hdrs->data are ignored.
- *
- * SIZE_MAX is considered "infinity" in this function.
- *
- * The number of tables that can be installed is not limited, but the 16-bit
- * counter at the beginning of "acpi_tables" wraps around after UINT16_MAX.
- */
-static void acpi_table_install(const char unsigned *blob, size_t bloblen,
- bool has_header,
- const struct AcpiTableOptions *hdrs,
- Error **errp)
-{
- size_t body_start;
- const char unsigned *hdr_src;
- size_t body_size, acpi_payload_size;
- struct acpi_table_header *ext_hdr;
- unsigned changed_fields;
-
- /* Calculate where the ACPI table body starts within the blob, plus where
- * to copy the ACPI table header from.
- */
- if (has_header) {
- /* _length | ACPI header in blob | blob body
- * ^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^
- * ACPI_TABLE_PFX_SIZE sizeof dfl_hdr body_size
- * == body_start
- *
- * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- * acpi_payload_size == bloblen
- */
- body_start = sizeof dfl_hdr;
-
- if (bloblen < body_start) {
- error_setg(errp, "ACPI table claiming to have header is too "
- "short, available: %zu, expected: %zu", bloblen,
- body_start);
- return;
- }
- hdr_src = blob;
- } else {
- /* _length | ACPI header in template | blob body
- * ^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^
- * ACPI_TABLE_PFX_SIZE sizeof dfl_hdr body_size
- * == bloblen
- *
- * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- * acpi_payload_size
- */
- body_start = 0;
- hdr_src = dfl_hdr;
- }
- body_size = bloblen - body_start;
- acpi_payload_size = sizeof dfl_hdr + body_size;
-
- if (acpi_payload_size > UINT16_MAX) {
- error_setg(errp, "ACPI table too big, requested: %zu, max: %u",
- acpi_payload_size, (unsigned)UINT16_MAX);
- return;
- }
-
- /* We won't fail from here on. Initialize / extend the globals. */
- if (acpi_tables == NULL) {
- acpi_tables_len = sizeof(uint16_t);
- acpi_tables = g_malloc0(acpi_tables_len);
- }
-
- acpi_tables = g_realloc(acpi_tables, acpi_tables_len +
- ACPI_TABLE_PFX_SIZE +
- sizeof dfl_hdr + body_size);
-
- ext_hdr = (struct acpi_table_header *)(acpi_tables + acpi_tables_len);
- acpi_tables_len += ACPI_TABLE_PFX_SIZE;
-
- memcpy(acpi_tables + acpi_tables_len, hdr_src, sizeof dfl_hdr);
- acpi_tables_len += sizeof dfl_hdr;
-
- if (blob != NULL) {
- memcpy(acpi_tables + acpi_tables_len, blob + body_start, body_size);
- acpi_tables_len += body_size;
- }
-
- /* increase number of tables */
- stw_le_p(acpi_tables, lduw_le_p(acpi_tables) + 1u);
-
- /* Update the header fields. The strings need not be NUL-terminated. */
- changed_fields = 0;
- ext_hdr->_length = cpu_to_le16(acpi_payload_size);
-
- if (hdrs->has_sig) {
- strncpy(ext_hdr->sig, hdrs->sig, sizeof ext_hdr->sig);
- ++changed_fields;
- }
-
- if (has_header && le32_to_cpu(ext_hdr->length) != acpi_payload_size) {
- fprintf(stderr,
- "warning: ACPI table has wrong length, header says "
- "%" PRIu32 ", actual size %zu bytes\n",
- le32_to_cpu(ext_hdr->length), acpi_payload_size);
- }
- ext_hdr->length = cpu_to_le32(acpi_payload_size);
-
- if (hdrs->has_rev) {
- ext_hdr->revision = hdrs->rev;
- ++changed_fields;
- }
-
- ext_hdr->checksum = 0;
-
- if (hdrs->has_oem_id) {
- strncpy(ext_hdr->oem_id, hdrs->oem_id, sizeof ext_hdr->oem_id);
- ++changed_fields;
- }
- if (hdrs->has_oem_table_id) {
- strncpy(ext_hdr->oem_table_id, hdrs->oem_table_id,
- sizeof ext_hdr->oem_table_id);
- ++changed_fields;
- }
- if (hdrs->has_oem_rev) {
- ext_hdr->oem_revision = cpu_to_le32(hdrs->oem_rev);
- ++changed_fields;
- }
- if (hdrs->has_asl_compiler_id) {
- strncpy(ext_hdr->asl_compiler_id, hdrs->asl_compiler_id,
- sizeof ext_hdr->asl_compiler_id);
- ++changed_fields;
- }
- if (hdrs->has_asl_compiler_rev) {
- ext_hdr->asl_compiler_revision = cpu_to_le32(hdrs->asl_compiler_rev);
- ++changed_fields;
- }
-
- if (!has_header && changed_fields == 0) {
- fprintf(stderr, "warning: ACPI table: no headers are specified\n");
- }
-
- /* recalculate checksum */
- ext_hdr->checksum = acpi_checksum((const char unsigned *)ext_hdr +
- ACPI_TABLE_PFX_SIZE, acpi_payload_size);
-}
-
-void acpi_table_add(const QemuOpts *opts, Error **errp)
-{
- AcpiTableOptions *hdrs = NULL;
- Error *err = NULL;
- char **pathnames = NULL;
- char **cur;
- size_t bloblen = 0;
- char unsigned *blob = NULL;
-
- {
- OptsVisitor *ov;
-
- ov = opts_visitor_new(opts);
- visit_type_AcpiTableOptions(opts_get_visitor(ov), NULL, &hdrs, &err);
- opts_visitor_cleanup(ov);
- }
-
- if (err) {
- goto out;
- }
- if (hdrs->has_file == hdrs->has_data) {
- error_setg(&err, "'-acpitable' requires one of 'data' or 'file'");
- goto out;
- }
-
- pathnames = g_strsplit(hdrs->has_file ? hdrs->file : hdrs->data, ":", 0);
- if (pathnames == NULL || pathnames[0] == NULL) {
- error_setg(&err, "'-acpitable' requires at least one pathname");
- goto out;
- }
-
- /* now read in the data files, reallocating buffer as needed */
- for (cur = pathnames; *cur; ++cur) {
- int fd = open(*cur, O_RDONLY | O_BINARY);
-
- if (fd < 0) {
- error_setg(&err, "can't open file %s: %s", *cur, strerror(errno));
- goto out;
- }
-
- for (;;) {
- char unsigned data[8192];
- ssize_t r;
-
- r = read(fd, data, sizeof data);
- if (r == 0) {
- break;
- } else if (r > 0) {
- blob = g_realloc(blob, bloblen + r);
- memcpy(blob + bloblen, data, r);
- bloblen += r;
- } else if (errno != EINTR) {
- error_setg(&err, "can't read file %s: %s",
- *cur, strerror(errno));
- close(fd);
- goto out;
- }
- }
-
- close(fd);
- }
-
- acpi_table_install(blob, bloblen, hdrs->has_file, hdrs, &err);
-
-out:
- g_free(blob);
- g_strfreev(pathnames);
- qapi_free_AcpiTableOptions(hdrs);
-
- error_propagate(errp, err);
-}
-
-static bool acpi_table_builtin = false;
-
-void acpi_table_add_builtin(const QemuOpts *opts, Error **errp)
-{
- acpi_table_builtin = true;
- acpi_table_add(opts, errp);
-}
-
-unsigned acpi_table_len(void *current)
-{
- struct acpi_table_header *hdr = current - sizeof(hdr->_length);
- return hdr->_length;
-}
-
-static
-void *acpi_table_hdr(void *h)
-{
- struct acpi_table_header *hdr = h;
- return &hdr->sig;
-}
-
-uint8_t *acpi_table_first(void)
-{
- if (acpi_table_builtin || !acpi_tables) {
- return NULL;
- }
- return acpi_table_hdr(acpi_tables + ACPI_TABLE_PFX_SIZE);
-}
-
-uint8_t *acpi_table_next(uint8_t *current)
-{
- uint8_t *next = current + acpi_table_len(current);
-
- if (next - acpi_tables >= acpi_tables_len) {
- return NULL;
- } else {
- return acpi_table_hdr(next);
- }
-}
-
-int acpi_get_slic_oem(AcpiSlicOem *oem)
-{
- uint8_t *u;
-
- for (u = acpi_table_first(); u; u = acpi_table_next(u)) {
- struct acpi_table_header *hdr = (void *)(u - sizeof(hdr->_length));
-
- if (memcmp(hdr->sig, "SLIC", 4) == 0) {
- oem->id = hdr->oem_id;
- oem->table_id = hdr->oem_table_id;
- return 0;
- }
- }
- return -1;
-}
-
-static void acpi_notify_wakeup(Notifier *notifier, void *data)
-{
- ACPIREGS *ar = container_of(notifier, ACPIREGS, wakeup);
- WakeupReason *reason = data;
-
- switch (*reason) {
- case QEMU_WAKEUP_REASON_RTC:
- ar->pm1.evt.sts |=
- (ACPI_BITMASK_WAKE_STATUS | ACPI_BITMASK_RT_CLOCK_STATUS);
- break;
- case QEMU_WAKEUP_REASON_PMTIMER:
- ar->pm1.evt.sts |=
- (ACPI_BITMASK_WAKE_STATUS | ACPI_BITMASK_TIMER_STATUS);
- break;
- case QEMU_WAKEUP_REASON_OTHER:
- /* ACPI_BITMASK_WAKE_STATUS should be set on resume.
- Pretend that resume was caused by power button */
- ar->pm1.evt.sts |=
- (ACPI_BITMASK_WAKE_STATUS | ACPI_BITMASK_POWER_BUTTON_STATUS);
- break;
- default:
- break;
- }
-}
-
-/* ACPI PM1a EVT */
-uint16_t acpi_pm1_evt_get_sts(ACPIREGS *ar)
-{
- /* Compare ns-clock, not PM timer ticks, because
- acpi_pm_tmr_update function uses ns for setting the timer. */
- int64_t d = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
- if (d >= muldiv64(ar->tmr.overflow_time,
- NANOSECONDS_PER_SECOND, PM_TIMER_FREQUENCY)) {
- ar->pm1.evt.sts |= ACPI_BITMASK_TIMER_STATUS;
- }
- return ar->pm1.evt.sts;
-}
-
-static void acpi_pm1_evt_write_sts(ACPIREGS *ar, uint16_t val)
-{
- uint16_t pm1_sts = acpi_pm1_evt_get_sts(ar);
- if (pm1_sts & val & ACPI_BITMASK_TIMER_STATUS) {
- /* if TMRSTS is reset, then compute the new overflow time */
- acpi_pm_tmr_calc_overflow_time(ar);
- }
- ar->pm1.evt.sts &= ~val;
-}
-
-static void acpi_pm1_evt_write_en(ACPIREGS *ar, uint16_t val)
-{
- ar->pm1.evt.en = val;
- qemu_system_wakeup_enable(QEMU_WAKEUP_REASON_RTC,
- val & ACPI_BITMASK_RT_CLOCK_ENABLE);
- qemu_system_wakeup_enable(QEMU_WAKEUP_REASON_PMTIMER,
- val & ACPI_BITMASK_TIMER_ENABLE);
-}
-
-void acpi_pm1_evt_power_down(ACPIREGS *ar)
-{
- if (ar->pm1.evt.en & ACPI_BITMASK_POWER_BUTTON_ENABLE) {
- ar->pm1.evt.sts |= ACPI_BITMASK_POWER_BUTTON_STATUS;
- ar->tmr.update_sci(ar);
- }
-}
-
-void acpi_pm1_evt_reset(ACPIREGS *ar)
-{
- ar->pm1.evt.sts = 0;
- ar->pm1.evt.en = 0;
- qemu_system_wakeup_enable(QEMU_WAKEUP_REASON_RTC, 0);
- qemu_system_wakeup_enable(QEMU_WAKEUP_REASON_PMTIMER, 0);
-}
-
-static uint64_t acpi_pm_evt_read(void *opaque, hwaddr addr, unsigned width)
-{
- ACPIREGS *ar = opaque;
- switch (addr) {
- case 0:
- return acpi_pm1_evt_get_sts(ar);
- case 2:
- return ar->pm1.evt.en;
- default:
- return 0;
- }
-}
-
-static void acpi_pm_evt_write(void *opaque, hwaddr addr, uint64_t val,
- unsigned width)
-{
- ACPIREGS *ar = opaque;
- switch (addr) {
- case 0:
- acpi_pm1_evt_write_sts(ar, val);
- ar->pm1.evt.update_sci(ar);
- break;
- case 2:
- acpi_pm1_evt_write_en(ar, val);
- ar->pm1.evt.update_sci(ar);
- break;
- }
-}
-
-static const MemoryRegionOps acpi_pm_evt_ops = {
- .read = acpi_pm_evt_read,
- .write = acpi_pm_evt_write,
- .valid.min_access_size = 2,
- .valid.max_access_size = 2,
- .endianness = DEVICE_LITTLE_ENDIAN,
-};
-
-void acpi_pm1_evt_init(ACPIREGS *ar, acpi_update_sci_fn update_sci,
- MemoryRegion *parent)
-{
- ar->pm1.evt.update_sci = update_sci;
- memory_region_init_io(&ar->pm1.evt.io, memory_region_owner(parent),
- &acpi_pm_evt_ops, ar, "acpi-evt", 4);
- memory_region_add_subregion(parent, 0, &ar->pm1.evt.io);
-}
-
-/* ACPI PM_TMR */
-void acpi_pm_tmr_update(ACPIREGS *ar, bool enable)
-{
- int64_t expire_time;
-
- /* schedule a timer interruption if needed */
- if (enable) {
- expire_time = muldiv64(ar->tmr.overflow_time, NANOSECONDS_PER_SECOND,
- PM_TIMER_FREQUENCY);
- timer_mod(ar->tmr.timer, expire_time);
- } else {
- timer_del(ar->tmr.timer);
- }
-}
-
-void acpi_pm_tmr_calc_overflow_time(ACPIREGS *ar)
-{
- int64_t d = acpi_pm_tmr_get_clock();
- ar->tmr.overflow_time = (d + 0x800000LL) & ~0x7fffffLL;
-}
-
-static uint32_t acpi_pm_tmr_get(ACPIREGS *ar)
-{
- uint32_t d = acpi_pm_tmr_get_clock();
- return d & 0xffffff;
-}
-
-static void acpi_pm_tmr_timer(void *opaque)
-{
- ACPIREGS *ar = opaque;
- qemu_system_wakeup_request(QEMU_WAKEUP_REASON_PMTIMER);
- ar->tmr.update_sci(ar);
-}
-
-static uint64_t acpi_pm_tmr_read(void *opaque, hwaddr addr, unsigned width)
-{
- return acpi_pm_tmr_get(opaque);
-}
-
-static void acpi_pm_tmr_write(void *opaque, hwaddr addr, uint64_t val,
- unsigned width)
-{
- /* nothing */
-}
-
-static const MemoryRegionOps acpi_pm_tmr_ops = {
- .read = acpi_pm_tmr_read,
- .write = acpi_pm_tmr_write,
- .valid.min_access_size = 4,
- .valid.max_access_size = 4,
- .endianness = DEVICE_LITTLE_ENDIAN,
-};
-
-void acpi_pm_tmr_init(ACPIREGS *ar, acpi_update_sci_fn update_sci,
- MemoryRegion *parent)
-{
- ar->tmr.update_sci = update_sci;
- ar->tmr.timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, acpi_pm_tmr_timer, ar);
- memory_region_init_io(&ar->tmr.io, memory_region_owner(parent),
- &acpi_pm_tmr_ops, ar, "acpi-tmr", 4);
- memory_region_add_subregion(parent, 8, &ar->tmr.io);
-}
-
-void acpi_pm_tmr_reset(ACPIREGS *ar)
-{
- ar->tmr.overflow_time = 0;
- timer_del(ar->tmr.timer);
-}
-
-/* ACPI PM1aCNT */
-static void acpi_pm1_cnt_write(ACPIREGS *ar, uint16_t val)
-{
- ar->pm1.cnt.cnt = val & ~(ACPI_BITMASK_SLEEP_ENABLE);
-
- if (val & ACPI_BITMASK_SLEEP_ENABLE) {
- /* change suspend type */
- uint16_t sus_typ = (val >> 10) & 7;
- switch(sus_typ) {
- case 0: /* soft power off */
- qemu_system_shutdown_request();
- break;
- case 1:
- qemu_system_suspend_request();
- break;
- default:
- if (sus_typ == ar->pm1.cnt.s4_val) { /* S4 request */
- qapi_event_send_suspend_disk(&error_abort);
- qemu_system_shutdown_request();
- }
- break;
- }
- }
-}
-
-void acpi_pm1_cnt_update(ACPIREGS *ar,
- bool sci_enable, bool sci_disable)
-{
- /* ACPI specs 3.0, 4.7.2.5 */
- if (sci_enable) {
- ar->pm1.cnt.cnt |= ACPI_BITMASK_SCI_ENABLE;
- } else if (sci_disable) {
- ar->pm1.cnt.cnt &= ~ACPI_BITMASK_SCI_ENABLE;
- }
-}
-
-static uint64_t acpi_pm_cnt_read(void *opaque, hwaddr addr, unsigned width)
-{
- ACPIREGS *ar = opaque;
- return ar->pm1.cnt.cnt;
-}
-
-static void acpi_pm_cnt_write(void *opaque, hwaddr addr, uint64_t val,
- unsigned width)
-{
- acpi_pm1_cnt_write(opaque, val);
-}
-
-static const MemoryRegionOps acpi_pm_cnt_ops = {
- .read = acpi_pm_cnt_read,
- .write = acpi_pm_cnt_write,
- .valid.min_access_size = 2,
- .valid.max_access_size = 2,
- .endianness = DEVICE_LITTLE_ENDIAN,
-};
-
-void acpi_pm1_cnt_init(ACPIREGS *ar, MemoryRegion *parent,
- bool disable_s3, bool disable_s4, uint8_t s4_val)
-{
- FWCfgState *fw_cfg;
-
- ar->pm1.cnt.s4_val = s4_val;
- ar->wakeup.notify = acpi_notify_wakeup;
- qemu_register_wakeup_notifier(&ar->wakeup);
- memory_region_init_io(&ar->pm1.cnt.io, memory_region_owner(parent),
- &acpi_pm_cnt_ops, ar, "acpi-cnt", 2);
- memory_region_add_subregion(parent, 4, &ar->pm1.cnt.io);
-
- fw_cfg = fw_cfg_find();
- if (fw_cfg) {
- uint8_t suspend[6] = {128, 0, 0, 129, 128, 128};
- suspend[3] = 1 | ((!disable_s3) << 7);
- suspend[4] = s4_val | ((!disable_s4) << 7);
-
- fw_cfg_add_file(fw_cfg, "etc/system-states", g_memdup(suspend, 6), 6);
- }
-}
-
-void acpi_pm1_cnt_reset(ACPIREGS *ar)
-{
- ar->pm1.cnt.cnt = 0;
-}
-
-/* ACPI GPE */
-void acpi_gpe_init(ACPIREGS *ar, uint8_t len)
-{
- ar->gpe.len = len;
- /* Only first len / 2 bytes are ever used,
- * but the caller in ich9.c migrates full len bytes.
- * TODO: fix ich9.c and drop the extra allocation.
- */
- ar->gpe.sts = g_malloc0(len);
- ar->gpe.en = g_malloc0(len);
-}
-
-void acpi_gpe_reset(ACPIREGS *ar)
-{
- memset(ar->gpe.sts, 0, ar->gpe.len / 2);
- memset(ar->gpe.en, 0, ar->gpe.len / 2);
-}
-
-static uint8_t *acpi_gpe_ioport_get_ptr(ACPIREGS *ar, uint32_t addr)
-{
- uint8_t *cur = NULL;
-
- if (addr < ar->gpe.len / 2) {
- cur = ar->gpe.sts + addr;
- } else if (addr < ar->gpe.len) {
- cur = ar->gpe.en + addr - ar->gpe.len / 2;
- } else {
- abort();
- }
-
- return cur;
-}
-
-void acpi_gpe_ioport_writeb(ACPIREGS *ar, uint32_t addr, uint32_t val)
-{
- uint8_t *cur;
-
- cur = acpi_gpe_ioport_get_ptr(ar, addr);
- if (addr < ar->gpe.len / 2) {
- /* GPE_STS */
- *cur = (*cur) & ~val;
- } else if (addr < ar->gpe.len) {
- /* GPE_EN */
- *cur = val;
- } else {
- abort();
- }
-}
-
-uint32_t acpi_gpe_ioport_readb(ACPIREGS *ar, uint32_t addr)
-{
- uint8_t *cur;
- uint32_t val;
-
- cur = acpi_gpe_ioport_get_ptr(ar, addr);
- val = 0;
- if (cur != NULL) {
- val = *cur;
- }
-
- return val;
-}
-
-void acpi_send_gpe_event(ACPIREGS *ar, qemu_irq irq,
- AcpiGPEStatusBits status)
-{
- ar->gpe.sts[0] |= status;
- acpi_update_sci(ar, irq);
-}
-
-void acpi_update_sci(ACPIREGS *regs, qemu_irq irq)
-{
- int sci_level, pm1a_sts;
-
- pm1a_sts = acpi_pm1_evt_get_sts(regs);
-
- sci_level = ((pm1a_sts &
- regs->pm1.evt.en & ACPI_BITMASK_PM1_COMMON_ENABLED) != 0) ||
- ((regs->gpe.sts[0] & regs->gpe.en[0]) != 0);
-
- qemu_set_irq(irq, sci_level);
-
- /* schedule a timer interruption if needed */
- acpi_pm_tmr_update(regs,
- (regs->pm1.evt.en & ACPI_BITMASK_TIMER_ENABLE) &&
- !(pm1a_sts & ACPI_BITMASK_TIMER_STATUS));
-}
diff --git a/qemu/hw/acpi/cpu_hotplug.c b/qemu/hw/acpi/cpu_hotplug.c
deleted file mode 100644
index 4d86743fd..000000000
--- a/qemu/hw/acpi/cpu_hotplug.c
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * QEMU ACPI hotplug utilities
- *
- * Copyright (C) 2013 Red Hat Inc
- *
- * Authors:
- * Igor Mammedov <imammedo@redhat.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-#include "qemu/osdep.h"
-#include "hw/hw.h"
-#include "hw/acpi/cpu_hotplug.h"
-#include "qapi/error.h"
-#include "qom/cpu.h"
-
-static uint64_t cpu_status_read(void *opaque, hwaddr addr, unsigned int size)
-{
- AcpiCpuHotplug *cpus = opaque;
- uint64_t val = cpus->sts[addr];
-
- return val;
-}
-
-static void cpu_status_write(void *opaque, hwaddr addr, uint64_t data,
- unsigned int size)
-{
- /* TODO: implement VCPU removal on guest signal that CPU can be removed */
-}
-
-static const MemoryRegionOps AcpiCpuHotplug_ops = {
- .read = cpu_status_read,
- .write = cpu_status_write,
- .endianness = DEVICE_LITTLE_ENDIAN,
- .valid = {
- .min_access_size = 1,
- .max_access_size = 1,
- },
-};
-
-static void acpi_set_cpu_present_bit(AcpiCpuHotplug *g, CPUState *cpu,
- Error **errp)
-{
- CPUClass *k = CPU_GET_CLASS(cpu);
- int64_t cpu_id;
-
- cpu_id = k->get_arch_id(cpu);
- if ((cpu_id / 8) >= ACPI_GPE_PROC_LEN) {
- error_setg(errp, "acpi: invalid cpu id: %" PRIi64, cpu_id);
- return;
- }
-
- g->sts[cpu_id / 8] |= (1 << (cpu_id % 8));
-}
-
-void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq,
- AcpiCpuHotplug *g, DeviceState *dev, Error **errp)
-{
- acpi_set_cpu_present_bit(g, CPU(dev), errp);
- if (*errp != NULL) {
- return;
- }
-
- acpi_send_gpe_event(ar, irq, ACPI_CPU_HOTPLUG_STATUS);
-}
-
-void acpi_cpu_hotplug_init(MemoryRegion *parent, Object *owner,
- AcpiCpuHotplug *gpe_cpu, uint16_t base)
-{
- CPUState *cpu;
-
- CPU_FOREACH(cpu) {
- acpi_set_cpu_present_bit(gpe_cpu, cpu, &error_abort);
- }
- memory_region_init_io(&gpe_cpu->io, owner, &AcpiCpuHotplug_ops,
- gpe_cpu, "acpi-cpu-hotplug", ACPI_GPE_PROC_LEN);
- memory_region_add_subregion(parent, base, &gpe_cpu->io);
-}
diff --git a/qemu/hw/acpi/cpu_hotplug_acpi_table.c b/qemu/hw/acpi/cpu_hotplug_acpi_table.c
deleted file mode 100644
index 97bb1092a..000000000
--- a/qemu/hw/acpi/cpu_hotplug_acpi_table.c
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "qemu/osdep.h"
-#include "hw/acpi/cpu_hotplug.h"
-
-void build_cpu_hotplug_aml(Aml *ctx)
-{
- Aml *method;
- Aml *if_ctx;
- Aml *else_ctx;
- Aml *sb_scope = aml_scope("_SB");
- uint8_t madt_tmpl[8] = {0x00, 0x08, 0x00, 0x00, 0x00, 0, 0, 0};
- Aml *cpu_id = aml_arg(0);
- Aml *cpu_on = aml_local(0);
- Aml *madt = aml_local(1);
- Aml *cpus_map = aml_name(CPU_ON_BITMAP);
- Aml *zero = aml_int(0);
- Aml *one = aml_int(1);
-
- /*
- * _MAT method - creates an madt apic buffer
- * cpu_id = Arg0 = Processor ID = Local APIC ID
- * cpu_on = Local0 = CPON flag for this cpu
- * madt = Local1 = Buffer (in madt apic form) to return
- */
- method = aml_method(CPU_MAT_METHOD, 1, AML_NOTSERIALIZED);
- aml_append(method,
- aml_store(aml_derefof(aml_index(cpus_map, cpu_id)), cpu_on));
- aml_append(method,
- aml_store(aml_buffer(sizeof(madt_tmpl), madt_tmpl), madt));
- /* Update the processor id, lapic id, and enable/disable status */
- aml_append(method, aml_store(cpu_id, aml_index(madt, aml_int(2))));
- aml_append(method, aml_store(cpu_id, aml_index(madt, aml_int(3))));
- aml_append(method, aml_store(cpu_on, aml_index(madt, aml_int(4))));
- aml_append(method, aml_return(madt));
- aml_append(sb_scope, method);
-
- /*
- * _STA method - return ON status of cpu
- * cpu_id = Arg0 = Processor ID = Local APIC ID
- * cpu_on = Local0 = CPON flag for this cpu
- */
- method = aml_method(CPU_STATUS_METHOD, 1, AML_NOTSERIALIZED);
- aml_append(method,
- aml_store(aml_derefof(aml_index(cpus_map, cpu_id)), cpu_on));
- if_ctx = aml_if(cpu_on);
- {
- aml_append(if_ctx, aml_return(aml_int(0xF)));
- }
- aml_append(method, if_ctx);
- else_ctx = aml_else();
- {
- aml_append(else_ctx, aml_return(zero));
- }
- aml_append(method, else_ctx);
- aml_append(sb_scope, method);
-
- method = aml_method(CPU_EJECT_METHOD, 2, AML_NOTSERIALIZED);
- aml_append(method, aml_sleep(200));
- aml_append(sb_scope, method);
-
- method = aml_method(CPU_SCAN_METHOD, 0, AML_NOTSERIALIZED);
- {
- Aml *while_ctx, *if_ctx2, *else_ctx2;
- Aml *bus_check_evt = aml_int(1);
- Aml *remove_evt = aml_int(3);
- Aml *status_map = aml_local(5); /* Local5 = active cpu bitmap */
- Aml *byte = aml_local(2); /* Local2 = last read byte from bitmap */
- Aml *idx = aml_local(0); /* Processor ID / APIC ID iterator */
- Aml *is_cpu_on = aml_local(1); /* Local1 = CPON flag for cpu */
- Aml *status = aml_local(3); /* Local3 = active state for cpu */
-
- aml_append(method, aml_store(aml_name(CPU_STATUS_MAP), status_map));
- aml_append(method, aml_store(zero, byte));
- aml_append(method, aml_store(zero, idx));
-
- /* While (idx < SizeOf(CPON)) */
- while_ctx = aml_while(aml_lless(idx, aml_sizeof(cpus_map)));
- aml_append(while_ctx,
- aml_store(aml_derefof(aml_index(cpus_map, idx)), is_cpu_on));
-
- if_ctx = aml_if(aml_and(idx, aml_int(0x07), NULL));
- {
- /* Shift down previously read bitmap byte */
- aml_append(if_ctx, aml_shiftright(byte, one, byte));
- }
- aml_append(while_ctx, if_ctx);
-
- else_ctx = aml_else();
- {
- /* Read next byte from cpu bitmap */
- aml_append(else_ctx, aml_store(aml_derefof(aml_index(status_map,
- aml_shiftright(idx, aml_int(3), NULL))), byte));
- }
- aml_append(while_ctx, else_ctx);
-
- aml_append(while_ctx, aml_store(aml_and(byte, one, NULL), status));
- if_ctx = aml_if(aml_lnot(aml_equal(is_cpu_on, status)));
- {
- /* State change - update CPON with new state */
- aml_append(if_ctx, aml_store(status, aml_index(cpus_map, idx)));
- if_ctx2 = aml_if(aml_equal(status, one));
- {
- aml_append(if_ctx2,
- aml_call2(AML_NOTIFY_METHOD, idx, bus_check_evt));
- }
- aml_append(if_ctx, if_ctx2);
- else_ctx2 = aml_else();
- {
- aml_append(else_ctx2,
- aml_call2(AML_NOTIFY_METHOD, idx, remove_evt));
- }
- }
- aml_append(if_ctx, else_ctx2);
- aml_append(while_ctx, if_ctx);
-
- aml_append(while_ctx, aml_increment(idx)); /* go to next cpu */
- aml_append(method, while_ctx);
- }
- aml_append(sb_scope, method);
-
- aml_append(ctx, sb_scope);
-}
diff --git a/qemu/hw/acpi/ich9.c b/qemu/hw/acpi/ich9.c
deleted file mode 100644
index 27e978f5f..000000000
--- a/qemu/hw/acpi/ich9.c
+++ /dev/null
@@ -1,477 +0,0 @@
-/*
- * ACPI implementation
- *
- * Copyright (c) 2006 Fabrice Bellard
- * Copyright (c) 2009 Isaku Yamahata <yamahata at valinux co jp>
- * VA Linux Systems Japan K.K.
- * Copyright (C) 2012 Jason Baron <jbaron@redhat.com>
- *
- * This is based on acpi.c.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License version 2 as published by the Free Software Foundation.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see <http://www.gnu.org/licenses/>
- *
- * Contributions after 2012-01-13 are licensed under the terms of the
- * GNU GPL, version 2 or (at your option) any later version.
- */
-#include "qemu/osdep.h"
-#include "hw/hw.h"
-#include "qapi/error.h"
-#include "qapi/visitor.h"
-#include "hw/i386/pc.h"
-#include "hw/pci/pci.h"
-#include "qemu/timer.h"
-#include "sysemu/sysemu.h"
-#include "hw/acpi/acpi.h"
-#include "hw/acpi/tco.h"
-#include "sysemu/kvm.h"
-#include "exec/address-spaces.h"
-
-#include "hw/i386/ich9.h"
-#include "hw/mem/pc-dimm.h"
-
-//#define DEBUG
-
-#ifdef DEBUG
-#define ICH9_DEBUG(fmt, ...) \
-do { printf("%s "fmt, __func__, ## __VA_ARGS__); } while (0)
-#else
-#define ICH9_DEBUG(fmt, ...) do { } while (0)
-#endif
-
-static void ich9_pm_update_sci_fn(ACPIREGS *regs)
-{
- ICH9LPCPMRegs *pm = container_of(regs, ICH9LPCPMRegs, acpi_regs);
- acpi_update_sci(&pm->acpi_regs, pm->irq);
-}
-
-static uint64_t ich9_gpe_readb(void *opaque, hwaddr addr, unsigned width)
-{
- ICH9LPCPMRegs *pm = opaque;
- return acpi_gpe_ioport_readb(&pm->acpi_regs, addr);
-}
-
-static void ich9_gpe_writeb(void *opaque, hwaddr addr, uint64_t val,
- unsigned width)
-{
- ICH9LPCPMRegs *pm = opaque;
- acpi_gpe_ioport_writeb(&pm->acpi_regs, addr, val);
- acpi_update_sci(&pm->acpi_regs, pm->irq);
-}
-
-static const MemoryRegionOps ich9_gpe_ops = {
- .read = ich9_gpe_readb,
- .write = ich9_gpe_writeb,
- .valid.min_access_size = 1,
- .valid.max_access_size = 4,
- .impl.min_access_size = 1,
- .impl.max_access_size = 1,
- .endianness = DEVICE_LITTLE_ENDIAN,
-};
-
-static uint64_t ich9_smi_readl(void *opaque, hwaddr addr, unsigned width)
-{
- ICH9LPCPMRegs *pm = opaque;
- switch (addr) {
- case 0:
- return pm->smi_en;
- case 4:
- return pm->smi_sts;
- default:
- return 0;
- }
-}
-
-static void ich9_smi_writel(void *opaque, hwaddr addr, uint64_t val,
- unsigned width)
-{
- ICH9LPCPMRegs *pm = opaque;
- TCOIORegs *tr = &pm->tco_regs;
- uint64_t tco_en;
-
- switch (addr) {
- case 0:
- tco_en = pm->smi_en & ICH9_PMIO_SMI_EN_TCO_EN;
- /* once TCO_LOCK bit is set, TCO_EN bit cannot be overwritten */
- if (tr->tco.cnt1 & TCO_LOCK) {
- val = (val & ~ICH9_PMIO_SMI_EN_TCO_EN) | tco_en;
- }
- pm->smi_en &= ~pm->smi_en_wmask;
- pm->smi_en |= (val & pm->smi_en_wmask);
- break;
- }
-}
-
-static const MemoryRegionOps ich9_smi_ops = {
- .read = ich9_smi_readl,
- .write = ich9_smi_writel,
- .valid.min_access_size = 4,
- .valid.max_access_size = 4,
- .endianness = DEVICE_LITTLE_ENDIAN,
-};
-
-void ich9_pm_iospace_update(ICH9LPCPMRegs *pm, uint32_t pm_io_base)
-{
- ICH9_DEBUG("to 0x%x\n", pm_io_base);
-
- assert((pm_io_base & ICH9_PMIO_MASK) == 0);
-
- pm->pm_io_base = pm_io_base;
- memory_region_transaction_begin();
- memory_region_set_enabled(&pm->io, pm->pm_io_base != 0);
- memory_region_set_address(&pm->io, pm->pm_io_base);
- memory_region_transaction_commit();
-}
-
-static int ich9_pm_post_load(void *opaque, int version_id)
-{
- ICH9LPCPMRegs *pm = opaque;
- uint32_t pm_io_base = pm->pm_io_base;
- pm->pm_io_base = 0;
- ich9_pm_iospace_update(pm, pm_io_base);
- return 0;
-}
-
-#define VMSTATE_GPE_ARRAY(_field, _state) \
- { \
- .name = (stringify(_field)), \
- .version_id = 0, \
- .num = ICH9_PMIO_GPE0_LEN, \
- .info = &vmstate_info_uint8, \
- .size = sizeof(uint8_t), \
- .flags = VMS_ARRAY | VMS_POINTER, \
- .offset = vmstate_offset_pointer(_state, _field, uint8_t), \
- }
-
-static bool vmstate_test_use_memhp(void *opaque)
-{
- ICH9LPCPMRegs *s = opaque;
- return s->acpi_memory_hotplug.is_enabled;
-}
-
-static const VMStateDescription vmstate_memhp_state = {
- .name = "ich9_pm/memhp",
- .version_id = 1,
- .minimum_version_id = 1,
- .minimum_version_id_old = 1,
- .needed = vmstate_test_use_memhp,
- .fields = (VMStateField[]) {
- VMSTATE_MEMORY_HOTPLUG(acpi_memory_hotplug, ICH9LPCPMRegs),
- VMSTATE_END_OF_LIST()
- }
-};
-
-static bool vmstate_test_use_tco(void *opaque)
-{
- ICH9LPCPMRegs *s = opaque;
- return s->enable_tco;
-}
-
-static const VMStateDescription vmstate_tco_io_state = {
- .name = "ich9_pm/tco",
- .version_id = 1,
- .minimum_version_id = 1,
- .minimum_version_id_old = 1,
- .needed = vmstate_test_use_tco,
- .fields = (VMStateField[]) {
- VMSTATE_STRUCT(tco_regs, ICH9LPCPMRegs, 1, vmstate_tco_io_sts,
- TCOIORegs),
- VMSTATE_END_OF_LIST()
- }
-};
-
-const VMStateDescription vmstate_ich9_pm = {
- .name = "ich9_pm",
- .version_id = 1,
- .minimum_version_id = 1,
- .post_load = ich9_pm_post_load,
- .fields = (VMStateField[]) {
- VMSTATE_UINT16(acpi_regs.pm1.evt.sts, ICH9LPCPMRegs),
- VMSTATE_UINT16(acpi_regs.pm1.evt.en, ICH9LPCPMRegs),
- VMSTATE_UINT16(acpi_regs.pm1.cnt.cnt, ICH9LPCPMRegs),
- VMSTATE_TIMER_PTR(acpi_regs.tmr.timer, ICH9LPCPMRegs),
- VMSTATE_INT64(acpi_regs.tmr.overflow_time, ICH9LPCPMRegs),
- VMSTATE_GPE_ARRAY(acpi_regs.gpe.sts, ICH9LPCPMRegs),
- VMSTATE_GPE_ARRAY(acpi_regs.gpe.en, ICH9LPCPMRegs),
- VMSTATE_UINT32(smi_en, ICH9LPCPMRegs),
- VMSTATE_UINT32(smi_sts, ICH9LPCPMRegs),
- VMSTATE_END_OF_LIST()
- },
- .subsections = (const VMStateDescription*[]) {
- &vmstate_memhp_state,
- &vmstate_tco_io_state,
- NULL
- }
-};
-
-static void pm_reset(void *opaque)
-{
- ICH9LPCPMRegs *pm = opaque;
- ich9_pm_iospace_update(pm, 0);
-
- acpi_pm1_evt_reset(&pm->acpi_regs);
- acpi_pm1_cnt_reset(&pm->acpi_regs);
- acpi_pm_tmr_reset(&pm->acpi_regs);
- acpi_gpe_reset(&pm->acpi_regs);
-
- pm->smi_en = 0;
- if (!pm->smm_enabled) {
- /* Mark SMM as already inited to prevent SMM from running. */
- pm->smi_en |= ICH9_PMIO_SMI_EN_APMC_EN;
- }
- pm->smi_en_wmask = ~0;
-
- acpi_update_sci(&pm->acpi_regs, pm->irq);
-}
-
-static void pm_powerdown_req(Notifier *n, void *opaque)
-{
- ICH9LPCPMRegs *pm = container_of(n, ICH9LPCPMRegs, powerdown_notifier);
-
- acpi_pm1_evt_power_down(&pm->acpi_regs);
-}
-
-void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs *pm,
- bool smm_enabled,
- qemu_irq sci_irq)
-{
- memory_region_init(&pm->io, OBJECT(lpc_pci), "ich9-pm", ICH9_PMIO_SIZE);
- memory_region_set_enabled(&pm->io, false);
- memory_region_add_subregion(pci_address_space_io(lpc_pci),
- 0, &pm->io);
-
- acpi_pm_tmr_init(&pm->acpi_regs, ich9_pm_update_sci_fn, &pm->io);
- acpi_pm1_evt_init(&pm->acpi_regs, ich9_pm_update_sci_fn, &pm->io);
- acpi_pm1_cnt_init(&pm->acpi_regs, &pm->io, pm->disable_s3, pm->disable_s4,
- pm->s4_val);
-
- acpi_gpe_init(&pm->acpi_regs, ICH9_PMIO_GPE0_LEN);
- memory_region_init_io(&pm->io_gpe, OBJECT(lpc_pci), &ich9_gpe_ops, pm,
- "acpi-gpe0", ICH9_PMIO_GPE0_LEN);
- memory_region_add_subregion(&pm->io, ICH9_PMIO_GPE0_STS, &pm->io_gpe);
-
- memory_region_init_io(&pm->io_smi, OBJECT(lpc_pci), &ich9_smi_ops, pm,
- "acpi-smi", 8);
- memory_region_add_subregion(&pm->io, ICH9_PMIO_SMI_EN, &pm->io_smi);
-
- pm->smm_enabled = smm_enabled;
-
- pm->enable_tco = true;
- acpi_pm_tco_init(&pm->tco_regs, &pm->io);
-
- pm->irq = sci_irq;
- qemu_register_reset(pm_reset, pm);
- pm->powerdown_notifier.notify = pm_powerdown_req;
- qemu_register_powerdown_notifier(&pm->powerdown_notifier);
-
- acpi_cpu_hotplug_init(pci_address_space_io(lpc_pci), OBJECT(lpc_pci),
- &pm->gpe_cpu, ICH9_CPU_HOTPLUG_IO_BASE);
-
- if (pm->acpi_memory_hotplug.is_enabled) {
- acpi_memory_hotplug_init(pci_address_space_io(lpc_pci), OBJECT(lpc_pci),
- &pm->acpi_memory_hotplug);
- }
-}
-
-static void ich9_pm_get_gpe0_blk(Object *obj, Visitor *v, const char *name,
- void *opaque, Error **errp)
-{
- ICH9LPCPMRegs *pm = opaque;
- uint32_t value = pm->pm_io_base + ICH9_PMIO_GPE0_STS;
-
- visit_type_uint32(v, name, &value, errp);
-}
-
-static bool ich9_pm_get_memory_hotplug_support(Object *obj, Error **errp)
-{
- ICH9LPCState *s = ICH9_LPC_DEVICE(obj);
-
- return s->pm.acpi_memory_hotplug.is_enabled;
-}
-
-static void ich9_pm_set_memory_hotplug_support(Object *obj, bool value,
- Error **errp)
-{
- ICH9LPCState *s = ICH9_LPC_DEVICE(obj);
-
- s->pm.acpi_memory_hotplug.is_enabled = value;
-}
-
-static void ich9_pm_get_disable_s3(Object *obj, Visitor *v, const char *name,
- void *opaque, Error **errp)
-{
- ICH9LPCPMRegs *pm = opaque;
- uint8_t value = pm->disable_s3;
-
- visit_type_uint8(v, name, &value, errp);
-}
-
-static void ich9_pm_set_disable_s3(Object *obj, Visitor *v, const char *name,
- void *opaque, Error **errp)
-{
- ICH9LPCPMRegs *pm = opaque;
- Error *local_err = NULL;
- uint8_t value;
-
- visit_type_uint8(v, name, &value, &local_err);
- if (local_err) {
- goto out;
- }
- pm->disable_s3 = value;
-out:
- error_propagate(errp, local_err);
-}
-
-static void ich9_pm_get_disable_s4(Object *obj, Visitor *v, const char *name,
- void *opaque, Error **errp)
-{
- ICH9LPCPMRegs *pm = opaque;
- uint8_t value = pm->disable_s4;
-
- visit_type_uint8(v, name, &value, errp);
-}
-
-static void ich9_pm_set_disable_s4(Object *obj, Visitor *v, const char *name,
- void *opaque, Error **errp)
-{
- ICH9LPCPMRegs *pm = opaque;
- Error *local_err = NULL;
- uint8_t value;
-
- visit_type_uint8(v, name, &value, &local_err);
- if (local_err) {
- goto out;
- }
- pm->disable_s4 = value;
-out:
- error_propagate(errp, local_err);
-}
-
-static void ich9_pm_get_s4_val(Object *obj, Visitor *v, const char *name,
- void *opaque, Error **errp)
-{
- ICH9LPCPMRegs *pm = opaque;
- uint8_t value = pm->s4_val;
-
- visit_type_uint8(v, name, &value, errp);
-}
-
-static void ich9_pm_set_s4_val(Object *obj, Visitor *v, const char *name,
- void *opaque, Error **errp)
-{
- ICH9LPCPMRegs *pm = opaque;
- Error *local_err = NULL;
- uint8_t value;
-
- visit_type_uint8(v, name, &value, &local_err);
- if (local_err) {
- goto out;
- }
- pm->s4_val = value;
-out:
- error_propagate(errp, local_err);
-}
-
-static bool ich9_pm_get_enable_tco(Object *obj, Error **errp)
-{
- ICH9LPCState *s = ICH9_LPC_DEVICE(obj);
- return s->pm.enable_tco;
-}
-
-static void ich9_pm_set_enable_tco(Object *obj, bool value, Error **errp)
-{
- ICH9LPCState *s = ICH9_LPC_DEVICE(obj);
- s->pm.enable_tco = value;
-}
-
-void ich9_pm_add_properties(Object *obj, ICH9LPCPMRegs *pm, Error **errp)
-{
- static const uint32_t gpe0_len = ICH9_PMIO_GPE0_LEN;
- pm->acpi_memory_hotplug.is_enabled = true;
- pm->disable_s3 = 0;
- pm->disable_s4 = 0;
- pm->s4_val = 2;
-
- object_property_add_uint32_ptr(obj, ACPI_PM_PROP_PM_IO_BASE,
- &pm->pm_io_base, errp);
- object_property_add(obj, ACPI_PM_PROP_GPE0_BLK, "uint32",
- ich9_pm_get_gpe0_blk,
- NULL, NULL, pm, NULL);
- object_property_add_uint32_ptr(obj, ACPI_PM_PROP_GPE0_BLK_LEN,
- &gpe0_len, errp);
- object_property_add_bool(obj, "memory-hotplug-support",
- ich9_pm_get_memory_hotplug_support,
- ich9_pm_set_memory_hotplug_support,
- NULL);
- object_property_add(obj, ACPI_PM_PROP_S3_DISABLED, "uint8",
- ich9_pm_get_disable_s3,
- ich9_pm_set_disable_s3,
- NULL, pm, NULL);
- object_property_add(obj, ACPI_PM_PROP_S4_DISABLED, "uint8",
- ich9_pm_get_disable_s4,
- ich9_pm_set_disable_s4,
- NULL, pm, NULL);
- object_property_add(obj, ACPI_PM_PROP_S4_VAL, "uint8",
- ich9_pm_get_s4_val,
- ich9_pm_set_s4_val,
- NULL, pm, NULL);
- object_property_add_bool(obj, ACPI_PM_PROP_TCO_ENABLED,
- ich9_pm_get_enable_tco,
- ich9_pm_set_enable_tco,
- NULL);
-}
-
-void ich9_pm_device_plug_cb(ICH9LPCPMRegs *pm, DeviceState *dev, Error **errp)
-{
- if (pm->acpi_memory_hotplug.is_enabled &&
- object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
- acpi_memory_plug_cb(&pm->acpi_regs, pm->irq, &pm->acpi_memory_hotplug,
- dev, errp);
- } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
- acpi_cpu_plug_cb(&pm->acpi_regs, pm->irq, &pm->gpe_cpu, dev, errp);
- } else {
- error_setg(errp, "acpi: device plug request for not supported device"
- " type: %s", object_get_typename(OBJECT(dev)));
- }
-}
-
-void ich9_pm_device_unplug_request_cb(ICH9LPCPMRegs *pm, DeviceState *dev,
- Error **errp)
-{
- if (pm->acpi_memory_hotplug.is_enabled &&
- object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
- acpi_memory_unplug_request_cb(&pm->acpi_regs, pm->irq,
- &pm->acpi_memory_hotplug, dev, errp);
- } else {
- error_setg(errp, "acpi: device unplug request for not supported device"
- " type: %s", object_get_typename(OBJECT(dev)));
- }
-}
-
-void ich9_pm_device_unplug_cb(ICH9LPCPMRegs *pm, DeviceState *dev,
- Error **errp)
-{
- if (pm->acpi_memory_hotplug.is_enabled &&
- object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
- acpi_memory_unplug_cb(&pm->acpi_memory_hotplug, dev, errp);
- } else {
- error_setg(errp, "acpi: device unplug for not supported device"
- " type: %s", object_get_typename(OBJECT(dev)));
- }
-}
-
-void ich9_pm_ospm_status(AcpiDeviceIf *adev, ACPIOSTInfoList ***list)
-{
- ICH9LPCState *s = ICH9_LPC_DEVICE(adev);
-
- acpi_memory_ospm_status(&s->pm.acpi_memory_hotplug, list);
-}
diff --git a/qemu/hw/acpi/memory_hotplug.c b/qemu/hw/acpi/memory_hotplug.c
deleted file mode 100644
index f65a3a21e..000000000
--- a/qemu/hw/acpi/memory_hotplug.c
+++ /dev/null
@@ -1,312 +0,0 @@
-#include "qemu/osdep.h"
-#include "hw/acpi/memory_hotplug.h"
-#include "hw/acpi/pc-hotplug.h"
-#include "hw/mem/pc-dimm.h"
-#include "hw/boards.h"
-#include "hw/qdev-core.h"
-#include "trace.h"
-#include "qapi-event.h"
-
-static ACPIOSTInfo *acpi_memory_device_status(int slot, MemStatus *mdev)
-{
- ACPIOSTInfo *info = g_new0(ACPIOSTInfo, 1);
-
- info->slot_type = ACPI_SLOT_TYPE_DIMM;
- info->slot = g_strdup_printf("%d", slot);
- info->source = mdev->ost_event;
- info->status = mdev->ost_status;
- if (mdev->dimm) {
- DeviceState *dev = DEVICE(mdev->dimm);
- if (dev->id) {
- info->device = g_strdup(dev->id);
- info->has_device = true;
- }
- }
- return info;
-}
-
-void acpi_memory_ospm_status(MemHotplugState *mem_st, ACPIOSTInfoList ***list)
-{
- int i;
-
- for (i = 0; i < mem_st->dev_count; i++) {
- ACPIOSTInfoList *elem = g_new0(ACPIOSTInfoList, 1);
- elem->value = acpi_memory_device_status(i, &mem_st->devs[i]);
- elem->next = NULL;
- **list = elem;
- *list = &elem->next;
- }
-}
-
-static uint64_t acpi_memory_hotplug_read(void *opaque, hwaddr addr,
- unsigned int size)
-{
- uint32_t val = 0;
- MemHotplugState *mem_st = opaque;
- MemStatus *mdev;
- Object *o;
-
- if (mem_st->selector >= mem_st->dev_count) {
- trace_mhp_acpi_invalid_slot_selected(mem_st->selector);
- return 0;
- }
-
- mdev = &mem_st->devs[mem_st->selector];
- o = OBJECT(mdev->dimm);
- switch (addr) {
- case 0x0: /* Lo part of phys address where DIMM is mapped */
- val = o ? object_property_get_int(o, PC_DIMM_ADDR_PROP, NULL) : 0;
- trace_mhp_acpi_read_addr_lo(mem_st->selector, val);
- break;
- case 0x4: /* Hi part of phys address where DIMM is mapped */
- val = o ? object_property_get_int(o, PC_DIMM_ADDR_PROP, NULL) >> 32 : 0;
- trace_mhp_acpi_read_addr_hi(mem_st->selector, val);
- break;
- case 0x8: /* Lo part of DIMM size */
- val = o ? object_property_get_int(o, PC_DIMM_SIZE_PROP, NULL) : 0;
- trace_mhp_acpi_read_size_lo(mem_st->selector, val);
- break;
- case 0xc: /* Hi part of DIMM size */
- val = o ? object_property_get_int(o, PC_DIMM_SIZE_PROP, NULL) >> 32 : 0;
- trace_mhp_acpi_read_size_hi(mem_st->selector, val);
- break;
- case 0x10: /* node proximity for _PXM method */
- val = o ? object_property_get_int(o, PC_DIMM_NODE_PROP, NULL) : 0;
- trace_mhp_acpi_read_pxm(mem_st->selector, val);
- break;
- case 0x14: /* pack and return is_* fields */
- val |= mdev->is_enabled ? 1 : 0;
- val |= mdev->is_inserting ? 2 : 0;
- val |= mdev->is_removing ? 4 : 0;
- trace_mhp_acpi_read_flags(mem_st->selector, val);
- break;
- default:
- val = ~0;
- break;
- }
- return val;
-}
-
-static void acpi_memory_hotplug_write(void *opaque, hwaddr addr, uint64_t data,
- unsigned int size)
-{
- MemHotplugState *mem_st = opaque;
- MemStatus *mdev;
- ACPIOSTInfo *info;
- DeviceState *dev = NULL;
- HotplugHandler *hotplug_ctrl = NULL;
- Error *local_err = NULL;
-
- if (!mem_st->dev_count) {
- return;
- }
-
- if (addr) {
- if (mem_st->selector >= mem_st->dev_count) {
- trace_mhp_acpi_invalid_slot_selected(mem_st->selector);
- return;
- }
- }
-
- switch (addr) {
- case 0x0: /* DIMM slot selector */
- mem_st->selector = data;
- trace_mhp_acpi_write_slot(mem_st->selector);
- break;
- case 0x4: /* _OST event */
- mdev = &mem_st->devs[mem_st->selector];
- if (data == 1) {
- /* TODO: handle device insert OST event */
- } else if (data == 3) {
- /* TODO: handle device remove OST event */
- }
- mdev->ost_event = data;
- trace_mhp_acpi_write_ost_ev(mem_st->selector, mdev->ost_event);
- break;
- case 0x8: /* _OST status */
- mdev = &mem_st->devs[mem_st->selector];
- mdev->ost_status = data;
- trace_mhp_acpi_write_ost_status(mem_st->selector, mdev->ost_status);
- /* TODO: implement memory removal on guest signal */
-
- info = acpi_memory_device_status(mem_st->selector, mdev);
- qapi_event_send_acpi_device_ost(info, &error_abort);
- qapi_free_ACPIOSTInfo(info);
- break;
- case 0x14: /* set is_* fields */
- mdev = &mem_st->devs[mem_st->selector];
- if (data & 2) { /* clear insert event */
- mdev->is_inserting = false;
- trace_mhp_acpi_clear_insert_evt(mem_st->selector);
- } else if (data & 4) {
- mdev->is_removing = false;
- trace_mhp_acpi_clear_remove_evt(mem_st->selector);
- } else if (data & 8) {
- if (!mdev->is_enabled) {
- trace_mhp_acpi_ejecting_invalid_slot(mem_st->selector);
- break;
- }
-
- dev = DEVICE(mdev->dimm);
- hotplug_ctrl = qdev_get_hotplug_handler(dev);
- /* call pc-dimm unplug cb */
- hotplug_handler_unplug(hotplug_ctrl, dev, &local_err);
- if (local_err) {
- trace_mhp_acpi_pc_dimm_delete_failed(mem_st->selector);
- qapi_event_send_mem_unplug_error(dev->id,
- error_get_pretty(local_err),
- &error_abort);
- error_free(local_err);
- break;
- }
- trace_mhp_acpi_pc_dimm_deleted(mem_st->selector);
- }
- break;
- default:
- break;
- }
-
-}
-static const MemoryRegionOps acpi_memory_hotplug_ops = {
- .read = acpi_memory_hotplug_read,
- .write = acpi_memory_hotplug_write,
- .endianness = DEVICE_LITTLE_ENDIAN,
- .valid = {
- .min_access_size = 1,
- .max_access_size = 4,
- },
-};
-
-void acpi_memory_hotplug_init(MemoryRegion *as, Object *owner,
- MemHotplugState *state)
-{
- MachineState *machine = MACHINE(qdev_get_machine());
-
- state->dev_count = machine->ram_slots;
- if (!state->dev_count) {
- return;
- }
-
- state->devs = g_malloc0(sizeof(*state->devs) * state->dev_count);
- memory_region_init_io(&state->io, owner, &acpi_memory_hotplug_ops, state,
- "acpi-mem-hotplug", ACPI_MEMORY_HOTPLUG_IO_LEN);
- memory_region_add_subregion(as, ACPI_MEMORY_HOTPLUG_BASE, &state->io);
-}
-
-/**
- * acpi_memory_slot_status:
- * @mem_st: memory hotplug state
- * @dev: device
- * @errp: set in case of an error
- *
- * Obtain a single memory slot status.
- *
- * This function will be called by memory unplug request cb and unplug cb.
- */
-static MemStatus *
-acpi_memory_slot_status(MemHotplugState *mem_st,
- DeviceState *dev, Error **errp)
-{
- Error *local_err = NULL;
- int slot = object_property_get_int(OBJECT(dev), PC_DIMM_SLOT_PROP,
- &local_err);
-
- if (local_err) {
- error_propagate(errp, local_err);
- return NULL;
- }
-
- if (slot >= mem_st->dev_count) {
- char *dev_path = object_get_canonical_path(OBJECT(dev));
- error_setg(errp, "acpi_memory_slot_status: "
- "device [%s] returned invalid memory slot[%d]",
- dev_path, slot);
- g_free(dev_path);
- return NULL;
- }
-
- return &mem_st->devs[slot];
-}
-
-void acpi_memory_plug_cb(ACPIREGS *ar, qemu_irq irq, MemHotplugState *mem_st,
- DeviceState *dev, Error **errp)
-{
- MemStatus *mdev;
- DeviceClass *dc = DEVICE_GET_CLASS(dev);
-
- if (!dc->hotpluggable) {
- return;
- }
-
- mdev = acpi_memory_slot_status(mem_st, dev, errp);
- if (!mdev) {
- return;
- }
-
- mdev->dimm = dev;
- mdev->is_enabled = true;
- if (dev->hotplugged) {
- mdev->is_inserting = true;
-
- /* do ACPI magic */
- acpi_send_gpe_event(ar, irq, ACPI_MEMORY_HOTPLUG_STATUS);
- }
-}
-
-void acpi_memory_unplug_request_cb(ACPIREGS *ar, qemu_irq irq,
- MemHotplugState *mem_st,
- DeviceState *dev, Error **errp)
-{
- MemStatus *mdev;
-
- mdev = acpi_memory_slot_status(mem_st, dev, errp);
- if (!mdev) {
- return;
- }
-
- mdev->is_removing = true;
-
- /* Do ACPI magic */
- acpi_send_gpe_event(ar, irq, ACPI_MEMORY_HOTPLUG_STATUS);
-}
-
-void acpi_memory_unplug_cb(MemHotplugState *mem_st,
- DeviceState *dev, Error **errp)
-{
- MemStatus *mdev;
-
- mdev = acpi_memory_slot_status(mem_st, dev, errp);
- if (!mdev) {
- return;
- }
-
- mdev->is_enabled = false;
- mdev->dimm = NULL;
-}
-
-static const VMStateDescription vmstate_memhp_sts = {
- .name = "memory hotplug device state",
- .version_id = 1,
- .minimum_version_id = 1,
- .minimum_version_id_old = 1,
- .fields = (VMStateField[]) {
- VMSTATE_BOOL(is_enabled, MemStatus),
- VMSTATE_BOOL(is_inserting, MemStatus),
- VMSTATE_UINT32(ost_event, MemStatus),
- VMSTATE_UINT32(ost_status, MemStatus),
- VMSTATE_END_OF_LIST()
- }
-};
-
-const VMStateDescription vmstate_memory_hotplug = {
- .name = "memory hotplug state",
- .version_id = 1,
- .minimum_version_id = 1,
- .minimum_version_id_old = 1,
- .fields = (VMStateField[]) {
- VMSTATE_UINT32(selector, MemHotplugState),
- VMSTATE_STRUCT_VARRAY_POINTER_UINT32(devs, MemHotplugState, dev_count,
- vmstate_memhp_sts, MemStatus),
- VMSTATE_END_OF_LIST()
- }
-};
diff --git a/qemu/hw/acpi/memory_hotplug_acpi_table.c b/qemu/hw/acpi/memory_hotplug_acpi_table.c
deleted file mode 100644
index c75660215..000000000
--- a/qemu/hw/acpi/memory_hotplug_acpi_table.c
+++ /dev/null
@@ -1,262 +0,0 @@
-/*
- * Memory hotplug AML code of DSDT ACPI table
- *
- * Copyright (C) 2015 Red Hat Inc
- *
- * Author: Igor Mammedov <imammedo@redhat.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-
-#include "qemu/osdep.h"
-#include "hw/acpi/memory_hotplug.h"
-#include "include/hw/acpi/pc-hotplug.h"
-#include "hw/boards.h"
-
-void build_memory_hotplug_aml(Aml *ctx, uint32_t nr_mem,
- uint16_t io_base, uint16_t io_len)
-{
- Aml *ifctx;
- Aml *method;
- Aml *pci_scope;
- Aml *mem_ctrl_dev;
-
- /* scope for memory hotplug controller device node */
- pci_scope = aml_scope("_SB.PCI0");
- mem_ctrl_dev = aml_device(MEMORY_HOTPLUG_DEVICE);
- {
- Aml *one = aml_int(1);
- Aml *zero = aml_int(0);
- Aml *ret_val = aml_local(0);
- Aml *slot_arg0 = aml_arg(0);
- Aml *slots_nr = aml_name(MEMORY_SLOTS_NUMBER);
- Aml *ctrl_lock = aml_name(MEMORY_SLOT_LOCK);
- Aml *slot_selector = aml_name(MEMORY_SLOT_SLECTOR);
-
- aml_append(mem_ctrl_dev, aml_name_decl("_HID", aml_string("PNP0A06")));
- aml_append(mem_ctrl_dev,
- aml_name_decl("_UID", aml_string("Memory hotplug resources")));
-
- method = aml_method("_STA", 0, AML_NOTSERIALIZED);
- ifctx = aml_if(aml_equal(slots_nr, zero));
- {
- aml_append(ifctx, aml_return(zero));
- }
- aml_append(method, ifctx);
- /* present, functioning, decoding, not shown in UI */
- aml_append(method, aml_return(aml_int(0xB)));
- aml_append(mem_ctrl_dev, method);
-
- aml_append(mem_ctrl_dev, aml_mutex(MEMORY_SLOT_LOCK, 0));
-
- method = aml_method(MEMORY_SLOT_SCAN_METHOD, 0, AML_NOTSERIALIZED);
- {
- Aml *else_ctx;
- Aml *while_ctx;
- Aml *idx = aml_local(0);
- Aml *eject_req = aml_int(3);
- Aml *dev_chk = aml_int(1);
-
- ifctx = aml_if(aml_equal(slots_nr, zero));
- {
- aml_append(ifctx, aml_return(zero));
- }
- aml_append(method, ifctx);
-
- aml_append(method, aml_store(zero, idx));
- aml_append(method, aml_acquire(ctrl_lock, 0xFFFF));
- /* build AML that:
- * loops over all slots and Notifies DIMMs with
- * Device Check or Eject Request notifications if
- * slot has corresponding status bit set and clears
- * slot status.
- */
- while_ctx = aml_while(aml_lless(idx, slots_nr));
- {
- Aml *ins_evt = aml_name(MEMORY_SLOT_INSERT_EVENT);
- Aml *rm_evt = aml_name(MEMORY_SLOT_REMOVE_EVENT);
-
- aml_append(while_ctx, aml_store(idx, slot_selector));
- ifctx = aml_if(aml_equal(ins_evt, one));
- {
- aml_append(ifctx,
- aml_call2(MEMORY_SLOT_NOTIFY_METHOD,
- idx, dev_chk));
- aml_append(ifctx, aml_store(one, ins_evt));
- }
- aml_append(while_ctx, ifctx);
-
- else_ctx = aml_else();
- ifctx = aml_if(aml_equal(rm_evt, one));
- {
- aml_append(ifctx,
- aml_call2(MEMORY_SLOT_NOTIFY_METHOD,
- idx, eject_req));
- aml_append(ifctx, aml_store(one, rm_evt));
- }
- aml_append(else_ctx, ifctx);
- aml_append(while_ctx, else_ctx);
-
- aml_append(while_ctx, aml_add(idx, one, idx));
- }
- aml_append(method, while_ctx);
- aml_append(method, aml_release(ctrl_lock));
- aml_append(method, aml_return(one));
- }
- aml_append(mem_ctrl_dev, method);
-
- method = aml_method(MEMORY_SLOT_STATUS_METHOD, 1, AML_NOTSERIALIZED);
- {
- Aml *slot_enabled = aml_name(MEMORY_SLOT_ENABLED);
-
- aml_append(method, aml_store(zero, ret_val));
- aml_append(method, aml_acquire(ctrl_lock, 0xFFFF));
- aml_append(method,
- aml_store(aml_to_integer(slot_arg0), slot_selector));
-
- ifctx = aml_if(aml_equal(slot_enabled, one));
- {
- aml_append(ifctx, aml_store(aml_int(0xF), ret_val));
- }
- aml_append(method, ifctx);
-
- aml_append(method, aml_release(ctrl_lock));
- aml_append(method, aml_return(ret_val));
- }
- aml_append(mem_ctrl_dev, method);
-
- method = aml_method(MEMORY_SLOT_CRS_METHOD, 1, AML_SERIALIZED);
- {
- Aml *mr64 = aml_name("MR64");
- Aml *mr32 = aml_name("MR32");
- Aml *crs_tmpl = aml_resource_template();
- Aml *minl = aml_name("MINL");
- Aml *minh = aml_name("MINH");
- Aml *maxl = aml_name("MAXL");
- Aml *maxh = aml_name("MAXH");
- Aml *lenl = aml_name("LENL");
- Aml *lenh = aml_name("LENH");
-
- aml_append(method, aml_acquire(ctrl_lock, 0xFFFF));
- aml_append(method, aml_store(aml_to_integer(slot_arg0),
- slot_selector));
-
- aml_append(crs_tmpl,
- aml_qword_memory(AML_POS_DECODE, AML_MIN_FIXED, AML_MAX_FIXED,
- AML_CACHEABLE, AML_READ_WRITE,
- 0, 0x0, 0xFFFFFFFFFFFFFFFEULL, 0,
- 0xFFFFFFFFFFFFFFFFULL));
- aml_append(method, aml_name_decl("MR64", crs_tmpl));
- aml_append(method,
- aml_create_dword_field(mr64, aml_int(14), "MINL"));
- aml_append(method,
- aml_create_dword_field(mr64, aml_int(18), "MINH"));
- aml_append(method,
- aml_create_dword_field(mr64, aml_int(38), "LENL"));
- aml_append(method,
- aml_create_dword_field(mr64, aml_int(42), "LENH"));
- aml_append(method,
- aml_create_dword_field(mr64, aml_int(22), "MAXL"));
- aml_append(method,
- aml_create_dword_field(mr64, aml_int(26), "MAXH"));
-
- aml_append(method,
- aml_store(aml_name(MEMORY_SLOT_ADDR_HIGH), minh));
- aml_append(method,
- aml_store(aml_name(MEMORY_SLOT_ADDR_LOW), minl));
- aml_append(method,
- aml_store(aml_name(MEMORY_SLOT_SIZE_HIGH), lenh));
- aml_append(method,
- aml_store(aml_name(MEMORY_SLOT_SIZE_LOW), lenl));
-
- /* 64-bit math: MAX = MIN + LEN - 1 */
- aml_append(method, aml_add(minl, lenl, maxl));
- aml_append(method, aml_add(minh, lenh, maxh));
- ifctx = aml_if(aml_lless(maxl, minl));
- {
- aml_append(ifctx, aml_add(maxh, one, maxh));
- }
- aml_append(method, ifctx);
- ifctx = aml_if(aml_lless(maxl, one));
- {
- aml_append(ifctx, aml_subtract(maxh, one, maxh));
- }
- aml_append(method, ifctx);
- aml_append(method, aml_subtract(maxl, one, maxl));
-
- /* return 32-bit _CRS if addr/size is in low mem */
- /* TODO: remove it since all hotplugged DIMMs are in high mem */
- ifctx = aml_if(aml_equal(maxh, zero));
- {
- crs_tmpl = aml_resource_template();
- aml_append(crs_tmpl,
- aml_dword_memory(AML_POS_DECODE, AML_MIN_FIXED,
- AML_MAX_FIXED, AML_CACHEABLE,
- AML_READ_WRITE,
- 0, 0x0, 0xFFFFFFFE, 0,
- 0xFFFFFFFF));
- aml_append(ifctx, aml_name_decl("MR32", crs_tmpl));
- aml_append(ifctx,
- aml_create_dword_field(mr32, aml_int(10), "MIN"));
- aml_append(ifctx,
- aml_create_dword_field(mr32, aml_int(14), "MAX"));
- aml_append(ifctx,
- aml_create_dword_field(mr32, aml_int(22), "LEN"));
- aml_append(ifctx, aml_store(minl, aml_name("MIN")));
- aml_append(ifctx, aml_store(maxl, aml_name("MAX")));
- aml_append(ifctx, aml_store(lenl, aml_name("LEN")));
-
- aml_append(ifctx, aml_release(ctrl_lock));
- aml_append(ifctx, aml_return(mr32));
- }
- aml_append(method, ifctx);
-
- aml_append(method, aml_release(ctrl_lock));
- aml_append(method, aml_return(mr64));
- }
- aml_append(mem_ctrl_dev, method);
-
- method = aml_method(MEMORY_SLOT_PROXIMITY_METHOD, 1,
- AML_NOTSERIALIZED);
- {
- Aml *proximity = aml_name(MEMORY_SLOT_PROXIMITY);
-
- aml_append(method, aml_acquire(ctrl_lock, 0xFFFF));
- aml_append(method, aml_store(aml_to_integer(slot_arg0),
- slot_selector));
- aml_append(method, aml_store(proximity, ret_val));
- aml_append(method, aml_release(ctrl_lock));
- aml_append(method, aml_return(ret_val));
- }
- aml_append(mem_ctrl_dev, method);
-
- method = aml_method(MEMORY_SLOT_OST_METHOD, 4, AML_NOTSERIALIZED);
- {
- Aml *ost_evt = aml_name(MEMORY_SLOT_OST_EVENT);
- Aml *ost_status = aml_name(MEMORY_SLOT_OST_STATUS);
-
- aml_append(method, aml_acquire(ctrl_lock, 0xFFFF));
- aml_append(method, aml_store(aml_to_integer(slot_arg0),
- slot_selector));
- aml_append(method, aml_store(aml_arg(1), ost_evt));
- aml_append(method, aml_store(aml_arg(2), ost_status));
- aml_append(method, aml_release(ctrl_lock));
- }
- aml_append(mem_ctrl_dev, method);
-
- method = aml_method(MEMORY_SLOT_EJECT_METHOD, 2, AML_NOTSERIALIZED);
- {
- Aml *eject = aml_name(MEMORY_SLOT_EJECT);
-
- aml_append(method, aml_acquire(ctrl_lock, 0xFFFF));
- aml_append(method, aml_store(aml_to_integer(slot_arg0),
- slot_selector));
- aml_append(method, aml_store(one, eject));
- aml_append(method, aml_release(ctrl_lock));
- }
- aml_append(mem_ctrl_dev, method);
- }
- aml_append(pci_scope, mem_ctrl_dev);
- aml_append(ctx, pci_scope);
-}
diff --git a/qemu/hw/acpi/nvdimm.c b/qemu/hw/acpi/nvdimm.c
deleted file mode 100644
index 9531340e5..000000000
--- a/qemu/hw/acpi/nvdimm.c
+++ /dev/null
@@ -1,706 +0,0 @@
-/*
- * NVDIMM ACPI Implementation
- *
- * Copyright(C) 2015 Intel Corporation.
- *
- * Author:
- * Xiao Guangrong <guangrong.xiao@linux.intel.com>
- *
- * NFIT is defined in ACPI 6.0: 5.2.25 NVDIMM Firmware Interface Table (NFIT)
- * and the DSM specification can be found at:
- * http://pmem.io/documents/NVDIMM_DSM_Interface_Example.pdf
- *
- * Currently, it only supports PMEM Virtualization.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see <http://www.gnu.org/licenses/>
- */
-
-#include "qemu/osdep.h"
-#include "hw/acpi/acpi.h"
-#include "hw/acpi/aml-build.h"
-#include "hw/acpi/bios-linker-loader.h"
-#include "hw/nvram/fw_cfg.h"
-#include "hw/mem/nvdimm.h"
-
-static int nvdimm_plugged_device_list(Object *obj, void *opaque)
-{
- GSList **list = opaque;
-
- if (object_dynamic_cast(obj, TYPE_NVDIMM)) {
- DeviceState *dev = DEVICE(obj);
-
- if (dev->realized) { /* only realized NVDIMMs matter */
- *list = g_slist_append(*list, DEVICE(obj));
- }
- }
-
- object_child_foreach(obj, nvdimm_plugged_device_list, opaque);
- return 0;
-}
-
-/*
- * inquire plugged NVDIMM devices and link them into the list which is
- * returned to the caller.
- *
- * Note: it is the caller's responsibility to free the list to avoid
- * memory leak.
- */
-static GSList *nvdimm_get_plugged_device_list(void)
-{
- GSList *list = NULL;
-
- object_child_foreach(qdev_get_machine(), nvdimm_plugged_device_list,
- &list);
- return list;
-}
-
-#define NVDIMM_UUID_LE(a, b, c, d0, d1, d2, d3, d4, d5, d6, d7) \
- { (a) & 0xff, ((a) >> 8) & 0xff, ((a) >> 16) & 0xff, ((a) >> 24) & 0xff, \
- (b) & 0xff, ((b) >> 8) & 0xff, (c) & 0xff, ((c) >> 8) & 0xff, \
- (d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) }
-
-/*
- * define Byte Addressable Persistent Memory (PM) Region according to
- * ACPI 6.0: 5.2.25.1 System Physical Address Range Structure.
- */
-static const uint8_t nvdimm_nfit_spa_uuid[] =
- NVDIMM_UUID_LE(0x66f0d379, 0xb4f3, 0x4074, 0xac, 0x43, 0x0d, 0x33,
- 0x18, 0xb7, 0x8c, 0xdb);
-
-/*
- * NVDIMM Firmware Interface Table
- * @signature: "NFIT"
- *
- * It provides information that allows OSPM to enumerate NVDIMM present in
- * the platform and associate system physical address ranges created by the
- * NVDIMMs.
- *
- * It is defined in ACPI 6.0: 5.2.25 NVDIMM Firmware Interface Table (NFIT)
- */
-struct NvdimmNfitHeader {
- ACPI_TABLE_HEADER_DEF
- uint32_t reserved;
-} QEMU_PACKED;
-typedef struct NvdimmNfitHeader NvdimmNfitHeader;
-
-/*
- * define NFIT structures according to ACPI 6.0: 5.2.25 NVDIMM Firmware
- * Interface Table (NFIT).
- */
-
-/*
- * System Physical Address Range Structure
- *
- * It describes the system physical address ranges occupied by NVDIMMs and
- * the types of the regions.
- */
-struct NvdimmNfitSpa {
- uint16_t type;
- uint16_t length;
- uint16_t spa_index;
- uint16_t flags;
- uint32_t reserved;
- uint32_t proximity_domain;
- uint8_t type_guid[16];
- uint64_t spa_base;
- uint64_t spa_length;
- uint64_t mem_attr;
-} QEMU_PACKED;
-typedef struct NvdimmNfitSpa NvdimmNfitSpa;
-
-/*
- * Memory Device to System Physical Address Range Mapping Structure
- *
- * It enables identifying each NVDIMM region and the corresponding SPA
- * describing the memory interleave
- */
-struct NvdimmNfitMemDev {
- uint16_t type;
- uint16_t length;
- uint32_t nfit_handle;
- uint16_t phys_id;
- uint16_t region_id;
- uint16_t spa_index;
- uint16_t dcr_index;
- uint64_t region_len;
- uint64_t region_offset;
- uint64_t region_dpa;
- uint16_t interleave_index;
- uint16_t interleave_ways;
- uint16_t flags;
- uint16_t reserved;
-} QEMU_PACKED;
-typedef struct NvdimmNfitMemDev NvdimmNfitMemDev;
-
-/*
- * NVDIMM Control Region Structure
- *
- * It describes the NVDIMM and if applicable, Block Control Window.
- */
-struct NvdimmNfitControlRegion {
- uint16_t type;
- uint16_t length;
- uint16_t dcr_index;
- uint16_t vendor_id;
- uint16_t device_id;
- uint16_t revision_id;
- uint16_t sub_vendor_id;
- uint16_t sub_device_id;
- uint16_t sub_revision_id;
- uint8_t reserved[6];
- uint32_t serial_number;
- uint16_t fic;
- uint16_t num_bcw;
- uint64_t bcw_size;
- uint64_t cmd_offset;
- uint64_t cmd_size;
- uint64_t status_offset;
- uint64_t status_size;
- uint16_t flags;
- uint8_t reserved2[6];
-} QEMU_PACKED;
-typedef struct NvdimmNfitControlRegion NvdimmNfitControlRegion;
-
-/*
- * Module serial number is a unique number for each device. We use the
- * slot id of NVDIMM device to generate this number so that each device
- * associates with a different number.
- *
- * 0x123456 is a magic number we arbitrarily chose.
- */
-static uint32_t nvdimm_slot_to_sn(int slot)
-{
- return 0x123456 + slot;
-}
-
-/*
- * handle is used to uniquely associate nfit_memdev structure with NVDIMM
- * ACPI device - nfit_memdev.nfit_handle matches with the value returned
- * by ACPI device _ADR method.
- *
- * We generate the handle with the slot id of NVDIMM device and reserve
- * 0 for NVDIMM root device.
- */
-static uint32_t nvdimm_slot_to_handle(int slot)
-{
- return slot + 1;
-}
-
-/*
- * index uniquely identifies the structure, 0 is reserved which indicates
- * that the structure is not valid or the associated structure is not
- * present.
- *
- * Each NVDIMM device needs two indexes, one for nfit_spa and another for
- * nfit_dc which are generated by the slot id of NVDIMM device.
- */
-static uint16_t nvdimm_slot_to_spa_index(int slot)
-{
- return (slot + 1) << 1;
-}
-
-/* See the comments of nvdimm_slot_to_spa_index(). */
-static uint32_t nvdimm_slot_to_dcr_index(int slot)
-{
- return nvdimm_slot_to_spa_index(slot) + 1;
-}
-
-/* ACPI 6.0: 5.2.25.1 System Physical Address Range Structure */
-static void
-nvdimm_build_structure_spa(GArray *structures, DeviceState *dev)
-{
- NvdimmNfitSpa *nfit_spa;
- uint64_t addr = object_property_get_int(OBJECT(dev), PC_DIMM_ADDR_PROP,
- NULL);
- uint64_t size = object_property_get_int(OBJECT(dev), PC_DIMM_SIZE_PROP,
- NULL);
- uint32_t node = object_property_get_int(OBJECT(dev), PC_DIMM_NODE_PROP,
- NULL);
- int slot = object_property_get_int(OBJECT(dev), PC_DIMM_SLOT_PROP,
- NULL);
-
- nfit_spa = acpi_data_push(structures, sizeof(*nfit_spa));
-
- nfit_spa->type = cpu_to_le16(0 /* System Physical Address Range
- Structure */);
- nfit_spa->length = cpu_to_le16(sizeof(*nfit_spa));
- nfit_spa->spa_index = cpu_to_le16(nvdimm_slot_to_spa_index(slot));
-
- /*
- * Control region is strict as all the device info, such as SN, index,
- * is associated with slot id.
- */
- nfit_spa->flags = cpu_to_le16(1 /* Control region is strictly for
- management during hot add/online
- operation */ |
- 2 /* Data in Proximity Domain field is
- valid*/);
-
- /* NUMA node. */
- nfit_spa->proximity_domain = cpu_to_le32(node);
- /* the region reported as PMEM. */
- memcpy(nfit_spa->type_guid, nvdimm_nfit_spa_uuid,
- sizeof(nvdimm_nfit_spa_uuid));
-
- nfit_spa->spa_base = cpu_to_le64(addr);
- nfit_spa->spa_length = cpu_to_le64(size);
-
- /* It is the PMEM and can be cached as writeback. */
- nfit_spa->mem_attr = cpu_to_le64(0x8ULL /* EFI_MEMORY_WB */ |
- 0x8000ULL /* EFI_MEMORY_NV */);
-}
-
-/*
- * ACPI 6.0: 5.2.25.2 Memory Device to System Physical Address Range Mapping
- * Structure
- */
-static void
-nvdimm_build_structure_memdev(GArray *structures, DeviceState *dev)
-{
- NvdimmNfitMemDev *nfit_memdev;
- uint64_t addr = object_property_get_int(OBJECT(dev), PC_DIMM_ADDR_PROP,
- NULL);
- uint64_t size = object_property_get_int(OBJECT(dev), PC_DIMM_SIZE_PROP,
- NULL);
- int slot = object_property_get_int(OBJECT(dev), PC_DIMM_SLOT_PROP,
- NULL);
- uint32_t handle = nvdimm_slot_to_handle(slot);
-
- nfit_memdev = acpi_data_push(structures, sizeof(*nfit_memdev));
-
- nfit_memdev->type = cpu_to_le16(1 /* Memory Device to System Address
- Range Map Structure*/);
- nfit_memdev->length = cpu_to_le16(sizeof(*nfit_memdev));
- nfit_memdev->nfit_handle = cpu_to_le32(handle);
-
- /*
- * associate memory device with System Physical Address Range
- * Structure.
- */
- nfit_memdev->spa_index = cpu_to_le16(nvdimm_slot_to_spa_index(slot));
- /* associate memory device with Control Region Structure. */
- nfit_memdev->dcr_index = cpu_to_le16(nvdimm_slot_to_dcr_index(slot));
-
- /* The memory region on the device. */
- nfit_memdev->region_len = cpu_to_le64(size);
- nfit_memdev->region_dpa = cpu_to_le64(addr);
-
- /* Only one interleave for PMEM. */
- nfit_memdev->interleave_ways = cpu_to_le16(1);
-}
-
-/*
- * ACPI 6.0: 5.2.25.5 NVDIMM Control Region Structure.
- */
-static void nvdimm_build_structure_dcr(GArray *structures, DeviceState *dev)
-{
- NvdimmNfitControlRegion *nfit_dcr;
- int slot = object_property_get_int(OBJECT(dev), PC_DIMM_SLOT_PROP,
- NULL);
- uint32_t sn = nvdimm_slot_to_sn(slot);
-
- nfit_dcr = acpi_data_push(structures, sizeof(*nfit_dcr));
-
- nfit_dcr->type = cpu_to_le16(4 /* NVDIMM Control Region Structure */);
- nfit_dcr->length = cpu_to_le16(sizeof(*nfit_dcr));
- nfit_dcr->dcr_index = cpu_to_le16(nvdimm_slot_to_dcr_index(slot));
-
- /* vendor: Intel. */
- nfit_dcr->vendor_id = cpu_to_le16(0x8086);
- nfit_dcr->device_id = cpu_to_le16(1);
-
- /* The _DSM method is following Intel's DSM specification. */
- nfit_dcr->revision_id = cpu_to_le16(1 /* Current Revision supported
- in ACPI 6.0 is 1. */);
- nfit_dcr->serial_number = cpu_to_le32(sn);
- nfit_dcr->fic = cpu_to_le16(0x201 /* Format Interface Code. See Chapter
- 2: NVDIMM Device Specific Method
- (DSM) in DSM Spec Rev1.*/);
-}
-
-static GArray *nvdimm_build_device_structure(GSList *device_list)
-{
- GArray *structures = g_array_new(false, true /* clear */, 1);
-
- for (; device_list; device_list = device_list->next) {
- DeviceState *dev = device_list->data;
-
- /* build System Physical Address Range Structure. */
- nvdimm_build_structure_spa(structures, dev);
-
- /*
- * build Memory Device to System Physical Address Range Mapping
- * Structure.
- */
- nvdimm_build_structure_memdev(structures, dev);
-
- /* build NVDIMM Control Region Structure. */
- nvdimm_build_structure_dcr(structures, dev);
- }
-
- return structures;
-}
-
-static void nvdimm_build_nfit(GSList *device_list, GArray *table_offsets,
- GArray *table_data, GArray *linker)
-{
- GArray *structures = nvdimm_build_device_structure(device_list);
- unsigned int header;
-
- acpi_add_table(table_offsets, table_data);
-
- /* NFIT header. */
- header = table_data->len;
- acpi_data_push(table_data, sizeof(NvdimmNfitHeader));
- /* NVDIMM device structures. */
- g_array_append_vals(table_data, structures->data, structures->len);
-
- build_header(linker, table_data,
- (void *)(table_data->data + header), "NFIT",
- sizeof(NvdimmNfitHeader) + structures->len, 1, NULL, NULL);
- g_array_free(structures, true);
-}
-
-struct NvdimmDsmIn {
- uint32_t handle;
- uint32_t revision;
- uint32_t function;
- /* the remaining size in the page is used by arg3. */
- union {
- uint8_t arg3[0];
- };
-} QEMU_PACKED;
-typedef struct NvdimmDsmIn NvdimmDsmIn;
-
-struct NvdimmDsmOut {
- /* the size of buffer filled by QEMU. */
- uint32_t len;
- uint8_t data[0];
-} QEMU_PACKED;
-typedef struct NvdimmDsmOut NvdimmDsmOut;
-
-struct NvdimmDsmFunc0Out {
- /* the size of buffer filled by QEMU. */
- uint32_t len;
- uint32_t supported_func;
-} QEMU_PACKED;
-typedef struct NvdimmDsmFunc0Out NvdimmDsmFunc0Out;
-
-struct NvdimmDsmFuncNoPayloadOut {
- /* the size of buffer filled by QEMU. */
- uint32_t len;
- uint32_t func_ret_status;
-} QEMU_PACKED;
-typedef struct NvdimmDsmFuncNoPayloadOut NvdimmDsmFuncNoPayloadOut;
-
-static uint64_t
-nvdimm_dsm_read(void *opaque, hwaddr addr, unsigned size)
-{
- nvdimm_debug("BUG: we never read _DSM IO Port.\n");
- return 0;
-}
-
-static void
-nvdimm_dsm_write(void *opaque, hwaddr addr, uint64_t val, unsigned size)
-{
- NvdimmDsmIn *in;
- hwaddr dsm_mem_addr = val;
-
- nvdimm_debug("dsm memory address %#" HWADDR_PRIx ".\n", dsm_mem_addr);
-
- /*
- * The DSM memory is mapped to guest address space so an evil guest
- * can change its content while we are doing DSM emulation. Avoid
- * this by copying DSM memory to QEMU local memory.
- */
- in = g_malloc(TARGET_PAGE_SIZE);
- cpu_physical_memory_read(dsm_mem_addr, in, TARGET_PAGE_SIZE);
-
- le32_to_cpus(&in->revision);
- le32_to_cpus(&in->function);
- le32_to_cpus(&in->handle);
-
- nvdimm_debug("Revision %#x Handler %#x Function %#x.\n", in->revision,
- in->handle, in->function);
-
- /*
- * function 0 is called to inquire which functions are supported by
- * OSPM
- */
- if (in->function == 0) {
- NvdimmDsmFunc0Out func0 = {
- .len = cpu_to_le32(sizeof(func0)),
- /* No function supported other than function 0 */
- .supported_func = cpu_to_le32(0),
- };
- cpu_physical_memory_write(dsm_mem_addr, &func0, sizeof func0);
- } else {
- /* No function except function 0 is supported yet. */
- NvdimmDsmFuncNoPayloadOut out = {
- .len = cpu_to_le32(sizeof(out)),
- .func_ret_status = cpu_to_le32(1) /* Not Supported */,
- };
- cpu_physical_memory_write(dsm_mem_addr, &out, sizeof(out));
- }
-
- g_free(in);
-}
-
-static const MemoryRegionOps nvdimm_dsm_ops = {
- .read = nvdimm_dsm_read,
- .write = nvdimm_dsm_write,
- .endianness = DEVICE_LITTLE_ENDIAN,
- .valid = {
- .min_access_size = 4,
- .max_access_size = 4,
- },
-};
-
-void nvdimm_init_acpi_state(AcpiNVDIMMState *state, MemoryRegion *io,
- FWCfgState *fw_cfg, Object *owner)
-{
- memory_region_init_io(&state->io_mr, owner, &nvdimm_dsm_ops, state,
- "nvdimm-acpi-io", NVDIMM_ACPI_IO_LEN);
- memory_region_add_subregion(io, NVDIMM_ACPI_IO_BASE, &state->io_mr);
-
- state->dsm_mem = g_array_new(false, true /* clear */, 1);
- acpi_data_push(state->dsm_mem, TARGET_PAGE_SIZE);
- fw_cfg_add_file(fw_cfg, NVDIMM_DSM_MEM_FILE, state->dsm_mem->data,
- state->dsm_mem->len);
-}
-
-#define NVDIMM_COMMON_DSM "NCAL"
-#define NVDIMM_ACPI_MEM_ADDR "MEMA"
-
-static void nvdimm_build_common_dsm(Aml *dev)
-{
- Aml *method, *ifctx, *function, *dsm_mem, *unpatched, *result_size;
- uint8_t byte_list[1];
-
- method = aml_method(NVDIMM_COMMON_DSM, 4, AML_SERIALIZED);
- function = aml_arg(2);
- dsm_mem = aml_name(NVDIMM_ACPI_MEM_ADDR);
-
- /*
- * do not support any method if DSM memory address has not been
- * patched.
- */
- unpatched = aml_if(aml_equal(dsm_mem, aml_int(0x0)));
-
- /*
- * function 0 is called to inquire what functions are supported by
- * OSPM
- */
- ifctx = aml_if(aml_equal(function, aml_int(0)));
- byte_list[0] = 0 /* No function Supported */;
- aml_append(ifctx, aml_return(aml_buffer(1, byte_list)));
- aml_append(unpatched, ifctx);
-
- /* No function is supported yet. */
- byte_list[0] = 1 /* Not Supported */;
- aml_append(unpatched, aml_return(aml_buffer(1, byte_list)));
- aml_append(method, unpatched);
-
- /*
- * The HDLE indicates the DSM function is issued from which device,
- * it is not used at this time as no function is supported yet.
- * Currently we make it always be 0 for all the devices and will set
- * the appropriate value once real function is implemented.
- */
- aml_append(method, aml_store(aml_int(0x0), aml_name("HDLE")));
- aml_append(method, aml_store(aml_arg(1), aml_name("REVS")));
- aml_append(method, aml_store(aml_arg(2), aml_name("FUNC")));
-
- /*
- * tell QEMU about the real address of DSM memory, then QEMU
- * gets the control and fills the result in DSM memory.
- */
- aml_append(method, aml_store(dsm_mem, aml_name("NTFI")));
-
- result_size = aml_local(1);
- aml_append(method, aml_store(aml_name("RLEN"), result_size));
- aml_append(method, aml_store(aml_shiftleft(result_size, aml_int(3)),
- result_size));
- aml_append(method, aml_create_field(aml_name("ODAT"), aml_int(0),
- result_size, "OBUF"));
- aml_append(method, aml_concatenate(aml_buffer(0, NULL), aml_name("OBUF"),
- aml_arg(6)));
- aml_append(method, aml_return(aml_arg(6)));
- aml_append(dev, method);
-}
-
-static void nvdimm_build_device_dsm(Aml *dev)
-{
- Aml *method;
-
- method = aml_method("_DSM", 4, AML_NOTSERIALIZED);
- aml_append(method, aml_return(aml_call4(NVDIMM_COMMON_DSM, aml_arg(0),
- aml_arg(1), aml_arg(2), aml_arg(3))));
- aml_append(dev, method);
-}
-
-static void nvdimm_build_nvdimm_devices(GSList *device_list, Aml *root_dev)
-{
- for (; device_list; device_list = device_list->next) {
- DeviceState *dev = device_list->data;
- int slot = object_property_get_int(OBJECT(dev), PC_DIMM_SLOT_PROP,
- NULL);
- uint32_t handle = nvdimm_slot_to_handle(slot);
- Aml *nvdimm_dev;
-
- nvdimm_dev = aml_device("NV%02X", slot);
-
- /*
- * ACPI 6.0: 9.20 NVDIMM Devices:
- *
- * _ADR object that is used to supply OSPM with unique address
- * of the NVDIMM device. This is done by returning the NFIT Device
- * handle that is used to identify the associated entries in ACPI
- * table NFIT or _FIT.
- */
- aml_append(nvdimm_dev, aml_name_decl("_ADR", aml_int(handle)));
-
- nvdimm_build_device_dsm(nvdimm_dev);
- aml_append(root_dev, nvdimm_dev);
- }
-}
-
-static void nvdimm_build_ssdt(GSList *device_list, GArray *table_offsets,
- GArray *table_data, GArray *linker)
-{
- Aml *ssdt, *sb_scope, *dev, *field;
- int mem_addr_offset, nvdimm_ssdt;
-
- acpi_add_table(table_offsets, table_data);
-
- ssdt = init_aml_allocator();
- acpi_data_push(ssdt->buf, sizeof(AcpiTableHeader));
-
- sb_scope = aml_scope("\\_SB");
-
- dev = aml_device("NVDR");
-
- /*
- * ACPI 6.0: 9.20 NVDIMM Devices:
- *
- * The ACPI Name Space device uses _HID of ACPI0012 to identify the root
- * NVDIMM interface device. Platform firmware is required to contain one
- * such device in _SB scope if NVDIMMs support is exposed by platform to
- * OSPM.
- * For each NVDIMM present or intended to be supported by platform,
- * platform firmware also exposes an ACPI Namespace Device under the
- * root device.
- */
- aml_append(dev, aml_name_decl("_HID", aml_string("ACPI0012")));
-
- /* map DSM memory and IO into ACPI namespace. */
- aml_append(dev, aml_operation_region("NPIO", AML_SYSTEM_IO,
- aml_int(NVDIMM_ACPI_IO_BASE), NVDIMM_ACPI_IO_LEN));
- aml_append(dev, aml_operation_region("NRAM", AML_SYSTEM_MEMORY,
- aml_name(NVDIMM_ACPI_MEM_ADDR), TARGET_PAGE_SIZE));
-
- /*
- * DSM notifier:
- * NTFI: write the address of DSM memory and notify QEMU to emulate
- * the access.
- *
- * It is the IO port so that accessing them will cause VM-exit, the
- * control will be transferred to QEMU.
- */
- field = aml_field("NPIO", AML_DWORD_ACC, AML_NOLOCK, AML_PRESERVE);
- aml_append(field, aml_named_field("NTFI",
- sizeof(uint32_t) * BITS_PER_BYTE));
- aml_append(dev, field);
-
- /*
- * DSM input:
- * HDLE: store device's handle, it's zero if the _DSM call happens
- * on NVDIMM Root Device.
- * REVS: store the Arg1 of _DSM call.
- * FUNC: store the Arg2 of _DSM call.
- * ARG3: store the Arg3 of _DSM call.
- *
- * They are RAM mapping on host so that these accesses never cause
- * VM-EXIT.
- */
- field = aml_field("NRAM", AML_DWORD_ACC, AML_NOLOCK, AML_PRESERVE);
- aml_append(field, aml_named_field("HDLE",
- sizeof(typeof_field(NvdimmDsmIn, handle)) * BITS_PER_BYTE));
- aml_append(field, aml_named_field("REVS",
- sizeof(typeof_field(NvdimmDsmIn, revision)) * BITS_PER_BYTE));
- aml_append(field, aml_named_field("FUNC",
- sizeof(typeof_field(NvdimmDsmIn, function)) * BITS_PER_BYTE));
- aml_append(field, aml_named_field("ARG3",
- (TARGET_PAGE_SIZE - offsetof(NvdimmDsmIn, arg3)) *
- BITS_PER_BYTE));
- aml_append(dev, field);
-
- /*
- * DSM output:
- * RLEN: the size of the buffer filled by QEMU.
- * ODAT: the buffer QEMU uses to store the result.
- *
- * Since the page is reused by both input and out, the input data
- * will be lost after storing new result into ODAT so we should fetch
- * all the input data before writing the result.
- */
- field = aml_field("NRAM", AML_DWORD_ACC, AML_NOLOCK, AML_PRESERVE);
- aml_append(field, aml_named_field("RLEN",
- sizeof(typeof_field(NvdimmDsmOut, len)) * BITS_PER_BYTE));
- aml_append(field, aml_named_field("ODAT",
- (TARGET_PAGE_SIZE - offsetof(NvdimmDsmOut, data)) *
- BITS_PER_BYTE));
- aml_append(dev, field);
-
- nvdimm_build_common_dsm(dev);
- nvdimm_build_device_dsm(dev);
-
- nvdimm_build_nvdimm_devices(device_list, dev);
-
- aml_append(sb_scope, dev);
- aml_append(ssdt, sb_scope);
-
- nvdimm_ssdt = table_data->len;
-
- /* copy AML table into ACPI tables blob and patch header there */
- g_array_append_vals(table_data, ssdt->buf->data, ssdt->buf->len);
- mem_addr_offset = build_append_named_dword(table_data,
- NVDIMM_ACPI_MEM_ADDR);
-
- bios_linker_loader_alloc(linker, NVDIMM_DSM_MEM_FILE, TARGET_PAGE_SIZE,
- false /* high memory */);
- bios_linker_loader_add_pointer(linker, ACPI_BUILD_TABLE_FILE,
- NVDIMM_DSM_MEM_FILE, table_data,
- table_data->data + mem_addr_offset,
- sizeof(uint32_t));
- build_header(linker, table_data,
- (void *)(table_data->data + nvdimm_ssdt),
- "SSDT", table_data->len - nvdimm_ssdt, 1, NULL, "NVDIMM");
- free_aml_allocator();
-}
-
-void nvdimm_build_acpi(GArray *table_offsets, GArray *table_data,
- GArray *linker)
-{
- GSList *device_list;
-
- /* no NVDIMM device is plugged. */
- device_list = nvdimm_get_plugged_device_list();
- if (!device_list) {
- return;
- }
- nvdimm_build_nfit(device_list, table_offsets, table_data, linker);
- nvdimm_build_ssdt(device_list, table_offsets, table_data, linker);
- g_slist_free(device_list);
-}
diff --git a/qemu/hw/acpi/pcihp.c b/qemu/hw/acpi/pcihp.c
deleted file mode 100644
index 71f4c4e14..000000000
--- a/qemu/hw/acpi/pcihp.c
+++ /dev/null
@@ -1,336 +0,0 @@
-/*
- * QEMU<->ACPI BIOS PCI hotplug interface
- *
- * QEMU supports PCI hotplug via ACPI. This module
- * implements the interface between QEMU and the ACPI BIOS.
- * Interface specification - see docs/specs/acpi_pci_hotplug.txt
- *
- * Copyright (c) 2013, Red Hat Inc, Michael S. Tsirkin (mst@redhat.com)
- * Copyright (c) 2006 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License version 2 as published by the Free Software Foundation.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see <http://www.gnu.org/licenses/>
- *
- * Contributions after 2012-01-13 are licensed under the terms of the
- * GNU GPL, version 2 or (at your option) any later version.
- */
-
-#include "qemu/osdep.h"
-#include "hw/acpi/pcihp.h"
-
-#include "hw/hw.h"
-#include "hw/i386/pc.h"
-#include "hw/pci/pci.h"
-#include "hw/acpi/acpi.h"
-#include "sysemu/sysemu.h"
-#include "exec/ioport.h"
-#include "exec/address-spaces.h"
-#include "hw/pci/pci_bus.h"
-#include "qapi/error.h"
-#include "qom/qom-qobject.h"
-#include "qapi/qmp/qint.h"
-
-//#define DEBUG
-
-#ifdef DEBUG
-# define ACPI_PCIHP_DPRINTF(format, ...) printf(format, ## __VA_ARGS__)
-#else
-# define ACPI_PCIHP_DPRINTF(format, ...) do { } while (0)
-#endif
-
-#define ACPI_PCIHP_ADDR 0xae00
-#define ACPI_PCIHP_SIZE 0x0014
-#define ACPI_PCIHP_LEGACY_SIZE 0x000f
-#define PCI_UP_BASE 0x0000
-#define PCI_DOWN_BASE 0x0004
-#define PCI_EJ_BASE 0x0008
-#define PCI_RMV_BASE 0x000c
-#define PCI_SEL_BASE 0x0010
-
-typedef struct AcpiPciHpFind {
- int bsel;
- PCIBus *bus;
-} AcpiPciHpFind;
-
-static int acpi_pcihp_get_bsel(PCIBus *bus)
-{
- Error *local_err = NULL;
- int64_t bsel = object_property_get_int(OBJECT(bus), ACPI_PCIHP_PROP_BSEL,
- &local_err);
-
- if (local_err || bsel < 0 || bsel >= ACPI_PCIHP_MAX_HOTPLUG_BUS) {
- if (local_err) {
- error_free(local_err);
- }
- return -1;
- } else {
- return bsel;
- }
-}
-
-static void acpi_pcihp_test_hotplug_bus(PCIBus *bus, void *opaque)
-{
- AcpiPciHpFind *find = opaque;
- if (find->bsel == acpi_pcihp_get_bsel(bus)) {
- find->bus = bus;
- }
-}
-
-static PCIBus *acpi_pcihp_find_hotplug_bus(AcpiPciHpState *s, int bsel)
-{
- AcpiPciHpFind find = { .bsel = bsel, .bus = NULL };
-
- if (bsel < 0) {
- return NULL;
- }
-
- pci_for_each_bus(s->root, acpi_pcihp_test_hotplug_bus, &find);
-
- /* Make bsel 0 eject root bus if bsel property is not set,
- * for compatibility with non acpi setups.
- * TODO: really needed?
- */
- if (!bsel && !find.bus) {
- find.bus = s->root;
- }
- return find.bus;
-}
-
-static bool acpi_pcihp_pc_no_hotplug(AcpiPciHpState *s, PCIDevice *dev)
-{
- PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev);
- DeviceClass *dc = DEVICE_GET_CLASS(dev);
- /*
- * ACPI doesn't allow hotplug of bridge devices. Don't allow
- * hot-unplug of bridge devices unless they were added by hotplug
- * (and so, not described by acpi).
- */
- return (pc->is_bridge && !dev->qdev.hotplugged) || !dc->hotpluggable;
-}
-
-static void acpi_pcihp_eject_slot(AcpiPciHpState *s, unsigned bsel, unsigned slots)
-{
- BusChild *kid, *next;
- int slot = ctz32(slots);
- PCIBus *bus = acpi_pcihp_find_hotplug_bus(s, bsel);
-
- if (!bus) {
- return;
- }
-
- /* Mark request as complete */
- s->acpi_pcihp_pci_status[bsel].down &= ~(1U << slot);
- s->acpi_pcihp_pci_status[bsel].up &= ~(1U << slot);
-
- QTAILQ_FOREACH_SAFE(kid, &bus->qbus.children, sibling, next) {
- DeviceState *qdev = kid->child;
- PCIDevice *dev = PCI_DEVICE(qdev);
- if (PCI_SLOT(dev->devfn) == slot) {
- if (!acpi_pcihp_pc_no_hotplug(s, dev)) {
- object_unparent(OBJECT(qdev));
- }
- }
- }
-}
-
-static void acpi_pcihp_update_hotplug_bus(AcpiPciHpState *s, int bsel)
-{
- BusChild *kid, *next;
- PCIBus *bus = acpi_pcihp_find_hotplug_bus(s, bsel);
-
- /* Execute any pending removes during reset */
- while (s->acpi_pcihp_pci_status[bsel].down) {
- acpi_pcihp_eject_slot(s, bsel, s->acpi_pcihp_pci_status[bsel].down);
- }
-
- s->acpi_pcihp_pci_status[bsel].hotplug_enable = ~0;
-
- if (!bus) {
- return;
- }
- QTAILQ_FOREACH_SAFE(kid, &bus->qbus.children, sibling, next) {
- DeviceState *qdev = kid->child;
- PCIDevice *pdev = PCI_DEVICE(qdev);
- int slot = PCI_SLOT(pdev->devfn);
-
- if (acpi_pcihp_pc_no_hotplug(s, pdev)) {
- s->acpi_pcihp_pci_status[bsel].hotplug_enable &= ~(1U << slot);
- }
- }
-}
-
-static void acpi_pcihp_update(AcpiPciHpState *s)
-{
- int i;
-
- for (i = 0; i < ACPI_PCIHP_MAX_HOTPLUG_BUS; ++i) {
- acpi_pcihp_update_hotplug_bus(s, i);
- }
-}
-
-void acpi_pcihp_reset(AcpiPciHpState *s)
-{
- acpi_pcihp_update(s);
-}
-
-void acpi_pcihp_device_plug_cb(ACPIREGS *ar, qemu_irq irq, AcpiPciHpState *s,
- DeviceState *dev, Error **errp)
-{
- PCIDevice *pdev = PCI_DEVICE(dev);
- int slot = PCI_SLOT(pdev->devfn);
- int bsel = acpi_pcihp_get_bsel(pdev->bus);
- if (bsel < 0) {
- error_setg(errp, "Unsupported bus. Bus doesn't have property '"
- ACPI_PCIHP_PROP_BSEL "' set");
- return;
- }
-
- /* Don't send event when device is enabled during qemu machine creation:
- * it is present on boot, no hotplug event is necessary. We do send an
- * event when the device is disabled later. */
- if (!dev->hotplugged) {
- return;
- }
-
- s->acpi_pcihp_pci_status[bsel].up |= (1U << slot);
-
- acpi_send_gpe_event(ar, irq, ACPI_PCI_HOTPLUG_STATUS);
-}
-
-void acpi_pcihp_device_unplug_cb(ACPIREGS *ar, qemu_irq irq, AcpiPciHpState *s,
- DeviceState *dev, Error **errp)
-{
- PCIDevice *pdev = PCI_DEVICE(dev);
- int slot = PCI_SLOT(pdev->devfn);
- int bsel = acpi_pcihp_get_bsel(pdev->bus);
- if (bsel < 0) {
- error_setg(errp, "Unsupported bus. Bus doesn't have property '"
- ACPI_PCIHP_PROP_BSEL "' set");
- return;
- }
-
- s->acpi_pcihp_pci_status[bsel].down |= (1U << slot);
-
- acpi_send_gpe_event(ar, irq, ACPI_PCI_HOTPLUG_STATUS);
-}
-
-static uint64_t pci_read(void *opaque, hwaddr addr, unsigned int size)
-{
- AcpiPciHpState *s = opaque;
- uint32_t val = 0;
- int bsel = s->hotplug_select;
-
- if (bsel < 0 || bsel >= ACPI_PCIHP_MAX_HOTPLUG_BUS) {
- return 0;
- }
-
- switch (addr) {
- case PCI_UP_BASE:
- val = s->acpi_pcihp_pci_status[bsel].up;
- if (!s->legacy_piix) {
- s->acpi_pcihp_pci_status[bsel].up = 0;
- }
- ACPI_PCIHP_DPRINTF("pci_up_read %" PRIu32 "\n", val);
- break;
- case PCI_DOWN_BASE:
- val = s->acpi_pcihp_pci_status[bsel].down;
- ACPI_PCIHP_DPRINTF("pci_down_read %" PRIu32 "\n", val);
- break;
- case PCI_EJ_BASE:
- /* No feature defined yet */
- ACPI_PCIHP_DPRINTF("pci_features_read %" PRIu32 "\n", val);
- break;
- case PCI_RMV_BASE:
- val = s->acpi_pcihp_pci_status[bsel].hotplug_enable;
- ACPI_PCIHP_DPRINTF("pci_rmv_read %" PRIu32 "\n", val);
- break;
- case PCI_SEL_BASE:
- val = s->hotplug_select;
- ACPI_PCIHP_DPRINTF("pci_sel_read %" PRIu32 "\n", val);
- default:
- break;
- }
-
- return val;
-}
-
-static void pci_write(void *opaque, hwaddr addr, uint64_t data,
- unsigned int size)
-{
- AcpiPciHpState *s = opaque;
- switch (addr) {
- case PCI_EJ_BASE:
- if (s->hotplug_select >= ACPI_PCIHP_MAX_HOTPLUG_BUS) {
- break;
- }
- acpi_pcihp_eject_slot(s, s->hotplug_select, data);
- ACPI_PCIHP_DPRINTF("pciej write %" HWADDR_PRIx " <== %" PRIu64 "\n",
- addr, data);
- break;
- case PCI_SEL_BASE:
- s->hotplug_select = data;
- ACPI_PCIHP_DPRINTF("pcisel write %" HWADDR_PRIx " <== %" PRIu64 "\n",
- addr, data);
- default:
- break;
- }
-}
-
-static const MemoryRegionOps acpi_pcihp_io_ops = {
- .read = pci_read,
- .write = pci_write,
- .endianness = DEVICE_LITTLE_ENDIAN,
- .valid = {
- .min_access_size = 4,
- .max_access_size = 4,
- },
-};
-
-void acpi_pcihp_init(Object *owner, AcpiPciHpState *s, PCIBus *root_bus,
- MemoryRegion *address_space_io, bool bridges_enabled)
-{
- s->io_len = ACPI_PCIHP_SIZE;
- s->io_base = ACPI_PCIHP_ADDR;
-
- s->root= root_bus;
- s->legacy_piix = !bridges_enabled;
-
- if (s->legacy_piix) {
- unsigned *bus_bsel = g_malloc(sizeof *bus_bsel);
-
- s->io_len = ACPI_PCIHP_LEGACY_SIZE;
-
- *bus_bsel = ACPI_PCIHP_BSEL_DEFAULT;
- object_property_add_uint32_ptr(OBJECT(root_bus), ACPI_PCIHP_PROP_BSEL,
- bus_bsel, NULL);
- }
-
- memory_region_init_io(&s->io, owner, &acpi_pcihp_io_ops, s,
- "acpi-pci-hotplug", s->io_len);
- memory_region_add_subregion(address_space_io, s->io_base, &s->io);
-
- object_property_add_uint16_ptr(owner, ACPI_PCIHP_IO_BASE_PROP, &s->io_base,
- &error_abort);
- object_property_add_uint16_ptr(owner, ACPI_PCIHP_IO_LEN_PROP, &s->io_len,
- &error_abort);
-}
-
-const VMStateDescription vmstate_acpi_pcihp_pci_status = {
- .name = "acpi_pcihp_pci_status",
- .version_id = 1,
- .minimum_version_id = 1,
- .fields = (VMStateField[]) {
- VMSTATE_UINT32(up, AcpiPciHpPciStatus),
- VMSTATE_UINT32(down, AcpiPciHpPciStatus),
- VMSTATE_END_OF_LIST()
- }
-};
diff --git a/qemu/hw/acpi/piix4.c b/qemu/hw/acpi/piix4.c
deleted file mode 100644
index 16abdf162..000000000
--- a/qemu/hw/acpi/piix4.c
+++ /dev/null
@@ -1,645 +0,0 @@
-/*
- * ACPI implementation
- *
- * Copyright (c) 2006 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License version 2 as published by the Free Software Foundation.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see <http://www.gnu.org/licenses/>
- *
- * Contributions after 2012-01-13 are licensed under the terms of the
- * GNU GPL, version 2 or (at your option) any later version.
- */
-#include "qemu/osdep.h"
-#include "hw/hw.h"
-#include "hw/i386/pc.h"
-#include "hw/isa/apm.h"
-#include "hw/i2c/pm_smbus.h"
-#include "hw/pci/pci.h"
-#include "hw/acpi/acpi.h"
-#include "sysemu/sysemu.h"
-#include "qapi/error.h"
-#include "qemu/range.h"
-#include "exec/ioport.h"
-#include "hw/nvram/fw_cfg.h"
-#include "exec/address-spaces.h"
-#include "hw/acpi/piix4.h"
-#include "hw/acpi/pcihp.h"
-#include "hw/acpi/cpu_hotplug.h"
-#include "hw/hotplug.h"
-#include "hw/mem/pc-dimm.h"
-#include "hw/acpi/memory_hotplug.h"
-#include "hw/acpi/acpi_dev_interface.h"
-#include "hw/xen/xen.h"
-
-//#define DEBUG
-
-#ifdef DEBUG
-# define PIIX4_DPRINTF(format, ...) printf(format, ## __VA_ARGS__)
-#else
-# define PIIX4_DPRINTF(format, ...) do { } while (0)
-#endif
-
-#define GPE_BASE 0xafe0
-#define GPE_LEN 4
-
-struct pci_status {
- uint32_t up; /* deprecated, maintained for migration compatibility */
- uint32_t down;
-};
-
-typedef struct PIIX4PMState {
- /*< private >*/
- PCIDevice parent_obj;
- /*< public >*/
-
- MemoryRegion io;
- uint32_t io_base;
-
- MemoryRegion io_gpe;
- ACPIREGS ar;
-
- APMState apm;
-
- PMSMBus smb;
- uint32_t smb_io_base;
-
- qemu_irq irq;
- qemu_irq smi_irq;
- int smm_enabled;
- Notifier machine_ready;
- Notifier powerdown_notifier;
-
- AcpiPciHpState acpi_pci_hotplug;
- bool use_acpi_pci_hotplug;
-
- uint8_t disable_s3;
- uint8_t disable_s4;
- uint8_t s4_val;
-
- AcpiCpuHotplug gpe_cpu;
-
- MemHotplugState acpi_memory_hotplug;
-} PIIX4PMState;
-
-#define TYPE_PIIX4_PM "PIIX4_PM"
-
-#define PIIX4_PM(obj) \
- OBJECT_CHECK(PIIX4PMState, (obj), TYPE_PIIX4_PM)
-
-static void piix4_acpi_system_hot_add_init(MemoryRegion *parent,
- PCIBus *bus, PIIX4PMState *s);
-
-#define ACPI_ENABLE 0xf1
-#define ACPI_DISABLE 0xf0
-
-static void pm_tmr_timer(ACPIREGS *ar)
-{
- PIIX4PMState *s = container_of(ar, PIIX4PMState, ar);
- acpi_update_sci(&s->ar, s->irq);
-}
-
-static void apm_ctrl_changed(uint32_t val, void *arg)
-{
- PIIX4PMState *s = arg;
- PCIDevice *d = PCI_DEVICE(s);
-
- /* ACPI specs 3.0, 4.7.2.5 */
- acpi_pm1_cnt_update(&s->ar, val == ACPI_ENABLE, val == ACPI_DISABLE);
- if (val == ACPI_ENABLE || val == ACPI_DISABLE) {
- return;
- }
-
- if (d->config[0x5b] & (1 << 1)) {
- if (s->smi_irq) {
- qemu_irq_raise(s->smi_irq);
- }
- }
-}
-
-static void pm_io_space_update(PIIX4PMState *s)
-{
- PCIDevice *d = PCI_DEVICE(s);
-
- s->io_base = le32_to_cpu(*(uint32_t *)(d->config + 0x40));
- s->io_base &= 0xffc0;
-
- memory_region_transaction_begin();
- memory_region_set_enabled(&s->io, d->config[0x80] & 1);
- memory_region_set_address(&s->io, s->io_base);
- memory_region_transaction_commit();
-}
-
-static void smbus_io_space_update(PIIX4PMState *s)
-{
- PCIDevice *d = PCI_DEVICE(s);
-
- s->smb_io_base = le32_to_cpu(*(uint32_t *)(d->config + 0x90));
- s->smb_io_base &= 0xffc0;
-
- memory_region_transaction_begin();
- memory_region_set_enabled(&s->smb.io, d->config[0xd2] & 1);
- memory_region_set_address(&s->smb.io, s->smb_io_base);
- memory_region_transaction_commit();
-}
-
-static void pm_write_config(PCIDevice *d,
- uint32_t address, uint32_t val, int len)
-{
- pci_default_write_config(d, address, val, len);
- if (range_covers_byte(address, len, 0x80) ||
- ranges_overlap(address, len, 0x40, 4)) {
- pm_io_space_update((PIIX4PMState *)d);
- }
- if (range_covers_byte(address, len, 0xd2) ||
- ranges_overlap(address, len, 0x90, 4)) {
- smbus_io_space_update((PIIX4PMState *)d);
- }
-}
-
-static int vmstate_acpi_post_load(void *opaque, int version_id)
-{
- PIIX4PMState *s = opaque;
-
- pm_io_space_update(s);
- return 0;
-}
-
-#define VMSTATE_GPE_ARRAY(_field, _state) \
- { \
- .name = (stringify(_field)), \
- .version_id = 0, \
- .info = &vmstate_info_uint16, \
- .size = sizeof(uint16_t), \
- .flags = VMS_SINGLE | VMS_POINTER, \
- .offset = vmstate_offset_pointer(_state, _field, uint8_t), \
- }
-
-static const VMStateDescription vmstate_gpe = {
- .name = "gpe",
- .version_id = 1,
- .minimum_version_id = 1,
- .fields = (VMStateField[]) {
- VMSTATE_GPE_ARRAY(sts, ACPIGPE),
- VMSTATE_GPE_ARRAY(en, ACPIGPE),
- VMSTATE_END_OF_LIST()
- }
-};
-
-static const VMStateDescription vmstate_pci_status = {
- .name = "pci_status",
- .version_id = 1,
- .minimum_version_id = 1,
- .fields = (VMStateField[]) {
- VMSTATE_UINT32(up, struct AcpiPciHpPciStatus),
- VMSTATE_UINT32(down, struct AcpiPciHpPciStatus),
- VMSTATE_END_OF_LIST()
- }
-};
-
-static int acpi_load_old(QEMUFile *f, void *opaque, int version_id)
-{
- PIIX4PMState *s = opaque;
- int ret, i;
- uint16_t temp;
-
- ret = pci_device_load(PCI_DEVICE(s), f);
- if (ret < 0) {
- return ret;
- }
- qemu_get_be16s(f, &s->ar.pm1.evt.sts);
- qemu_get_be16s(f, &s->ar.pm1.evt.en);
- qemu_get_be16s(f, &s->ar.pm1.cnt.cnt);
-
- ret = vmstate_load_state(f, &vmstate_apm, &s->apm, 1);
- if (ret) {
- return ret;
- }
-
- timer_get(f, s->ar.tmr.timer);
- qemu_get_sbe64s(f, &s->ar.tmr.overflow_time);
-
- qemu_get_be16s(f, (uint16_t *)s->ar.gpe.sts);
- for (i = 0; i < 3; i++) {
- qemu_get_be16s(f, &temp);
- }
-
- qemu_get_be16s(f, (uint16_t *)s->ar.gpe.en);
- for (i = 0; i < 3; i++) {
- qemu_get_be16s(f, &temp);
- }
-
- ret = vmstate_load_state(f, &vmstate_pci_status,
- &s->acpi_pci_hotplug.acpi_pcihp_pci_status[ACPI_PCIHP_BSEL_DEFAULT], 1);
- return ret;
-}
-
-static bool vmstate_test_use_acpi_pci_hotplug(void *opaque, int version_id)
-{
- PIIX4PMState *s = opaque;
- return s->use_acpi_pci_hotplug;
-}
-
-static bool vmstate_test_no_use_acpi_pci_hotplug(void *opaque, int version_id)
-{
- PIIX4PMState *s = opaque;
- return !s->use_acpi_pci_hotplug;
-}
-
-static bool vmstate_test_use_memhp(void *opaque)
-{
- PIIX4PMState *s = opaque;
- return s->acpi_memory_hotplug.is_enabled;
-}
-
-static const VMStateDescription vmstate_memhp_state = {
- .name = "piix4_pm/memhp",
- .version_id = 1,
- .minimum_version_id = 1,
- .minimum_version_id_old = 1,
- .needed = vmstate_test_use_memhp,
- .fields = (VMStateField[]) {
- VMSTATE_MEMORY_HOTPLUG(acpi_memory_hotplug, PIIX4PMState),
- VMSTATE_END_OF_LIST()
- }
-};
-
-/* qemu-kvm 1.2 uses version 3 but advertised as 2
- * To support incoming qemu-kvm 1.2 migration, change version_id
- * and minimum_version_id to 2 below (which breaks migration from
- * qemu 1.2).
- *
- */
-static const VMStateDescription vmstate_acpi = {
- .name = "piix4_pm",
- .version_id = 3,
- .minimum_version_id = 3,
- .minimum_version_id_old = 1,
- .load_state_old = acpi_load_old,
- .post_load = vmstate_acpi_post_load,
- .fields = (VMStateField[]) {
- VMSTATE_PCI_DEVICE(parent_obj, PIIX4PMState),
- VMSTATE_UINT16(ar.pm1.evt.sts, PIIX4PMState),
- VMSTATE_UINT16(ar.pm1.evt.en, PIIX4PMState),
- VMSTATE_UINT16(ar.pm1.cnt.cnt, PIIX4PMState),
- VMSTATE_STRUCT(apm, PIIX4PMState, 0, vmstate_apm, APMState),
- VMSTATE_TIMER_PTR(ar.tmr.timer, PIIX4PMState),
- VMSTATE_INT64(ar.tmr.overflow_time, PIIX4PMState),
- VMSTATE_STRUCT(ar.gpe, PIIX4PMState, 2, vmstate_gpe, ACPIGPE),
- VMSTATE_STRUCT_TEST(
- acpi_pci_hotplug.acpi_pcihp_pci_status[ACPI_PCIHP_BSEL_DEFAULT],
- PIIX4PMState,
- vmstate_test_no_use_acpi_pci_hotplug,
- 2, vmstate_pci_status,
- struct AcpiPciHpPciStatus),
- VMSTATE_PCI_HOTPLUG(acpi_pci_hotplug, PIIX4PMState,
- vmstate_test_use_acpi_pci_hotplug),
- VMSTATE_END_OF_LIST()
- },
- .subsections = (const VMStateDescription*[]) {
- &vmstate_memhp_state,
- NULL
- }
-};
-
-static void piix4_reset(void *opaque)
-{
- PIIX4PMState *s = opaque;
- PCIDevice *d = PCI_DEVICE(s);
- uint8_t *pci_conf = d->config;
-
- pci_conf[0x58] = 0;
- pci_conf[0x59] = 0;
- pci_conf[0x5a] = 0;
- pci_conf[0x5b] = 0;
-
- pci_conf[0x40] = 0x01; /* PM io base read only bit */
- pci_conf[0x80] = 0;
-
- if (!s->smm_enabled) {
- /* Mark SMM as already inited (until KVM supports SMM). */
- pci_conf[0x5B] = 0x02;
- }
- pm_io_space_update(s);
- acpi_pcihp_reset(&s->acpi_pci_hotplug);
-}
-
-static void piix4_pm_powerdown_req(Notifier *n, void *opaque)
-{
- PIIX4PMState *s = container_of(n, PIIX4PMState, powerdown_notifier);
-
- assert(s != NULL);
- acpi_pm1_evt_power_down(&s->ar);
-}
-
-static void piix4_device_plug_cb(HotplugHandler *hotplug_dev,
- DeviceState *dev, Error **errp)
-{
- PIIX4PMState *s = PIIX4_PM(hotplug_dev);
-
- if (s->acpi_memory_hotplug.is_enabled &&
- object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
- acpi_memory_plug_cb(&s->ar, s->irq, &s->acpi_memory_hotplug, dev, errp);
- } else if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
- acpi_pcihp_device_plug_cb(&s->ar, s->irq, &s->acpi_pci_hotplug, dev,
- errp);
- } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
- acpi_cpu_plug_cb(&s->ar, s->irq, &s->gpe_cpu, dev, errp);
- } else {
- error_setg(errp, "acpi: device plug request for not supported device"
- " type: %s", object_get_typename(OBJECT(dev)));
- }
-}
-
-static void piix4_device_unplug_request_cb(HotplugHandler *hotplug_dev,
- DeviceState *dev, Error **errp)
-{
- PIIX4PMState *s = PIIX4_PM(hotplug_dev);
-
- if (s->acpi_memory_hotplug.is_enabled &&
- object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
- acpi_memory_unplug_request_cb(&s->ar, s->irq, &s->acpi_memory_hotplug,
- dev, errp);
- } else if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
- acpi_pcihp_device_unplug_cb(&s->ar, s->irq, &s->acpi_pci_hotplug, dev,
- errp);
- } else {
- error_setg(errp, "acpi: device unplug request for not supported device"
- " type: %s", object_get_typename(OBJECT(dev)));
- }
-}
-
-static void piix4_device_unplug_cb(HotplugHandler *hotplug_dev,
- DeviceState *dev, Error **errp)
-{
- PIIX4PMState *s = PIIX4_PM(hotplug_dev);
-
- if (s->acpi_memory_hotplug.is_enabled &&
- object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
- acpi_memory_unplug_cb(&s->acpi_memory_hotplug, dev, errp);
- } else {
- error_setg(errp, "acpi: device unplug for not supported device"
- " type: %s", object_get_typename(OBJECT(dev)));
- }
-}
-
-static void piix4_update_bus_hotplug(PCIBus *pci_bus, void *opaque)
-{
- PIIX4PMState *s = opaque;
-
- qbus_set_hotplug_handler(BUS(pci_bus), DEVICE(s), &error_abort);
-}
-
-static void piix4_pm_machine_ready(Notifier *n, void *opaque)
-{
- PIIX4PMState *s = container_of(n, PIIX4PMState, machine_ready);
- PCIDevice *d = PCI_DEVICE(s);
- MemoryRegion *io_as = pci_address_space_io(d);
- uint8_t *pci_conf;
-
- pci_conf = d->config;
- pci_conf[0x5f] = 0x10 |
- (memory_region_present(io_as, 0x378) ? 0x80 : 0);
- pci_conf[0x63] = 0x60;
- pci_conf[0x67] = (memory_region_present(io_as, 0x3f8) ? 0x08 : 0) |
- (memory_region_present(io_as, 0x2f8) ? 0x90 : 0);
-
- if (s->use_acpi_pci_hotplug) {
- pci_for_each_bus(d->bus, piix4_update_bus_hotplug, s);
- } else {
- piix4_update_bus_hotplug(d->bus, s);
- }
-}
-
-static void piix4_pm_add_propeties(PIIX4PMState *s)
-{
- static const uint8_t acpi_enable_cmd = ACPI_ENABLE;
- static const uint8_t acpi_disable_cmd = ACPI_DISABLE;
- static const uint32_t gpe0_blk = GPE_BASE;
- static const uint32_t gpe0_blk_len = GPE_LEN;
- static const uint16_t sci_int = 9;
-
- object_property_add_uint8_ptr(OBJECT(s), ACPI_PM_PROP_ACPI_ENABLE_CMD,
- &acpi_enable_cmd, NULL);
- object_property_add_uint8_ptr(OBJECT(s), ACPI_PM_PROP_ACPI_DISABLE_CMD,
- &acpi_disable_cmd, NULL);
- object_property_add_uint32_ptr(OBJECT(s), ACPI_PM_PROP_GPE0_BLK,
- &gpe0_blk, NULL);
- object_property_add_uint32_ptr(OBJECT(s), ACPI_PM_PROP_GPE0_BLK_LEN,
- &gpe0_blk_len, NULL);
- object_property_add_uint16_ptr(OBJECT(s), ACPI_PM_PROP_SCI_INT,
- &sci_int, NULL);
- object_property_add_uint32_ptr(OBJECT(s), ACPI_PM_PROP_PM_IO_BASE,
- &s->io_base, NULL);
-}
-
-static void piix4_pm_realize(PCIDevice *dev, Error **errp)
-{
- PIIX4PMState *s = PIIX4_PM(dev);
- uint8_t *pci_conf;
-
- pci_conf = dev->config;
- pci_conf[0x06] = 0x80;
- pci_conf[0x07] = 0x02;
- pci_conf[0x09] = 0x00;
- pci_conf[0x3d] = 0x01; // interrupt pin 1
-
- /* APM */
- apm_init(dev, &s->apm, apm_ctrl_changed, s);
-
- if (!s->smm_enabled) {
- /* Mark SMM as already inited to prevent SMM from running. KVM does not
- * support SMM mode. */
- pci_conf[0x5B] = 0x02;
- }
-
- /* XXX: which specification is used ? The i82731AB has different
- mappings */
- pci_conf[0x90] = s->smb_io_base | 1;
- pci_conf[0x91] = s->smb_io_base >> 8;
- pci_conf[0xd2] = 0x09;
- pm_smbus_init(DEVICE(dev), &s->smb);
- memory_region_set_enabled(&s->smb.io, pci_conf[0xd2] & 1);
- memory_region_add_subregion(pci_address_space_io(dev),
- s->smb_io_base, &s->smb.io);
-
- memory_region_init(&s->io, OBJECT(s), "piix4-pm", 64);
- memory_region_set_enabled(&s->io, false);
- memory_region_add_subregion(pci_address_space_io(dev),
- 0, &s->io);
-
- acpi_pm_tmr_init(&s->ar, pm_tmr_timer, &s->io);
- acpi_pm1_evt_init(&s->ar, pm_tmr_timer, &s->io);
- acpi_pm1_cnt_init(&s->ar, &s->io, s->disable_s3, s->disable_s4, s->s4_val);
- acpi_gpe_init(&s->ar, GPE_LEN);
-
- s->powerdown_notifier.notify = piix4_pm_powerdown_req;
- qemu_register_powerdown_notifier(&s->powerdown_notifier);
-
- s->machine_ready.notify = piix4_pm_machine_ready;
- qemu_add_machine_init_done_notifier(&s->machine_ready);
- qemu_register_reset(piix4_reset, s);
-
- piix4_acpi_system_hot_add_init(pci_address_space_io(dev), dev->bus, s);
-
- piix4_pm_add_propeties(s);
-}
-
-Object *piix4_pm_find(void)
-{
- bool ambig;
- Object *o = object_resolve_path_type("", TYPE_PIIX4_PM, &ambig);
-
- if (ambig || !o) {
- return NULL;
- }
- return o;
-}
-
-I2CBus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
- qemu_irq sci_irq, qemu_irq smi_irq,
- int smm_enabled, DeviceState **piix4_pm)
-{
- DeviceState *dev;
- PIIX4PMState *s;
-
- dev = DEVICE(pci_create(bus, devfn, TYPE_PIIX4_PM));
- qdev_prop_set_uint32(dev, "smb_io_base", smb_io_base);
- if (piix4_pm) {
- *piix4_pm = dev;
- }
-
- s = PIIX4_PM(dev);
- s->irq = sci_irq;
- s->smi_irq = smi_irq;
- s->smm_enabled = smm_enabled;
- if (xen_enabled()) {
- s->use_acpi_pci_hotplug = false;
- }
-
- qdev_init_nofail(dev);
-
- return s->smb.smbus;
-}
-
-static uint64_t gpe_readb(void *opaque, hwaddr addr, unsigned width)
-{
- PIIX4PMState *s = opaque;
- uint32_t val = acpi_gpe_ioport_readb(&s->ar, addr);
-
- PIIX4_DPRINTF("gpe read %" HWADDR_PRIx " == %" PRIu32 "\n", addr, val);
- return val;
-}
-
-static void gpe_writeb(void *opaque, hwaddr addr, uint64_t val,
- unsigned width)
-{
- PIIX4PMState *s = opaque;
-
- acpi_gpe_ioport_writeb(&s->ar, addr, val);
- acpi_update_sci(&s->ar, s->irq);
-
- PIIX4_DPRINTF("gpe write %" HWADDR_PRIx " <== %" PRIu64 "\n", addr, val);
-}
-
-static const MemoryRegionOps piix4_gpe_ops = {
- .read = gpe_readb,
- .write = gpe_writeb,
- .valid.min_access_size = 1,
- .valid.max_access_size = 4,
- .impl.min_access_size = 1,
- .impl.max_access_size = 1,
- .endianness = DEVICE_LITTLE_ENDIAN,
-};
-
-static void piix4_acpi_system_hot_add_init(MemoryRegion *parent,
- PCIBus *bus, PIIX4PMState *s)
-{
- memory_region_init_io(&s->io_gpe, OBJECT(s), &piix4_gpe_ops, s,
- "acpi-gpe0", GPE_LEN);
- memory_region_add_subregion(parent, GPE_BASE, &s->io_gpe);
-
- acpi_pcihp_init(OBJECT(s), &s->acpi_pci_hotplug, bus, parent,
- s->use_acpi_pci_hotplug);
-
- acpi_cpu_hotplug_init(parent, OBJECT(s), &s->gpe_cpu,
- PIIX4_CPU_HOTPLUG_IO_BASE);
-
- if (s->acpi_memory_hotplug.is_enabled) {
- acpi_memory_hotplug_init(parent, OBJECT(s), &s->acpi_memory_hotplug);
- }
-}
-
-static void piix4_ospm_status(AcpiDeviceIf *adev, ACPIOSTInfoList ***list)
-{
- PIIX4PMState *s = PIIX4_PM(adev);
-
- acpi_memory_ospm_status(&s->acpi_memory_hotplug, list);
-}
-
-static Property piix4_pm_properties[] = {
- DEFINE_PROP_UINT32("smb_io_base", PIIX4PMState, smb_io_base, 0),
- DEFINE_PROP_UINT8(ACPI_PM_PROP_S3_DISABLED, PIIX4PMState, disable_s3, 0),
- DEFINE_PROP_UINT8(ACPI_PM_PROP_S4_DISABLED, PIIX4PMState, disable_s4, 0),
- DEFINE_PROP_UINT8(ACPI_PM_PROP_S4_VAL, PIIX4PMState, s4_val, 2),
- DEFINE_PROP_BOOL("acpi-pci-hotplug-with-bridge-support", PIIX4PMState,
- use_acpi_pci_hotplug, true),
- DEFINE_PROP_BOOL("memory-hotplug-support", PIIX4PMState,
- acpi_memory_hotplug.is_enabled, true),
- DEFINE_PROP_END_OF_LIST(),
-};
-
-static void piix4_pm_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
- PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
- HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass);
- AcpiDeviceIfClass *adevc = ACPI_DEVICE_IF_CLASS(klass);
-
- k->realize = piix4_pm_realize;
- k->config_write = pm_write_config;
- k->vendor_id = PCI_VENDOR_ID_INTEL;
- k->device_id = PCI_DEVICE_ID_INTEL_82371AB_3;
- k->revision = 0x03;
- k->class_id = PCI_CLASS_BRIDGE_OTHER;
- dc->desc = "PM";
- dc->vmsd = &vmstate_acpi;
- dc->props = piix4_pm_properties;
- /*
- * Reason: part of PIIX4 southbridge, needs to be wired up,
- * e.g. by mips_malta_init()
- */
- dc->cannot_instantiate_with_device_add_yet = true;
- dc->hotpluggable = false;
- hc->plug = piix4_device_plug_cb;
- hc->unplug_request = piix4_device_unplug_request_cb;
- hc->unplug = piix4_device_unplug_cb;
- adevc->ospm_status = piix4_ospm_status;
-}
-
-static const TypeInfo piix4_pm_info = {
- .name = TYPE_PIIX4_PM,
- .parent = TYPE_PCI_DEVICE,
- .instance_size = sizeof(PIIX4PMState),
- .class_init = piix4_pm_class_init,
- .interfaces = (InterfaceInfo[]) {
- { TYPE_HOTPLUG_HANDLER },
- { TYPE_ACPI_DEVICE_IF },
- { }
- }
-};
-
-static void piix4_pm_register_types(void)
-{
- type_register_static(&piix4_pm_info);
-}
-
-type_init(piix4_pm_register_types)
diff --git a/qemu/hw/acpi/tco.c b/qemu/hw/acpi/tco.c
deleted file mode 100644
index 8ce7daf23..000000000
--- a/qemu/hw/acpi/tco.c
+++ /dev/null
@@ -1,265 +0,0 @@
-/*
- * QEMU ICH9 TCO emulation
- *
- * Copyright (c) 2015 Paulo Alcantara <pcacjr@zytor.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-#include "qemu/osdep.h"
-#include "qemu-common.h"
-#include "sysemu/watchdog.h"
-#include "hw/i386/ich9.h"
-
-#include "hw/acpi/tco.h"
-
-//#define DEBUG
-
-#ifdef DEBUG
-#define TCO_DEBUG(fmt, ...) \
- do { \
- fprintf(stderr, "%s "fmt, __func__, ## __VA_ARGS__); \
- } while (0)
-#else
-#define TCO_DEBUG(fmt, ...) do { } while (0)
-#endif
-
-enum {
- TCO_RLD_DEFAULT = 0x0000,
- TCO_DAT_IN_DEFAULT = 0x00,
- TCO_DAT_OUT_DEFAULT = 0x00,
- TCO1_STS_DEFAULT = 0x0000,
- TCO2_STS_DEFAULT = 0x0000,
- TCO1_CNT_DEFAULT = 0x0000,
- TCO2_CNT_DEFAULT = 0x0008,
- TCO_MESSAGE1_DEFAULT = 0x00,
- TCO_MESSAGE2_DEFAULT = 0x00,
- TCO_WDCNT_DEFAULT = 0x00,
- TCO_TMR_DEFAULT = 0x0004,
- SW_IRQ_GEN_DEFAULT = 0x03,
-};
-
-static inline void tco_timer_reload(TCOIORegs *tr)
-{
- tr->expire_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
- ((int64_t)(tr->tco.tmr & TCO_TMR_MASK) * TCO_TICK_NSEC);
- timer_mod(tr->tco_timer, tr->expire_time);
-}
-
-static inline void tco_timer_stop(TCOIORegs *tr)
-{
- tr->expire_time = -1;
-}
-
-static void tco_timer_expired(void *opaque)
-{
- TCOIORegs *tr = opaque;
- ICH9LPCPMRegs *pm = container_of(tr, ICH9LPCPMRegs, tco_regs);
- ICH9LPCState *lpc = container_of(pm, ICH9LPCState, pm);
- uint32_t gcs = pci_get_long(lpc->chip_config + ICH9_CC_GCS);
-
- tr->tco.rld = 0;
- tr->tco.sts1 |= TCO_TIMEOUT;
- if (++tr->timeouts_no == 2) {
- tr->tco.sts2 |= TCO_SECOND_TO_STS;
- tr->tco.sts2 |= TCO_BOOT_STS;
- tr->timeouts_no = 0;
-
- if (!lpc->pin_strap.spkr_hi && !(gcs & ICH9_CC_GCS_NO_REBOOT)) {
- watchdog_perform_action();
- tco_timer_stop(tr);
- return;
- }
- }
-
- if (pm->smi_en & ICH9_PMIO_SMI_EN_TCO_EN) {
- ich9_generate_smi();
- } else {
- ich9_generate_nmi();
- }
- tr->tco.rld = tr->tco.tmr;
- tco_timer_reload(tr);
-}
-
-/* NOTE: values of 0 or 1 will be ignored by ICH */
-static inline int can_start_tco_timer(TCOIORegs *tr)
-{
- return !(tr->tco.cnt1 & TCO_TMR_HLT) && tr->tco.tmr > 1;
-}
-
-static uint32_t tco_ioport_readw(TCOIORegs *tr, uint32_t addr)
-{
- uint16_t rld;
-
- switch (addr) {
- case TCO_RLD:
- if (tr->expire_time != -1) {
- int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
- int64_t elapsed = (tr->expire_time - now) / TCO_TICK_NSEC;
- rld = (uint16_t)elapsed | (tr->tco.rld & ~TCO_RLD_MASK);
- } else {
- rld = tr->tco.rld;
- }
- return rld;
- case TCO_DAT_IN:
- return tr->tco.din;
- case TCO_DAT_OUT:
- return tr->tco.dout;
- case TCO1_STS:
- return tr->tco.sts1;
- case TCO2_STS:
- return tr->tco.sts2;
- case TCO1_CNT:
- return tr->tco.cnt1;
- case TCO2_CNT:
- return tr->tco.cnt2;
- case TCO_MESSAGE1:
- return tr->tco.msg1;
- case TCO_MESSAGE2:
- return tr->tco.msg2;
- case TCO_WDCNT:
- return tr->tco.wdcnt;
- case TCO_TMR:
- return tr->tco.tmr;
- case SW_IRQ_GEN:
- return tr->sw_irq_gen;
- }
- return 0;
-}
-
-static void tco_ioport_writew(TCOIORegs *tr, uint32_t addr, uint32_t val)
-{
- switch (addr) {
- case TCO_RLD:
- tr->timeouts_no = 0;
- if (can_start_tco_timer(tr)) {
- tr->tco.rld = tr->tco.tmr;
- tco_timer_reload(tr);
- } else {
- tr->tco.rld = val;
- }
- break;
- case TCO_DAT_IN:
- tr->tco.din = val;
- tr->tco.sts1 |= SW_TCO_SMI;
- ich9_generate_smi();
- break;
- case TCO_DAT_OUT:
- tr->tco.dout = val;
- tr->tco.sts1 |= TCO_INT_STS;
- /* TODO: cause an interrupt, as selected by the TCO_INT_SEL bits */
- break;
- case TCO1_STS:
- tr->tco.sts1 = val & TCO1_STS_MASK;
- break;
- case TCO2_STS:
- tr->tco.sts2 = val & TCO2_STS_MASK;
- break;
- case TCO1_CNT:
- val &= TCO1_CNT_MASK;
- /*
- * once TCO_LOCK bit is set, it can not be cleared by software. a reset
- * is required to change this bit from 1 to 0 -- it defaults to 0.
- */
- tr->tco.cnt1 = val | (tr->tco.cnt1 & TCO_LOCK);
- if (can_start_tco_timer(tr)) {
- tr->tco.rld = tr->tco.tmr;
- tco_timer_reload(tr);
- } else {
- tco_timer_stop(tr);
- }
- break;
- case TCO2_CNT:
- tr->tco.cnt2 = val;
- break;
- case TCO_MESSAGE1:
- tr->tco.msg1 = val;
- break;
- case TCO_MESSAGE2:
- tr->tco.msg2 = val;
- break;
- case TCO_WDCNT:
- tr->tco.wdcnt = val;
- break;
- case TCO_TMR:
- tr->tco.tmr = val;
- break;
- case SW_IRQ_GEN:
- tr->sw_irq_gen = val;
- break;
- }
-}
-
-static uint64_t tco_io_readw(void *opaque, hwaddr addr, unsigned width)
-{
- TCOIORegs *tr = opaque;
- return tco_ioport_readw(tr, addr);
-}
-
-static void tco_io_writew(void *opaque, hwaddr addr, uint64_t val,
- unsigned width)
-{
- TCOIORegs *tr = opaque;
- tco_ioport_writew(tr, addr, val);
-}
-
-static const MemoryRegionOps tco_io_ops = {
- .read = tco_io_readw,
- .write = tco_io_writew,
- .valid.min_access_size = 1,
- .valid.max_access_size = 4,
- .impl.min_access_size = 1,
- .impl.max_access_size = 2,
- .endianness = DEVICE_LITTLE_ENDIAN,
-};
-
-void acpi_pm_tco_init(TCOIORegs *tr, MemoryRegion *parent)
-{
- *tr = (TCOIORegs) {
- .tco = {
- .rld = TCO_RLD_DEFAULT,
- .din = TCO_DAT_IN_DEFAULT,
- .dout = TCO_DAT_OUT_DEFAULT,
- .sts1 = TCO1_STS_DEFAULT,
- .sts2 = TCO2_STS_DEFAULT,
- .cnt1 = TCO1_CNT_DEFAULT,
- .cnt2 = TCO2_CNT_DEFAULT,
- .msg1 = TCO_MESSAGE1_DEFAULT,
- .msg2 = TCO_MESSAGE2_DEFAULT,
- .wdcnt = TCO_WDCNT_DEFAULT,
- .tmr = TCO_TMR_DEFAULT,
- },
- .sw_irq_gen = SW_IRQ_GEN_DEFAULT,
- .tco_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, tco_timer_expired, tr),
- .expire_time = -1,
- .timeouts_no = 0,
- };
- memory_region_init_io(&tr->io, memory_region_owner(parent),
- &tco_io_ops, tr, "sm-tco", ICH9_PMIO_TCO_LEN);
- memory_region_add_subregion(parent, ICH9_PMIO_TCO_RLD, &tr->io);
-}
-
-const VMStateDescription vmstate_tco_io_sts = {
- .name = "tco io device status",
- .version_id = 1,
- .minimum_version_id = 1,
- .minimum_version_id_old = 1,
- .fields = (VMStateField[]) {
- VMSTATE_UINT16(tco.rld, TCOIORegs),
- VMSTATE_UINT8(tco.din, TCOIORegs),
- VMSTATE_UINT8(tco.dout, TCOIORegs),
- VMSTATE_UINT16(tco.sts1, TCOIORegs),
- VMSTATE_UINT16(tco.sts2, TCOIORegs),
- VMSTATE_UINT16(tco.cnt1, TCOIORegs),
- VMSTATE_UINT16(tco.cnt2, TCOIORegs),
- VMSTATE_UINT8(tco.msg1, TCOIORegs),
- VMSTATE_UINT8(tco.msg2, TCOIORegs),
- VMSTATE_UINT8(tco.wdcnt, TCOIORegs),
- VMSTATE_UINT16(tco.tmr, TCOIORegs),
- VMSTATE_UINT8(sw_irq_gen, TCOIORegs),
- VMSTATE_TIMER_PTR(tco_timer, TCOIORegs),
- VMSTATE_INT64(expire_time, TCOIORegs),
- VMSTATE_UINT8(timeouts_no, TCOIORegs),
- VMSTATE_END_OF_LIST()
- }
-};