acpi dsdt rework, misc fixes

This completes the dsdt rewrite, and includes misc fixes all over the place.
 
 Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQEcBAABAgAGBQJWkXmiAAoJECgfDbjSjVRpRtoIAKCtPLZPapStgd85Fyl0m0Qg
 sVGcABtWxej+rwwpnOONJX2O0+fFp2aXh6mucirWtn5qaduMKj5Ou0wB9LnCUxyW
 tziafuHec/BQQ1TZ7WMGNJclVmLY6JmYMuSkcxeXHcskPnVdefGtTJEL8/fRA4/E
 RuIhjPIWpHGCm/ExXb41gfhh1GoTwIWJFBS53FR/Oc0oqVg7zlUOhUsfz02zk1QB
 WjAIedgXWFzeeGOAR4yKKMGMAJaJ1nueSfqD5lgMsAglbnOEIUYuQhQWDOWHdNMb
 +Xc2XBeYmnCxGk4KDx+h9H7Yacu9GDX3R4VUHSBPS92+YQdkUk3C3rUiDC9KcRE=
 =MsMN
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging

acpi dsdt rework, misc fixes

This completes the dsdt rewrite, and includes misc fixes all over the place.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>

# gpg: Signature made Sat 09 Jan 2016 21:20:34 GMT using RSA key ID D28D5469
# gpg: Good signature from "Michael S. Tsirkin <mst@kernel.org>"
# gpg:                 aka "Michael S. Tsirkin <mst@redhat.com>"

* remotes/mst/tags/for_upstream: (59 commits)
  virtio: fix error message for number of queues
  ivshmem: Store file descriptor for vhost-user negotiation
  migration/virtio: Remove simple .get/.put use
  Add VMSTATE_STRUCT_VARRAY_KNOWN
  i386/pc: expose identifying the floppy controller
  pc: acpi: remove unused ASL templates and related blobs/utils
  pc: acpi: switch to AML API composed DSDT
  pc: acpi: q35: PCST, PCSB opregions and PCIB field into SSDT
  pc: acpi: q35: move PCI0 device definition into SSDT
  pc: acpi: q35: move PCI0._OSC() method into SSDT
  pc: acpi: q35: move _PIC() method into SSDT
  pc: acpi: q35: move PRTP routing table into SSDT
  pc: acpi: q35: move PRTA routing table into SSDT
  pc: acpi: q35: move _PRT() into SSDT
  pc: acpi: q35: move ISA bridge into SSDT
  pc: acpi: q35: move IQST() into SSDT
  pc: acpi: q35: move IQCR() into SSDT
  pc: acpi: q35: move link devices to SSDT
  pc: acpi: q35: move GSI links to SSDT
  pc: acpi: piix4: acpi move PCI0 device to SSDT
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
master
Peter Maydell 2016-01-11 11:19:05 +00:00
commit d21ccd7bb9
33 changed files with 1690 additions and 12589 deletions

10
exec.c
View File

@ -1757,6 +1757,16 @@ int qemu_get_ram_fd(ram_addr_t addr)
return fd;
}
void qemu_set_ram_fd(ram_addr_t addr, int fd)
{
RAMBlock *block;
rcu_read_lock();
block = qemu_get_ram_block(addr);
block->fd = fd;
rcu_read_unlock();
}
void *qemu_get_ram_block_host_ptr(ram_addr_t addr)
{
RAMBlock *block;

View File

@ -1,7 +1,7 @@
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
common-obj-$(CONFIG_ACPI_MEMORY_HOTPLUG) += memory_hotplug.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
common-obj-$(CONFIG_ACPI_NVDIMM) += nvdimm.o
common-obj-$(CONFIG_ACPI) += acpi_interface.o
common-obj-$(CONFIG_ACPI) += bios-linker-loader.o

View File

@ -0,0 +1,135 @@
/*
* 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 "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);
}

View File

@ -0,0 +1,262 @@
/*
* 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 <stdbool.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);
}

View File

@ -353,16 +353,18 @@ static void nvdimm_build_nfit(GSList *device_list, GArray *table_offsets,
GArray *table_data, GArray *linker)
{
GArray *structures = nvdimm_build_device_structure(device_list);
void *header;
unsigned int header;
acpi_add_table(table_offsets, table_data);
/* NFIT header. */
header = acpi_data_push(table_data, sizeof(NvdimmNfitHeader));
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, header, "NFIT",
build_header(linker, table_data,
(void *)(table_data->data + header), "NFIT",
sizeof(NvdimmNfitHeader) + structures->len, 1, NULL);
g_array_free(structures, true);
}

View File

@ -8,33 +8,3 @@ obj-$(CONFIG_XEN) += ../xenpv/ xen/
obj-y += kvmvapic.o
obj-y += acpi-build.o
obj-y += pci-assign-load-rom.o
gen-hex-y += hw/i386/acpi-dsdt.hex
gen-hex-y += hw/i386/q35-acpi-dsdt.hex
hw/i386/acpi-build.o: hw/i386/acpi-build.c \
$(gen-hex-y)
-include $(gen-hex-y:.hex=.d)
iasl-option=$(shell if test -z "`$(1) $(2) 2>&1 > /dev/null`" \
; then echo "$(2)"; else echo "$(3)"; fi ;)
ifdef IASL
#IASL Present. Generate hex files from .dsl
hw/i386/%.hex: $(SRC_PATH)/hw/i386/%.dsl $(SRC_PATH)/scripts/acpi_extract_preprocess.py $(SRC_PATH)/scripts/acpi_extract.py
$(call quiet-command, $(CPP) -x c -P $(QEMU_DGFLAGS) $(QEMU_INCLUDES) $< -o $*.dsl.i.orig, " CPP $(TARGET_DIR)$*.dsl.i.orig")
$(call quiet-command, $(PYTHON) $(SRC_PATH)/scripts/acpi_extract_preprocess.py $*.dsl.i.orig > $*.dsl.i, " ACPI_PREPROCESS $(TARGET_DIR)$*.dsl.i")
$(call quiet-command, $(IASL) $(call iasl-option,$(IASL),-Pn,) -vs -l -tc -p $* $*.dsl.i $(if $(V), , > /dev/null) 2>&1 ," IASL $(TARGET_DIR)$*.dsl.i")
$(call quiet-command, $(PYTHON) $(SRC_PATH)/scripts/acpi_extract.py $*.lst > $*.off, " ACPI_EXTRACT $(TARGET_DIR)$*.off")
$(call quiet-command, cat $*.off > $@, " CAT $(TARGET_DIR)$@")
else
#IASL Not present. Restore pre-generated hex files.
hw/i386/%.hex: $(SRC_PATH)/hw/i386/%.hex.generated
$(call quiet-command, cp -f $< $@, " CP $(TARGET_DIR)$@")
endif
.PHONY: cleanhex
cleanhex:
rm -f hw/i386/*hex
clean: cleanhex

File diff suppressed because it is too large Load Diff

View File

@ -1,90 +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/>.
*/
/****************************************************************
* CPU hotplug
****************************************************************/
Scope(\_SB) {
/* Objects filled in by run-time generated SSDT */
External(NTFY, MethodObj)
External(CPON, PkgObj)
External(PRS, FieldUnitObj)
/* Methods called by run-time generated SSDT Processor objects */
Method(CPMA, 1, NotSerialized) {
// _MAT method - create an madt apic buffer
// Arg0 = Processor ID = Local APIC ID
// Local0 = CPON flag for this cpu
Store(DerefOf(Index(CPON, Arg0)), Local0)
// Local1 = Buffer (in madt apic form) to return
Store(Buffer(8) {0x00, 0x08, 0x00, 0x00, 0x00, 0, 0, 0}, Local1)
// Update the processor id, lapic id, and enable/disable status
Store(Arg0, Index(Local1, 2))
Store(Arg0, Index(Local1, 3))
Store(Local0, Index(Local1, 4))
Return (Local1)
}
Method(CPST, 1, NotSerialized) {
// _STA method - return ON status of cpu
// Arg0 = Processor ID = Local APIC ID
// Local0 = CPON flag for this cpu
Store(DerefOf(Index(CPON, Arg0)), Local0)
If (Local0) {
Return (0xF)
} Else {
Return (0x0)
}
}
Method(CPEJ, 2, NotSerialized) {
// _EJ0 method - eject callback
Sleep(200)
}
#define CPU_STATUS_LEN ACPI_GPE_PROC_LEN
Method(PRSC, 0) {
// Local5 = active cpu bitmap
Store(PRS, Local5)
// Local2 = last read byte from bitmap
Store(Zero, Local2)
// Local0 = Processor ID / APIC ID iterator
Store(Zero, Local0)
While (LLess(Local0, SizeOf(CPON))) {
// Local1 = CPON flag for this cpu
Store(DerefOf(Index(CPON, Local0)), Local1)
If (And(Local0, 0x07)) {
// Shift down previously read bitmap byte
ShiftRight(Local2, 1, Local2)
} Else {
// Read next byte from cpu bitmap
Store(DerefOf(Index(Local5, ShiftRight(Local0, 3))), Local2)
}
// Local3 = active state for this cpu
Store(And(Local2, 1), Local3)
If (LNotEqual(Local1, Local3)) {
// State change - update CPON with new state
Store(Local3, Index(CPON, Local0))
// Do CPU notify
If (LEqual(Local3, 1)) {
NTFY(Local0, 1)
} Else {
NTFY(Local0, 3)
}
}
Increment(Local0)
}
}
}

View File

@ -1,41 +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/>.
*/
/****************************************************************
* Debugging
****************************************************************/
Scope(\) {
/* Debug Output */
OperationRegion(DBG, SystemIO, 0x0402, 0x01)
Field(DBG, ByteAcc, NoLock, Preserve) {
DBGB, 8,
}
/* Debug method - use this method to send output to the QEMU
* BIOS debug port. This method handles strings, integers,
* and buffers. For example: DBUG("abc") DBUG(0x123) */
Method(DBUG, 1) {
ToHexString(Arg0, Local0)
ToBuffer(Local0, Local0)
Subtract(SizeOf(Local0), 1, Local1)
Store(Zero, Local2)
While (LLess(Local2, Local1)) {
Store(DerefOf(Index(Local0, Local2)), DBGB)
Increment(Local2)
}
Store(0x0A, DBGB)
}
}

View File

@ -1,48 +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/>.
*/
/****************************************************************
* HPET
****************************************************************/
Scope(\_SB) {
Device(HPET) {
Name(_HID, EISAID("PNP0103"))
Name(_UID, 0)
OperationRegion(HPTM, SystemMemory, 0xFED00000, 0x400)
Field(HPTM, DWordAcc, Lock, Preserve) {
VEND, 32,
PRD, 32,
}
Method(_STA, 0, NotSerialized) {
Store(VEND, Local0)
Store(PRD, Local1)
ShiftRight(Local0, 16, Local0)
If (LOr(LEqual(Local0, 0), LEqual(Local0, 0xffff))) {
Return (0x0)
}
If (LOr(LEqual(Local1, 0), LGreater(Local1, 100000000))) {
Return (0x0)
}
Return (0x0F)
}
Name(_CRS, ResourceTemplate() {
Memory32Fixed(ReadOnly,
0xFED00000, // Address Base
0x00000400, // Address Length
)
})
}
}

View File

@ -1,117 +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/>.
*/
/* Common legacy ISA style devices. */
Scope(\_SB.PCI0.ISA) {
Device(RTC) {
Name(_HID, EisaId("PNP0B00"))
Name(_CRS, ResourceTemplate() {
IO(Decode16, 0x0070, 0x0070, 0x10, 0x02)
IRQNoFlags() { 8 }
IO(Decode16, 0x0072, 0x0072, 0x02, 0x06)
})
}
Device(KBD) {
Name(_HID, EisaId("PNP0303"))
Method(_STA, 0, NotSerialized) {
Return (0x0f)
}
Name(_CRS, ResourceTemplate() {
IO(Decode16, 0x0060, 0x0060, 0x01, 0x01)
IO(Decode16, 0x0064, 0x0064, 0x01, 0x01)
IRQNoFlags() { 1 }
})
}
Device(MOU) {
Name(_HID, EisaId("PNP0F13"))
Method(_STA, 0, NotSerialized) {
Return (0x0f)
}
Name(_CRS, ResourceTemplate() {
IRQNoFlags() { 12 }
})
}
Device(FDC0) {
Name(_HID, EisaId("PNP0700"))
Method(_STA, 0, NotSerialized) {
Store(FDEN, Local0)
If (LEqual(Local0, 0)) {
Return (0x00)
} Else {
Return (0x0F)
}
}
Name(_CRS, ResourceTemplate() {
IO(Decode16, 0x03F2, 0x03F2, 0x00, 0x04)
IO(Decode16, 0x03F7, 0x03F7, 0x00, 0x01)
IRQNoFlags() { 6 }
DMA(Compatibility, NotBusMaster, Transfer8) { 2 }
})
}
Device(LPT) {
Name(_HID, EisaId("PNP0400"))
Method(_STA, 0, NotSerialized) {
Store(LPEN, Local0)
If (LEqual(Local0, 0)) {
Return (0x00)
} Else {
Return (0x0F)
}
}
Name(_CRS, ResourceTemplate() {
IO(Decode16, 0x0378, 0x0378, 0x08, 0x08)
IRQNoFlags() { 7 }
})
}
Device(COM1) {
Name(_HID, EisaId("PNP0501"))
Name(_UID, 0x01)
Method(_STA, 0, NotSerialized) {
Store(CAEN, Local0)
If (LEqual(Local0, 0)) {
Return (0x00)
} Else {
Return (0x0F)
}
}
Name(_CRS, ResourceTemplate() {
IO(Decode16, 0x03F8, 0x03F8, 0x00, 0x08)
IRQNoFlags() { 4 }
})
}
Device(COM2) {
Name(_HID, EisaId("PNP0501"))
Name(_UID, 0x02)
Method(_STA, 0, NotSerialized) {
Store(CBEN, Local0)
If (LEqual(Local0, 0)) {
Return (0x00)
} Else {
Return (0x0F)
}
}
Name(_CRS, ResourceTemplate() {
IO(Decode16, 0x02F8, 0x02F8, 0x00, 0x08)
IRQNoFlags() { 3 }
})
}
}

View File

@ -1,171 +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/>.
*/
External(MEMORY_SLOT_NOTIFY_METHOD, MethodObj)
Scope(\_SB.PCI0) {
Device(MEMORY_HOTPLUG_DEVICE) {
Name(_HID, "PNP0A06")
Name(_UID, "Memory hotplug resources")
External(MEMORY_SLOTS_NUMBER, IntObj)
/* Memory hotplug IO registers */
External(MEMORY_SLOT_ADDR_LOW, FieldUnitObj) // read only
External(MEMORY_SLOT_ADDR_HIGH, FieldUnitObj) // read only
External(MEMORY_SLOT_SIZE_LOW, FieldUnitObj) // read only
External(MEMORY_SLOT_SIZE_HIGH, FieldUnitObj) // read only
External(MEMORY_SLOT_PROXIMITY, FieldUnitObj) // read only
External(MEMORY_SLOT_ENABLED, FieldUnitObj) // 1 if enabled, read only
External(MEMORY_SLOT_INSERT_EVENT, FieldUnitObj) // (read) 1 if has a insert event. (write) 1 to clear event
External(MEMORY_SLOT_REMOVE_EVENT, FieldUnitObj) // (read) 1 if has a remove event. (write) 1 to clear event
External(MEMORY_SLOT_EJECT, FieldUnitObj) // initiates device eject, write only
External(MEMORY_SLOT_SLECTOR, FieldUnitObj) // DIMM selector, write only
External(MEMORY_SLOT_OST_EVENT, FieldUnitObj) // _OST event code, write only
External(MEMORY_SLOT_OST_STATUS, FieldUnitObj) // _OST status code, write only
Method(_STA, 0) {
If (LEqual(MEMORY_SLOTS_NUMBER, Zero)) {
Return(0x0)
}
/* present, functioning, decoding, not shown in UI */
Return(0xB)
}
Mutex (MEMORY_SLOT_LOCK, 0)
Method(MEMORY_SLOT_SCAN_METHOD, 0) {
If (LEqual(MEMORY_SLOTS_NUMBER, Zero)) {
Return(Zero)
}
Store(Zero, Local0) // Mem devs iterrator
Acquire(MEMORY_SLOT_LOCK, 0xFFFF)
while (LLess(Local0, MEMORY_SLOTS_NUMBER)) {
Store(Local0, MEMORY_SLOT_SLECTOR) // select Local0 DIMM
If (LEqual(MEMORY_SLOT_INSERT_EVENT, One)) { // Memory device needs check
MEMORY_SLOT_NOTIFY_METHOD(Local0, 1)
Store(1, MEMORY_SLOT_INSERT_EVENT)
} Elseif (LEqual(MEMORY_SLOT_REMOVE_EVENT, One)) { // Ejection request
MEMORY_SLOT_NOTIFY_METHOD(Local0, 3)
Store(1, MEMORY_SLOT_REMOVE_EVENT)
}
Add(Local0, One, Local0) // goto next DIMM
}
Release(MEMORY_SLOT_LOCK)
Return(One)
}
Method(MEMORY_SLOT_STATUS_METHOD, 1) {
Store(Zero, Local0)
Acquire(MEMORY_SLOT_LOCK, 0xFFFF)
Store(ToInteger(Arg0), MEMORY_SLOT_SLECTOR) // select DIMM
If (LEqual(MEMORY_SLOT_ENABLED, One)) {
Store(0xF, Local0)
}
Release(MEMORY_SLOT_LOCK)
Return(Local0)
}
Method(MEMORY_SLOT_CRS_METHOD, 1, Serialized) {
Acquire(MEMORY_SLOT_LOCK, 0xFFFF)
Store(ToInteger(Arg0), MEMORY_SLOT_SLECTOR) // select DIMM
Name(MR64, ResourceTemplate() {
QWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed,
Cacheable, ReadWrite,
0x0000000000000000, // Address Space Granularity
0x0000000000000000, // Address Range Minimum
0xFFFFFFFFFFFFFFFE, // Address Range Maximum
0x0000000000000000, // Address Translation Offset
0xFFFFFFFFFFFFFFFF, // Address Length
,, MW64, AddressRangeMemory, TypeStatic)
})
CreateDWordField(MR64, 14, MINL)
CreateDWordField(MR64, 18, MINH)
CreateDWordField(MR64, 38, LENL)
CreateDWordField(MR64, 42, LENH)
CreateDWordField(MR64, 22, MAXL)
CreateDWordField(MR64, 26, MAXH)
Store(MEMORY_SLOT_ADDR_HIGH, MINH)
Store(MEMORY_SLOT_ADDR_LOW, MINL)
Store(MEMORY_SLOT_SIZE_HIGH, LENH)
Store(MEMORY_SLOT_SIZE_LOW, LENL)
// 64-bit math: MAX = MIN + LEN - 1
Add(MINL, LENL, MAXL)
Add(MINH, LENH, MAXH)
If (LLess(MAXL, MINL)) {
Add(MAXH, One, MAXH)
}
If (LLess(MAXL, One)) {
Subtract(MAXH, One, MAXH)
}
Subtract(MAXL, One, MAXL)
If (LEqual(MAXH, Zero)){
Name(MR32, ResourceTemplate() {
DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed,
Cacheable, ReadWrite,
0x00000000, // Address Space Granularity
0x00000000, // Address Range Minimum
0xFFFFFFFE, // Address Range Maximum
0x00000000, // Address Translation Offset
0xFFFFFFFF, // Address Length
,, MW32, AddressRangeMemory, TypeStatic)
})
CreateDWordField(MR32, MW32._MIN, MIN)
CreateDWordField(MR32, MW32._MAX, MAX)
CreateDWordField(MR32, MW32._LEN, LEN)
Store(MINL, MIN)
Store(MAXL, MAX)
Store(LENL, LEN)
Release(MEMORY_SLOT_LOCK)
Return(MR32)
}
Release(MEMORY_SLOT_LOCK)
Return(MR64)
}
Method(MEMORY_SLOT_PROXIMITY_METHOD, 1) {
Acquire(MEMORY_SLOT_LOCK, 0xFFFF)
Store(ToInteger(Arg0), MEMORY_SLOT_SLECTOR) // select DIMM
Store(MEMORY_SLOT_PROXIMITY, Local0)
Release(MEMORY_SLOT_LOCK)
Return(Local0)
}
Method(MEMORY_SLOT_OST_METHOD, 4) {
Acquire(MEMORY_SLOT_LOCK, 0xFFFF)
Store(ToInteger(Arg0), MEMORY_SLOT_SLECTOR) // select DIMM
Store(Arg1, MEMORY_SLOT_OST_EVENT)
Store(Arg2, MEMORY_SLOT_OST_STATUS)
Release(MEMORY_SLOT_LOCK)
}
Method(MEMORY_SLOT_EJECT_METHOD, 2) {
Acquire(MEMORY_SLOT_LOCK, 0xFFFF)
Store(ToInteger(Arg0), MEMORY_SLOT_SLECTOR) // select DIMM
Store(1, MEMORY_SLOT_EJECT)
Release(MEMORY_SLOT_LOCK)
}
} // Device()
} // Scope()

View File

@ -1,303 +0,0 @@
/*
* Bochs/QEMU ACPI DSDT ASL definition
*
* 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, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
ACPI_EXTRACT_ALL_CODE AcpiDsdtAmlCode
DefinitionBlock (
"acpi-dsdt.aml", // Output Filename
"DSDT", // Signature
0x01, // DSDT Compliance Revision
"BXPC", // OEMID
"BXDSDT", // TABLE ID
0x1 // OEM Revision
)
{
#include "acpi-dsdt-dbug.dsl"
Scope(\_SB) {
Device(PCI0) {
Name(_HID, EisaId("PNP0A03"))
Name(_ADR, 0x00)
Name(_UID, 1)
//#define PX13 S0B_
// External(PX13, DeviceObj)
}
}
#include "acpi-dsdt-hpet.dsl"
/****************************************************************
* PIIX4 PM
****************************************************************/
Scope(\_SB.PCI0) {
Device(PX13) {
Name(_ADR, 0x00010003)
OperationRegion(P13C, PCI_Config, 0x00, 0xff)
}
}
/****************************************************************
* PIIX3 ISA bridge
****************************************************************/
Scope(\_SB.PCI0) {
External(ISA, DeviceObj)
Device(ISA) {
Name(_ADR, 0x00010000)
/* PIIX PCI to ISA irq remapping */
OperationRegion(P40C, PCI_Config, 0x60, 0x04)
/* enable bits */
Field(\_SB.PCI0.PX13.P13C, AnyAcc, NoLock, Preserve) {
Offset(0x5f),
, 7,
LPEN, 1, // LPT
Offset(0x67),
, 3,
CAEN, 1, // COM1
, 3,
CBEN, 1, // COM2
}
Name(FDEN, 1)
}
}
#include "acpi-dsdt-isa.dsl"
/****************************************************************
* PCI hotplug
****************************************************************/
Scope(\_SB.PCI0) {
OperationRegion(PCST, SystemIO, 0xae00, 0x08)
Field(PCST, DWordAcc, NoLock, WriteAsZeros) {
PCIU, 32,
PCID, 32,
}
OperationRegion(SEJ, SystemIO, 0xae08, 0x04)
Field(SEJ, DWordAcc, NoLock, WriteAsZeros) {
B0EJ, 32,
}
OperationRegion(BNMR, SystemIO, 0xae10, 0x04)
Field(BNMR, DWordAcc, NoLock, WriteAsZeros) {
BNUM, 32,
}
/* Lock to protect access to fields above. */
Mutex(BLCK, 0)
/* Methods called by bulk generated PCI devices below */
/* Methods called by hotplug devices */
Method(PCEJ, 2, NotSerialized) {
// _EJ0 method - eject callback
Acquire(BLCK, 0xFFFF)
Store(Arg0, BNUM)
Store(ShiftLeft(1, Arg1), B0EJ)
Release(BLCK)
Return (0x0)
}
/* Hotplug notification method supplied by SSDT */
External(\_SB.PCI0.PCNT, MethodObj)
}
/****************************************************************
* PCI IRQs
****************************************************************/
Scope(\_SB) {
Scope(PCI0) {
Method (_PRT, 0) {
Store(Package(128) {}, Local0)
Store(Zero, Local1)
While(LLess(Local1, 128)) {
// slot = pin >> 2
Store(ShiftRight(Local1, 2), Local2)
// lnk = (slot + pin) & 3
Store(And(Add(Local1, Local2), 3), Local3)
If (LEqual(Local3, 0)) {
Store(Package(4) { Zero, Zero, LNKD, Zero }, Local4)
}
If (LEqual(Local3, 1)) {
// device 1 is the power-management device, needs SCI
If (LEqual(Local1, 4)) {
Store(Package(4) { Zero, Zero, LNKS, Zero }, Local4)
} Else {
Store(Package(4) { Zero, Zero, LNKA, Zero }, Local4)
}
}
If (LEqual(Local3, 2)) {
Store(Package(4) { Zero, Zero, LNKB, Zero }, Local4)
}
If (LEqual(Local3, 3)) {
Store(Package(4) { Zero, Zero, LNKC, Zero }, Local4)
}
// Complete the interrupt routing entry:
// Package(4) { 0x[slot]FFFF, [pin], [link], 0) }
Store(Or(ShiftLeft(Local2, 16), 0xFFFF), Index(Local4, 0))
Store(And(Local1, 3), Index(Local4, 1))
Store(Local4, Index(Local0, Local1))
Increment(Local1)
}
Return(Local0)
}
}
Field(PCI0.ISA.P40C, ByteAcc, NoLock, Preserve) {
PRQ0, 8,
PRQ1, 8,
PRQ2, 8,
PRQ3, 8
}
Method(IQST, 1, NotSerialized) {
// _STA method - get status
If (And(0x80, Arg0)) {
Return (0x09)
}
Return (0x0B)
}
Method(IQCR, 1, Serialized) {
// _CRS method - get current settings
Name(PRR0, ResourceTemplate() {
Interrupt(, Level, ActiveHigh, Shared) { 0 }
})
CreateDWordField(PRR0, 0x05, PRRI)
If (LLess(Arg0, 0x80)) {
Store(Arg0, PRRI)
}
Return (PRR0)
}
#define define_link(link, uid, reg) \
Device(link) { \
Name(_HID, EISAID("PNP0C0F")) \
Name(_UID, uid) \
Name(_PRS, ResourceTemplate() { \
Interrupt(, Level, ActiveHigh, Shared) { \
5, 10, 11 \
} \
}) \
Method(_STA, 0, NotSerialized) { \
Return (IQST(reg)) \
} \
Method(_DIS, 0, NotSerialized) { \
Or(reg, 0x80, reg) \
} \
Method(_CRS, 0, NotSerialized) { \
Return (IQCR(reg)) \
} \
Method(_SRS, 1, NotSerialized) { \
CreateDWordField(Arg0, 0x05, PRRI) \
Store(PRRI, reg) \
} \
}
define_link(LNKA, 0, PRQ0)
define_link(LNKB, 1, PRQ1)
define_link(LNKC, 2, PRQ2)
define_link(LNKD, 3, PRQ3)
Device(LNKS) {
Name(_HID, EISAID("PNP0C0F"))
Name(_UID, 4)
Name(_PRS, ResourceTemplate() {
Interrupt(, Level, ActiveHigh, Shared) { 9 }
})
// The SCI cannot be disabled and is always attached to GSI 9,
// so these are no-ops. We only need this link to override the
// polarity to active high and match the content of the MADT.
Method(_STA, 0, NotSerialized) { Return (0x0b) }
Method(_DIS, 0, NotSerialized) { }
Method(_CRS, 0, NotSerialized) { Return (_PRS) }
Method(_SRS, 1, NotSerialized) { }
}
}
#include "hw/acpi/pc-hotplug.h"
#define CPU_STATUS_BASE PIIX4_CPU_HOTPLUG_IO_BASE
#include "acpi-dsdt-cpu-hotplug.dsl"
#include "acpi-dsdt-mem-hotplug.dsl"
/****************************************************************
* General purpose events
****************************************************************/
Scope(\_GPE) {
Name(_HID, "ACPI0006")
Method(_L00) {
}
Method(_E01) {
// PCI hotplug event
Acquire(\_SB.PCI0.BLCK, 0xFFFF)
\_SB.PCI0.PCNT()
Release(\_SB.PCI0.BLCK)
}
Method(_E02) {
// CPU hotplug event
\_SB.PRSC()
}
Method(_E03) {
// Memory hotplug event
\_SB.PCI0.MEMORY_HOTPLUG_DEVICE.MEMORY_SLOT_SCAN_METHOD()
}
Method(_L04) {
}
Method(_L05) {
}
Method(_L06) {
}
Method(_L07) {
}
Method(_L08) {
}
Method(_L09) {
}
Method(_L0A) {
}
Method(_L0B) {
}
Method(_L0C) {
}
Method(_L0D) {
}
Method(_L0E) {
}
Method(_L0F) {
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -360,6 +360,31 @@ static const char * const fdc_container_path[] = {
"/unattached", "/peripheral", "/peripheral-anon"
};
/*
* Locate the FDC at IO address 0x3f0, in order to configure the CMOS registers
* and ACPI objects.
*/
ISADevice *pc_find_fdc0(void)
{
int i;
Object *container;
CheckFdcState state = { 0 };
for (i = 0; i < ARRAY_SIZE(fdc_container_path); i++) {
container = container_get(qdev_get_machine(), fdc_container_path[i]);
object_child_foreach(container, check_fdc, &state);
}
if (state.multiple) {
error_report("warning: multiple floppy disk controllers with "
"iobase=0x3f0 have been found;\n"
"the one being picked for CMOS setup might not reflect "
"your intent");
}
return state.floppy;
}
static void pc_cmos_init_late(void *opaque)
{
pc_cmos_init_late_arg *arg = opaque;
@ -368,8 +393,6 @@ static void pc_cmos_init_late(void *opaque)
int8_t heads, sectors;
int val;
int i, trans;
Object *container;
CheckFdcState state = { 0 };
val = 0;
if (ide_get_geometry(arg->idebus[0], 0,
@ -399,22 +422,7 @@ static void pc_cmos_init_late(void *opaque)
}
rtc_set_memory(s, 0x39, val);
/*
* Locate the FDC at IO address 0x3f0, and configure the CMOS registers
* accordingly.
*/
for (i = 0; i < ARRAY_SIZE(fdc_container_path); i++) {
container = container_get(qdev_get_machine(), fdc_container_path[i]);
object_child_foreach(container, check_fdc, &state);
}
if (state.multiple) {
error_report("warning: multiple floppy disk controllers with "
"iobase=0x3f0 have been found;\n"
"the one being picked for CMOS setup might not reflect "
"your intent");
}
pc_cmos_init_floppy(s, state.floppy);
pc_cmos_init_floppy(s, pc_find_fdc0());
qemu_unregister_reset(pc_cmos_init_late, opaque);
}

View File

@ -1,436 +0,0 @@
/*
* Bochs/QEMU ACPI DSDT ASL definition
*
* 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, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
* Copyright (c) 2010 Isaku Yamahata
* yamahata at valinux co jp
* Based on acpi-dsdt.dsl, but heavily modified for q35 chipset.
*/
ACPI_EXTRACT_ALL_CODE Q35AcpiDsdtAmlCode
DefinitionBlock (
"q35-acpi-dsdt.aml",// Output Filename
"DSDT", // Signature
0x01, // DSDT Compliance Revision
"BXPC", // OEMID
"BXDSDT", // TABLE ID
0x2 // OEM Revision
)
{
#include "acpi-dsdt-dbug.dsl"
Scope(\_SB) {
OperationRegion(PCST, SystemIO, 0xae00, 0x0c)
OperationRegion(PCSB, SystemIO, 0xae0c, 0x01)
Field(PCSB, AnyAcc, NoLock, WriteAsZeros) {
PCIB, 8,
}
}
/****************************************************************
* PCI Bus definition
****************************************************************/
Scope(\_SB) {
Device(PCI0) {
Name(_HID, EisaId("PNP0A08"))
Name(_CID, EisaId("PNP0A03"))
Name(_ADR, 0x00)
Name(_UID, 1)
External(ISA, DeviceObj)
// _OSC: based on sample of ACPI3.0b spec
Name(SUPP, 0) // PCI _OSC Support Field value
Name(CTRL, 0) // PCI _OSC Control Field value
Method(_OSC, 4) {
// Create DWORD-addressable fields from the Capabilities Buffer
CreateDWordField(Arg3, 0, CDW1)
// Check for proper UUID
If (LEqual(Arg0, ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766"))) {
// Create DWORD-addressable fields from the Capabilities Buffer
CreateDWordField(Arg3, 4, CDW2)
CreateDWordField(Arg3, 8, CDW3)
// Save Capabilities DWORD2 & 3
Store(CDW2, SUPP)
Store(CDW3, CTRL)
// Always allow native PME, AER (no dependencies)
// Never allow SHPC (no SHPC controller in this system)
And(CTRL, 0x1D, CTRL)
#if 0 // For now, nothing to do
If (Not(And(CDW1, 1))) { // Query flag clear?
// Disable GPEs for features granted native control.
If (And(CTRL, 0x01)) { // Hot plug control granted?
Store(0, HPCE) // clear the hot plug SCI enable bit
Store(1, HPCS) // clear the hot plug SCI status bit
}
If (And(CTRL, 0x04)) { // PME control granted?
Store(0, PMCE) // clear the PME SCI enable bit
Store(1, PMCS) // clear the PME SCI status bit
}
If (And(CTRL, 0x10)) { // OS restoring PCI Express cap structure?
// Set status to not restore PCI Express cap structure
// upon resume from S3
Store(1, S3CR)
}
}
#endif
If (LNotEqual(Arg1, One)) {
// Unknown revision
Or(CDW1, 0x08, CDW1)
}
If (LNotEqual(CDW3, CTRL)) {
// Capabilities bits were masked
Or(CDW1, 0x10, CDW1)
}
// Update DWORD3 in the buffer
Store(CTRL, CDW3)
} Else {
Or(CDW1, 4, CDW1) // Unrecognized UUID
}
Return (Arg3)
}
}
}
#include "acpi-dsdt-hpet.dsl"
/****************************************************************
* LPC ISA bridge
****************************************************************/
Scope(\_SB.PCI0) {
/* PCI D31:f0 LPC ISA bridge */
Device(ISA) {
Name (_ADR, 0x001F0000) // _ADR: Address
/* ICH9 PCI to ISA irq remapping */
OperationRegion(PIRQ, PCI_Config, 0x60, 0x0C)
OperationRegion(LPCD, PCI_Config, 0x80, 0x2)
Field(LPCD, AnyAcc, NoLock, Preserve) {
COMA, 3,
, 1,
COMB, 3,
Offset(0x01),
LPTD, 2,
, 2,
FDCD, 2
}
OperationRegion(LPCE, PCI_Config, 0x82, 0x2)
Field(LPCE, AnyAcc, NoLock, Preserve) {
CAEN, 1,
CBEN, 1,
LPEN, 1,
FDEN, 1
}
}
}
#include "acpi-dsdt-isa.dsl"
/****************************************************************
* PCI IRQs
****************************************************************/
/* Zero => PIC mode, One => APIC Mode */
Name(\PICF, Zero)
Method(\_PIC, 1, NotSerialized) {
Store(Arg0, \PICF)
}
Scope(\_SB) {
Scope(PCI0) {
#define prt_slot_lnk(nr, lnk0, lnk1, lnk2, lnk3) \
Package() { nr##ffff, 0, lnk0, 0 }, \
Package() { nr##ffff, 1, lnk1, 0 }, \
Package() { nr##ffff, 2, lnk2, 0 }, \
Package() { nr##ffff, 3, lnk3, 0 }
#define prt_slot_lnkA(nr) prt_slot_lnk(nr, LNKA, LNKB, LNKC, LNKD)
#define prt_slot_lnkB(nr) prt_slot_lnk(nr, LNKB, LNKC, LNKD, LNKA)
#define prt_slot_lnkC(nr) prt_slot_lnk(nr, LNKC, LNKD, LNKA, LNKB)
#define prt_slot_lnkD(nr) prt_slot_lnk(nr, LNKD, LNKA, LNKB, LNKC)
#define prt_slot_lnkE(nr) prt_slot_lnk(nr, LNKE, LNKF, LNKG, LNKH)
#define prt_slot_lnkF(nr) prt_slot_lnk(nr, LNKF, LNKG, LNKH, LNKE)
#define prt_slot_lnkG(nr) prt_slot_lnk(nr, LNKG, LNKH, LNKE, LNKF)
#define prt_slot_lnkH(nr) prt_slot_lnk(nr, LNKH, LNKE, LNKF, LNKG)
Name(PRTP, package() {
prt_slot_lnkE(0x0000),
prt_slot_lnkF(0x0001),
prt_slot_lnkG(0x0002),
prt_slot_lnkH(0x0003),
prt_slot_lnkE(0x0004),
prt_slot_lnkF(0x0005),
prt_slot_lnkG(0x0006),
prt_slot_lnkH(0x0007),
prt_slot_lnkE(0x0008),
prt_slot_lnkF(0x0009),
prt_slot_lnkG(0x000a),
prt_slot_lnkH(0x000b),
prt_slot_lnkE(0x000c),
prt_slot_lnkF(0x000d),
prt_slot_lnkG(0x000e),
prt_slot_lnkH(0x000f),
prt_slot_lnkE(0x0010),
prt_slot_lnkF(0x0011),
prt_slot_lnkG(0x0012),
prt_slot_lnkH(0x0013),
prt_slot_lnkE(0x0014),
prt_slot_lnkF(0x0015),
prt_slot_lnkG(0x0016),
prt_slot_lnkH(0x0017),
prt_slot_lnkE(0x0018),
/* INTA -> PIRQA for slot 25 - 31
see the default value of D<N>IR */
prt_slot_lnkA(0x0019),
prt_slot_lnkA(0x001a),
prt_slot_lnkA(0x001b),
prt_slot_lnkA(0x001c),
prt_slot_lnkA(0x001d),
/* PCIe->PCI bridge. use PIRQ[E-H] */
prt_slot_lnkE(0x001e),
prt_slot_lnkA(0x001f)
})
#define prt_slot_gsi(nr, gsi0, gsi1, gsi2, gsi3) \
Package() { nr##ffff, 0, gsi0, 0 }, \
Package() { nr##ffff, 1, gsi1, 0 }, \
Package() { nr##ffff, 2, gsi2, 0 }, \
Package() { nr##ffff, 3, gsi3, 0 }
#define prt_slot_gsiA(nr) prt_slot_gsi(nr, GSIA, GSIB, GSIC, GSID)
#define prt_slot_gsiB(nr) prt_slot_gsi(nr, GSIB, GSIC, GSID, GSIA)
#define prt_slot_gsiC(nr) prt_slot_gsi(nr, GSIC, GSID, GSIA, GSIB)
#define prt_slot_gsiD(nr) prt_slot_gsi(nr, GSID, GSIA, GSIB, GSIC)
#define prt_slot_gsiE(nr) prt_slot_gsi(nr, GSIE, GSIF, GSIG, GSIH)
#define prt_slot_gsiF(nr) prt_slot_gsi(nr, GSIF, GSIG, GSIH, GSIE)
#define prt_slot_gsiG(nr) prt_slot_gsi(nr, GSIG, GSIH, GSIE, GSIF)
#define prt_slot_gsiH(nr) prt_slot_gsi(nr, GSIH, GSIE, GSIF, GSIG)
Name(PRTA, package() {
prt_slot_gsiE(0x0000),
prt_slot_gsiF(0x0001),
prt_slot_gsiG(0x0002),
prt_slot_gsiH(0x0003),
prt_slot_gsiE(0x0004),
prt_slot_gsiF(0x0005),
prt_slot_gsiG(0x0006),
prt_slot_gsiH(0x0007),
prt_slot_gsiE(0x0008),
prt_slot_gsiF(0x0009),
prt_slot_gsiG(0x000a),
prt_slot_gsiH(0x000b),
prt_slot_gsiE(0x000c),
prt_slot_gsiF(0x000d),
prt_slot_gsiG(0x000e),
prt_slot_gsiH(0x000f),
prt_slot_gsiE(0x0010),
prt_slot_gsiF(0x0011),
prt_slot_gsiG(0x0012),
prt_slot_gsiH(0x0013),
prt_slot_gsiE(0x0014),
prt_slot_gsiF(0x0015),
prt_slot_gsiG(0x0016),
prt_slot_gsiH(0x0017),
prt_slot_gsiE(0x0018),
/* INTA -> PIRQA for slot 25 - 31, but 30
see the default value of D<N>IR */
prt_slot_gsiA(0x0019),
prt_slot_gsiA(0x001a),
prt_slot_gsiA(0x001b),
prt_slot_gsiA(0x001c),
prt_slot_gsiA(0x001d),
/* PCIe->PCI bridge. use PIRQ[E-H] */
prt_slot_gsiE(0x001e),
prt_slot_gsiA(0x001f)
})
Method(_PRT, 0, NotSerialized) {
/* PCI IRQ routing table, example from ACPI 2.0a specification,
section 6.2.8.1 */
/* Note: we provide the same info as the PCI routing
table of the Bochs BIOS */
If (LEqual(\PICF, Zero)) {
Return (PRTP)
} Else {
Return (PRTA)
}
}
}
Field(PCI0.ISA.PIRQ, ByteAcc, NoLock, Preserve) {
PRQA, 8,
PRQB, 8,
PRQC, 8,
PRQD, 8,
Offset(0x08),
PRQE, 8,
PRQF, 8,
PRQG, 8,
PRQH, 8
}
Method(IQST, 1, NotSerialized) {
// _STA method - get status
If (And(0x80, Arg0)) {
Return (0x09)
}
Return (0x0B)
}
Method(IQCR, 1, Serialized) {
// _CRS method - get current settings
Name(PRR0, ResourceTemplate() {
Interrupt(, Level, ActiveHigh, Shared) { 0 }
})
CreateDWordField(PRR0, 0x05, PRRI)
Store(And(Arg0, 0x0F), PRRI)
Return (PRR0)
}
#define define_link(link, uid, reg) \
Device(link) { \
Name(_HID, EISAID("PNP0C0F")) \
Name(_UID, uid) \
Name(_PRS, ResourceTemplate() { \
Interrupt(, Level, ActiveHigh, Shared) { \
5, 10, 11 \
} \
}) \
Method(_STA, 0, NotSerialized) { \
Return (IQST(reg)) \
} \
Method(_DIS, 0, NotSerialized) { \
Or(reg, 0x80, reg) \
} \
Method(_CRS, 0, NotSerialized) { \
Return (IQCR(reg)) \
} \
Method(_SRS, 1, NotSerialized) { \
CreateDWordField(Arg0, 0x05, PRRI) \
Store(PRRI, reg) \
} \
}
define_link(LNKA, 0, PRQA)
define_link(LNKB, 1, PRQB)
define_link(LNKC, 2, PRQC)
define_link(LNKD, 3, PRQD)
define_link(LNKE, 4, PRQE)
define_link(LNKF, 5, PRQF)
define_link(LNKG, 6, PRQG)
define_link(LNKH, 7, PRQH)
#define define_gsi_link(link, uid, gsi) \
Device(link) { \
Name(_HID, EISAID("PNP0C0F")) \
Name(_UID, uid) \
Name(_PRS, ResourceTemplate() { \
Interrupt(, Level, ActiveHigh, Shared) { \
gsi \
} \
}) \
Name(_CRS, ResourceTemplate() { \
Interrupt(, Level, ActiveHigh, Shared) { \
gsi \
} \
}) \
Method(_SRS, 1, NotSerialized) { \
} \
}
define_gsi_link(GSIA, 0, 0x10)
define_gsi_link(GSIB, 0, 0x11)
define_gsi_link(GSIC, 0, 0x12)
define_gsi_link(GSID, 0, 0x13)
define_gsi_link(GSIE, 0, 0x14)
define_gsi_link(GSIF, 0, 0x15)
define_gsi_link(GSIG, 0, 0x16)
define_gsi_link(GSIH, 0, 0x17)
}
#include "hw/acpi/pc-hotplug.h"
#define CPU_STATUS_BASE ICH9_CPU_HOTPLUG_IO_BASE
#include "acpi-dsdt-cpu-hotplug.dsl"
#include "acpi-dsdt-mem-hotplug.dsl"
/****************************************************************
* General purpose events
****************************************************************/
Scope(\_GPE) {
Name(_HID, "ACPI0006")
Method(_L00) {
}
Method(_L01) {
}
Method(_E02) {
// CPU hotplug event
\_SB.PRSC()
}
Method(_E03) {
// Memory hotplug event
\_SB.PCI0.MEMORY_HOTPLUG_DEVICE.MEMORY_SLOT_SCAN_METHOD()
}
Method(_L04) {
}
Method(_L05) {
}
Method(_L06) {
}
Method(_L07) {
}
Method(_L08) {
}
Method(_L09) {
}
Method(_L0A) {
}
Method(_L0B) {
}
Method(_L0C) {
}
Method(_L0D) {
}
Method(_L0E) {
}
Method(_L0F) {
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -29,6 +29,7 @@
#include "sysemu/char.h"
#include "sysemu/hostmem.h"
#include "qapi/visitor.h"
#include "exec/ram_addr.h"
#include "hw/misc/ivshmem.h"
@ -422,6 +423,7 @@ static int create_shared_memory_BAR(IVShmemState *s, int fd, uint8_t attr,
memory_region_init_ram_ptr(&s->ivshmem, OBJECT(s), "ivshmem.bar2",
s->ivshmem_size, ptr);
qemu_set_ram_fd(s->ivshmem.ram_addr, fd);
vmstate_register_ram(&s->ivshmem, DEVICE(s));
memory_region_add_subregion(&s->bar, 0, &s->ivshmem);
@ -682,6 +684,7 @@ static void ivshmem_read(void *opaque, const uint8_t *buf, int size)
}
memory_region_init_ram_ptr(&s->ivshmem, OBJECT(s),
"ivshmem.bar2", s->ivshmem_size, map_ptr);
qemu_set_ram_fd(s->ivshmem.ram_addr, incoming_fd);
vmstate_register_ram(&s->ivshmem, DEVICE(s));
IVSHMEM_DPRINTF("guest h/w addr = %p, size = %" PRIu64 "\n",
@ -689,7 +692,6 @@ static void ivshmem_read(void *opaque, const uint8_t *buf, int size)
memory_region_add_subregion(&s->bar, 0, &s->ivshmem);
close(incoming_fd);
return;
}
@ -991,7 +993,6 @@ static void pci_ivshmem_realize(PCIDevice *dev, Error **errp)
}
create_shared_memory_BAR(s, fd, attr, errp);
close(fd);
}
}
@ -1010,11 +1011,15 @@ static void pci_ivshmem_exit(PCIDevice *dev)
if (memory_region_is_mapped(&s->ivshmem)) {
if (!s->hostmem) {
void *addr = memory_region_get_ram_ptr(&s->ivshmem);
int fd;
if (munmap(addr, s->ivshmem_size) == -1) {
error_report("Failed to munmap shared memory %s",
strerror(errno));
}
if ((fd = qemu_get_ram_fd(s->ivshmem.ram_addr)) != -1)
close(fd);
}
vmstate_unregister_ram(&s->ivshmem, DEVICE(dev));

View File

@ -761,7 +761,7 @@ static const IGDHostInfo igd_host_bridge_infos[] = {
{0xa8, 4}, /* SNB: base of GTT stolen memory */
};
static int host_pci_config_read(int pos, int len, uint32_t val)
static int host_pci_config_read(int pos, int len, uint32_t *val)
{
char path[PATH_MAX];
int config_fd;
@ -784,12 +784,14 @@ static int host_pci_config_read(int pos, int len, uint32_t val)
ret = -errno;
goto out;
}
do {
rc = read(config_fd, (uint8_t *)&val, len);
rc = read(config_fd, (uint8_t *)val, len);
} while (rc < 0 && (errno == EINTR || errno == EAGAIN));
if (rc != len) {
ret = -errno;
}
out:
close(config_fd);
return ret;
@ -805,7 +807,7 @@ static int igd_pt_i440fx_initfn(struct PCIDevice *pci_dev)
for (i = 0; i < num; i++) {
pos = igd_host_bridge_infos[i].offset;
len = igd_host_bridge_infos[i].len;
rc = host_pci_config_read(pos, len, val);
rc = host_pci_config_read(pos, len, &val);
if (rc) {
return -ENODEV;
}

View File

@ -713,7 +713,7 @@ static void hpet_init(Object *obj)
HPETState *s = HPET(obj);
/* HPET Area */
memory_region_init_io(&s->iomem, obj, &hpet_ram_ops, s, "hpet", 0x400);
memory_region_init_io(&s->iomem, obj, &hpet_ram_ops, s, "hpet", HPET_LEN);
sysbus_init_mmio(sbd, &s->iomem);
}

View File

@ -1126,33 +1126,15 @@ static bool virtio_extra_state_needed(void *opaque)
k->has_extra_state(qbus->parent);
}
static void put_virtqueue_state(QEMUFile *f, void *pv, size_t size)
{
VirtIODevice *vdev = pv;
int i;
for (i = 0; i < VIRTIO_QUEUE_MAX; i++) {
qemu_put_be64(f, vdev->vq[i].vring.avail);
qemu_put_be64(f, vdev->vq[i].vring.used);
}
}
static int get_virtqueue_state(QEMUFile *f, void *pv, size_t size)
{
VirtIODevice *vdev = pv;
int i;
for (i = 0; i < VIRTIO_QUEUE_MAX; i++) {
vdev->vq[i].vring.avail = qemu_get_be64(f);
vdev->vq[i].vring.used = qemu_get_be64(f);
}
return 0;
}
static VMStateInfo vmstate_info_virtqueue = {
static const VMStateDescription vmstate_virtqueue = {
.name = "virtqueue_state",
.get = get_virtqueue_state,
.put = put_virtqueue_state,
.version_id = 1,
.minimum_version_id = 1,
.fields = (VMStateField[]) {
VMSTATE_UINT64(vring.avail, struct VirtQueue),
VMSTATE_UINT64(vring.used, struct VirtQueue),
VMSTATE_END_OF_LIST()
}
};
static const VMStateDescription vmstate_virtio_virtqueues = {
@ -1161,44 +1143,20 @@ static const VMStateDescription vmstate_virtio_virtqueues = {
.minimum_version_id = 1,
.needed = &virtio_virtqueue_needed,
.fields = (VMStateField[]) {
{
.name = "virtqueues",
.version_id = 0,
.field_exists = NULL,
.size = 0,
.info = &vmstate_info_virtqueue,
.flags = VMS_SINGLE,
.offset = 0,
},
VMSTATE_STRUCT_VARRAY_KNOWN(vq, struct VirtIODevice, VIRTIO_QUEUE_MAX,
0, vmstate_virtqueue, VirtQueue),
VMSTATE_END_OF_LIST()
}
};
static void put_ringsize_state(QEMUFile *f, void *pv, size_t size)
{
VirtIODevice *vdev = pv;
int i;
for (i = 0; i < VIRTIO_QUEUE_MAX; i++) {
qemu_put_be32(f, vdev->vq[i].vring.num_default);
}
}
static int get_ringsize_state(QEMUFile *f, void *pv, size_t size)
{
VirtIODevice *vdev = pv;
int i;
for (i = 0; i < VIRTIO_QUEUE_MAX; i++) {
vdev->vq[i].vring.num_default = qemu_get_be32(f);
}
return 0;
}
static VMStateInfo vmstate_info_ringsize = {
static const VMStateDescription vmstate_ringsize = {
.name = "ringsize_state",
.get = get_ringsize_state,
.put = put_ringsize_state,
.version_id = 1,
.minimum_version_id = 1,
.fields = (VMStateField[]) {
VMSTATE_UINT32(vring.num_default, struct VirtQueue),
VMSTATE_END_OF_LIST()
}
};
static const VMStateDescription vmstate_virtio_ringsize = {
@ -1207,15 +1165,8 @@ static const VMStateDescription vmstate_virtio_ringsize = {
.minimum_version_id = 1,
.needed = &virtio_ringsize_needed,
.fields = (VMStateField[]) {
{
.name = "ringsize",
.version_id = 0,
.field_exists = NULL,
.size = 0,
.info = &vmstate_info_ringsize,
.flags = VMS_SINGLE,
.offset = 0,
},
VMSTATE_STRUCT_VARRAY_KNOWN(vq, struct VirtIODevice, VIRTIO_QUEUE_MAX,
0, vmstate_ringsize, VirtQueue),
VMSTATE_END_OF_LIST()
}
};
@ -1429,7 +1380,7 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id)
num = qemu_get_be32(f);
if (num > VIRTIO_QUEUE_MAX) {
error_report("Invalid number of PCI queues: 0x%x", num);
error_report("Invalid number of virtqueues: 0x%x", num);
return -1;
}

View File

@ -72,6 +72,7 @@ ram_addr_t qemu_ram_alloc_resizeable(ram_addr_t size, ram_addr_t max_size,
void *host),
MemoryRegion *mr, Error **errp);
int qemu_get_ram_fd(ram_addr_t addr);
void qemu_set_ram_fd(ram_addr_t addr, int fd);
void *qemu_get_ram_block_host_ptr(ram_addr_t addr);
void qemu_ram_free(ram_addr_t addr);

View File

@ -16,6 +16,8 @@
#define ACPI_BUILD_RSDP_FILE "etc/acpi/rsdp"
#define ACPI_BUILD_TPMLOG_FILE "etc/tpm/log"
#define AML_NOTIFY_METHOD "NTFY"
typedef enum {
AML_NO_OPCODE = 0,/* has only data */
AML_OPCODE, /* has opcode optionally followed by data */
@ -80,6 +82,7 @@ typedef enum {
typedef enum {
AML_SYSTEM_MEMORY = 0X00,
AML_SYSTEM_IO = 0X01,
AML_PCI_CONFIG = 0X02,
} AmlRegionSpace;
typedef enum {

View File

@ -14,6 +14,7 @@
#include "hw/acpi/acpi.h"
#include "hw/acpi/pc-hotplug.h"
#include "hw/acpi/aml-build.h"
typedef struct AcpiCpuHotplug {
MemoryRegion io;
@ -25,4 +26,13 @@ void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq,
void acpi_cpu_hotplug_init(MemoryRegion *parent, Object *owner,
AcpiCpuHotplug *gpe_cpu, uint16_t base);
#define CPU_EJECT_METHOD "CPEJ"
#define CPU_MAT_METHOD "CPMA"
#define CPU_ON_BITMAP "CPON"
#define CPU_STATUS_METHOD "CPST"
#define CPU_STATUS_MAP "PRS"
#define CPU_SCAN_METHOD "PRSC"
void build_cpu_hotplug_aml(Aml *ctx);
#endif

View File

@ -4,6 +4,7 @@
#include "hw/qdev-core.h"
#include "hw/acpi/acpi.h"
#include "migration/vmstate.h"
#include "hw/acpi/aml-build.h"
/**
* MemStatus:
@ -45,4 +46,12 @@ extern const VMStateDescription vmstate_memory_hotplug;
vmstate_memory_hotplug, MemHotplugState)
void acpi_memory_ospm_status(MemHotplugState *mem_st, ACPIOSTInfoList ***list);
#define MEMORY_HOTPLUG_DEVICE "MHPD"
#define MEMORY_SLOT_SCAN_METHOD "MSCN"
#define MEMORY_HOTPLUG_HANDLER_PATH "\\_SB.PCI0." \
MEMORY_HOTPLUG_DEVICE "." MEMORY_SLOT_SCAN_METHOD
void build_memory_hotplug_aml(Aml *ctx, uint32_t nr_mem,
uint16_t io_base, uint16_t io_len);
#endif

View File

@ -32,28 +32,26 @@
#define ACPI_MEMORY_HOTPLUG_IO_LEN 24
#define ACPI_MEMORY_HOTPLUG_BASE 0x0a00
#define MEMORY_HOTPLUG_DEVICE MHPD
#define MEMORY_SLOTS_NUMBER MDNR
#define MEMORY_HOTPLUG_IO_REGION HPMR
#define MEMORY_SLOT_ADDR_LOW MRBL
#define MEMORY_SLOT_ADDR_HIGH MRBH
#define MEMORY_SLOT_SIZE_LOW MRLL
#define MEMORY_SLOT_SIZE_HIGH MRLH
#define MEMORY_SLOT_PROXIMITY MPX
#define MEMORY_SLOT_ENABLED MES
#define MEMORY_SLOT_INSERT_EVENT MINS
#define MEMORY_SLOT_REMOVE_EVENT MRMV
#define MEMORY_SLOT_EJECT MEJ
#define MEMORY_SLOT_SLECTOR MSEL
#define MEMORY_SLOT_OST_EVENT MOEV
#define MEMORY_SLOT_OST_STATUS MOSC
#define MEMORY_SLOT_LOCK MLCK
#define MEMORY_SLOT_STATUS_METHOD MRST
#define MEMORY_SLOT_CRS_METHOD MCRS
#define MEMORY_SLOT_OST_METHOD MOST
#define MEMORY_SLOT_PROXIMITY_METHOD MPXM
#define MEMORY_SLOT_EJECT_METHOD MEJ0
#define MEMORY_SLOT_NOTIFY_METHOD MTFY
#define MEMORY_SLOT_SCAN_METHOD MSCN
#define MEMORY_SLOTS_NUMBER "MDNR"
#define MEMORY_HOTPLUG_IO_REGION "HPMR"
#define MEMORY_SLOT_ADDR_LOW "MRBL"
#define MEMORY_SLOT_ADDR_HIGH "MRBH"
#define MEMORY_SLOT_SIZE_LOW "MRLL"
#define MEMORY_SLOT_SIZE_HIGH "MRLH"
#define MEMORY_SLOT_PROXIMITY "MPX"
#define MEMORY_SLOT_ENABLED "MES"
#define MEMORY_SLOT_INSERT_EVENT "MINS"
#define MEMORY_SLOT_REMOVE_EVENT "MRMV"
#define MEMORY_SLOT_EJECT "MEJ"
#define MEMORY_SLOT_SLECTOR "MSEL"
#define MEMORY_SLOT_OST_EVENT "MOEV"
#define MEMORY_SLOT_OST_STATUS "MOSC"
#define MEMORY_SLOT_LOCK "MLCK"
#define MEMORY_SLOT_STATUS_METHOD "MRST"
#define MEMORY_SLOT_CRS_METHOD "MCRS"
#define MEMORY_SLOT_OST_METHOD "MOST"
#define MEMORY_SLOT_PROXIMITY_METHOD "MPXM"
#define MEMORY_SLOT_EJECT_METHOD "MEJ0"
#define MEMORY_SLOT_NOTIFY_METHOD "MTFY"
#endif

View File

@ -267,6 +267,8 @@ typedef void (*cpu_set_smm_t)(int smm, void *arg);
void ioapic_init_gsi(GSIState *gsi_state, const char *parent_name);
ISADevice *pc_find_fdc0(void);
/* acpi_piix.c */
I2CBus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,

View File

@ -16,6 +16,7 @@
#include "qom/object.h"
#define HPET_BASE 0xfed00000
#define HPET_LEN 0x400
#define HPET_CLK_PERIOD 10 /* 10 ns*/
#define FS_PER_NS 1000000 /* 1000000 femtoseconds == 1 ns */

View File

@ -374,6 +374,19 @@ extern const VMStateInfo vmstate_info_bitmap;
.offset = vmstate_offset_array(_state, _field, _type, _num),\
}
/* a variable length array (i.e. _type *_field) but we know the
* length
*/
#define VMSTATE_STRUCT_VARRAY_KNOWN(_field, _state, _num, _version, _vmsd, _type) { \
.name = (stringify(_field)), \
.num = (_num), \
.version_id = (_version), \
.vmsd = &(_vmsd), \
.size = sizeof(_type), \
.flags = VMS_STRUCT|VMS_ARRAY, \
.offset = offsetof(_state, _field), \
}
#define VMSTATE_STRUCT_VARRAY_UINT8(_field, _state, _field_num, _version, _vmsd, _type) { \
.name = (stringify(_field)), \
.num_offset = vmstate_offset_value(_state, _field_num, uint8_t), \

View File

@ -1,367 +0,0 @@
#!/usr/bin/python
# Copyright (C) 2011 Red Hat, Inc., 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/>.
# Process mixed ASL/AML listing (.lst file) produced by iasl -l
# Locate and execute ACPI_EXTRACT directives, output offset info
#
# Documentation of ACPI_EXTRACT_* directive tags:
#
# These directive tags output offset information from AML for BIOS runtime
# table generation.
# Each directive is of the form:
# ACPI_EXTRACT_<TYPE> <array_name> <Operator> (...)
# and causes the extractor to create an array
# named <array_name> with offset, in the generated AML,
# of an object of a given type in the following <Operator>.
#
# A directive must fit on a single code line.
#
# Object type in AML is verified, a mismatch causes a build failure.
#
# Directives and operators currently supported are:
# ACPI_EXTRACT_NAME_DWORD_CONST - extract a Dword Const object from Name()
# ACPI_EXTRACT_NAME_WORD_CONST - extract a Word Const object from Name()
# ACPI_EXTRACT_NAME_BYTE_CONST - extract a Byte Const object from Name()
# ACPI_EXTRACT_METHOD_STRING - extract a NameString from Method()
# ACPI_EXTRACT_NAME_STRING - extract a NameString from Name()
# ACPI_EXTRACT_PROCESSOR_START - start of Processor() block
# ACPI_EXTRACT_PROCESSOR_STRING - extract a NameString from Processor()
# ACPI_EXTRACT_PROCESSOR_END - offset at last byte of Processor() + 1
# ACPI_EXTRACT_PKG_START - start of Package block
#
# ACPI_EXTRACT_ALL_CODE - create an array storing the generated AML bytecode
#
# ACPI_EXTRACT is not allowed anywhere else in code, except in comments.
import re;
import sys;
import fileinput;
aml = []
asl = []
output = {}
debug = ""
class asl_line:
line = None
lineno = None
aml_offset = None
def die(diag):
sys.stderr.write("Error: %s; %s\n" % (diag, debug))
sys.exit(1)
#Store an ASL command, matching AML offset, and input line (for debugging)
def add_asl(lineno, line):
l = asl_line()
l.line = line
l.lineno = lineno
l.aml_offset = len(aml)
asl.append(l)
#Store an AML byte sequence
#Verify that offset output by iasl matches # of bytes so far
def add_aml(offset, line):
o = int(offset, 16);
# Sanity check: offset must match size of code so far
if (o != len(aml)):
die("Offset 0x%x != 0x%x" % (o, len(aml)))
# Strip any trailing dots and ASCII dump after "
line = re.sub(r'\s*\.*\s*".*$',"", line)
# Strip traling whitespace
line = re.sub(r'\s+$',"", line)
# Strip leading whitespace
line = re.sub(r'^\s+',"", line)
# Split on whitespace
code = re.split(r'\s+', line)
for c in code:
# Require a legal hex number, two digits
if (not(re.search(r'^[0-9A-Fa-f][0-9A-Fa-f]$', c))):
die("Unexpected octet %s" % c);
aml.append(int(c, 16));
# Process aml bytecode array, decoding AML
def aml_pkglen_bytes(offset):
# PkgLength can be multibyte. Bits 8-7 give the # of extra bytes.
pkglenbytes = aml[offset] >> 6;
return pkglenbytes + 1
def aml_pkglen(offset):
pkgstart = offset
pkglenbytes = aml_pkglen_bytes(offset)
pkglen = aml[offset] & 0x3F
# If multibyte, first nibble only uses bits 0-3
if ((pkglenbytes > 1) and (pkglen & 0x30)):
die("PkgLen bytes 0x%x but first nibble 0x%x expected 0x0X" %
(pkglen, pkglen))
offset += 1
pkglenbytes -= 1
for i in range(pkglenbytes):
pkglen |= aml[offset + i] << (i * 8 + 4)
if (len(aml) < pkgstart + pkglen):
die("PckgLen 0x%x at offset 0x%x exceeds AML size 0x%x" %
(pkglen, offset, len(aml)))
return pkglen
# Given method offset, find its NameString offset
def aml_method_string(offset):
#0x14 MethodOp PkgLength NameString MethodFlags TermList
if (aml[offset] != 0x14):
die( "Method offset 0x%x: expected 0x14 actual 0x%x" %
(offset, aml[offset]));
offset += 1;
pkglenbytes = aml_pkglen_bytes(offset)
offset += pkglenbytes;
return offset;
# Given name offset, find its NameString offset
def aml_name_string(offset):
#0x08 NameOp NameString DataRef
if (aml[offset] != 0x08):
die( "Name offset 0x%x: expected 0x08 actual 0x%x" %
(offset, aml[offset]));
offset += 1
# Block Name Modifier. Skip it.
if (aml[offset] == 0x5c or aml[offset] == 0x5e):
offset += 1
return offset;
# Given data offset, find variable length byte buffer offset
def aml_data_buffer(offset, length):
#0x11 PkgLength BufferSize ByteList
if (length > 63):
die( "Name offset 0x%x: expected a one byte PkgLength (length<=63)" %
(offset));
expect = [0x11, length+3, 0x0A, length]
if (aml[offset:offset+4] != expect):
die( "Name offset 0x%x: expected %s actual %s" %
(offset, expect, aml[offset:offset+4]))
return offset + len(expect)
# Given data offset, find dword const offset
def aml_data_dword_const(offset):
#0x08 NameOp NameString DataRef
if (aml[offset] != 0x0C):
die( "Name offset 0x%x: expected 0x0C actual 0x%x" %
(offset, aml[offset]));
return offset + 1;
# Given data offset, find word const offset
def aml_data_word_const(offset):
#0x08 NameOp NameString DataRef
if (aml[offset] != 0x0B):
die( "Name offset 0x%x: expected 0x0B actual 0x%x" %
(offset, aml[offset]));
return offset + 1;
# Given data offset, find byte const offset
def aml_data_byte_const(offset):
#0x08 NameOp NameString DataRef
if (aml[offset] != 0x0A):
die( "Name offset 0x%x: expected 0x0A actual 0x%x" %
(offset, aml[offset]));
return offset + 1;
# Find name'd buffer
def aml_name_buffer(offset, length):
return aml_data_buffer(aml_name_string(offset) + 4, length)
# Given name offset, find dword const offset
def aml_name_dword_const(offset):
return aml_data_dword_const(aml_name_string(offset) + 4)
# Given name offset, find word const offset
def aml_name_word_const(offset):
return aml_data_word_const(aml_name_string(offset) + 4)
# Given name offset, find byte const offset
def aml_name_byte_const(offset):
return aml_data_byte_const(aml_name_string(offset) + 4)
def aml_device_start(offset):
#0x5B 0x82 DeviceOp PkgLength NameString
if ((aml[offset] != 0x5B) or (aml[offset + 1] != 0x82)):
die( "Name offset 0x%x: expected 0x5B 0x82 actual 0x%x 0x%x" %
(offset, aml[offset], aml[offset + 1]));
return offset
def aml_device_string(offset):
#0x5B 0x82 DeviceOp PkgLength NameString
start = aml_device_start(offset)
offset += 2
pkglenbytes = aml_pkglen_bytes(offset)
offset += pkglenbytes
return offset
def aml_device_end(offset):
start = aml_device_start(offset)
offset += 2
pkglenbytes = aml_pkglen_bytes(offset)
pkglen = aml_pkglen(offset)
return offset + pkglen
def aml_processor_start(offset):
#0x5B 0x83 ProcessorOp PkgLength NameString ProcID
if ((aml[offset] != 0x5B) or (aml[offset + 1] != 0x83)):
die( "Name offset 0x%x: expected 0x5B 0x83 actual 0x%x 0x%x" %
(offset, aml[offset], aml[offset + 1]));
return offset
def aml_processor_string(offset):
#0x5B 0x83 ProcessorOp PkgLength NameString ProcID
start = aml_processor_start(offset)
offset += 2
pkglenbytes = aml_pkglen_bytes(offset)
offset += pkglenbytes
return offset
def aml_processor_end(offset):
start = aml_processor_start(offset)
offset += 2
pkglenbytes = aml_pkglen_bytes(offset)
pkglen = aml_pkglen(offset)
return offset + pkglen
def aml_package_start(offset):
offset = aml_name_string(offset) + 4
# 0x12 PkgLength NumElements PackageElementList
if (aml[offset] != 0x12):
die( "Name offset 0x%x: expected 0x12 actual 0x%x" %
(offset, aml[offset]));
offset += 1
return offset + aml_pkglen_bytes(offset) + 1
lineno = 0
for line in fileinput.input():
# Strip trailing newline
line = line.rstrip();
# line number and debug string to output in case of errors
lineno = lineno + 1
debug = "input line %d: %s" % (lineno, line)
#ASL listing: space, then line#, then ...., then code
pasl = re.compile('^\s+([0-9]+)(:\s\s|\.\.\.\.)\s*')
m = pasl.search(line)
if (m):
add_asl(lineno, pasl.sub("", line));
# AML listing: offset in hex, then ...., then code
paml = re.compile('^([0-9A-Fa-f]+)(:\s\s|\.\.\.\.)\s*')
m = paml.search(line)
if (m):
add_aml(m.group(1), paml.sub("", line))
# Now go over code
# Track AML offset of a previous non-empty ASL command
prev_aml_offset = -1
for i in range(len(asl)):
debug = "input line %d: %s" % (asl[i].lineno, asl[i].line)
l = asl[i].line
# skip if not an extract directive
a = len(re.findall(r'ACPI_EXTRACT', l))
if (not a):
# If not empty, store AML offset. Will be used for sanity checks
# IASL seems to put {}. at random places in the listing.
# Ignore any non-words for the purpose of this test.
m = re.search(r'\w+', l)
if (m):
prev_aml_offset = asl[i].aml_offset
continue
if (a > 1):
die("Expected at most one ACPI_EXTRACT per line, actual %d" % a)
mext = re.search(r'''
^\s* # leading whitespace
/\*\s* # start C comment
(ACPI_EXTRACT_\w+) # directive: group(1)
\s+ # whitspace separates directive from array name
(\w+) # array name: group(2)
\s*\*/ # end of C comment
\s*$ # trailing whitespace
''', l, re.VERBOSE)
if (not mext):
die("Stray ACPI_EXTRACT in input")
# previous command must have produced some AML,
# otherwise we are in a middle of a block
if (prev_aml_offset == asl[i].aml_offset):
die("ACPI_EXTRACT directive in the middle of a block")
directive = mext.group(1)
array = mext.group(2)
offset = asl[i].aml_offset
if (directive == "ACPI_EXTRACT_ALL_CODE"):
if array in output:
die("%s directive used more than once" % directive)
output[array] = aml
continue
if (directive == "ACPI_EXTRACT_NAME_BUFFER8"):
offset = aml_name_buffer(offset, 8)
elif (directive == "ACPI_EXTRACT_NAME_BUFFER16"):
offset = aml_name_buffer(offset, 16)
elif (directive == "ACPI_EXTRACT_NAME_DWORD_CONST"):
offset = aml_name_dword_const(offset)
elif (directive == "ACPI_EXTRACT_NAME_WORD_CONST"):
offset = aml_name_word_const(offset)
elif (directive == "ACPI_EXTRACT_NAME_BYTE_CONST"):
offset = aml_name_byte_const(offset)
elif (directive == "ACPI_EXTRACT_NAME_STRING"):
offset = aml_name_string(offset)
elif (directive == "ACPI_EXTRACT_METHOD_STRING"):
offset = aml_method_string(offset)
elif (directive == "ACPI_EXTRACT_DEVICE_START"):
offset = aml_device_start(offset)
elif (directive == "ACPI_EXTRACT_DEVICE_STRING"):
offset = aml_device_string(offset)
elif (directive == "ACPI_EXTRACT_DEVICE_END"):
offset = aml_device_end(offset)
elif (directive == "ACPI_EXTRACT_PROCESSOR_START"):
offset = aml_processor_start(offset)
elif (directive == "ACPI_EXTRACT_PROCESSOR_STRING"):
offset = aml_processor_string(offset)
elif (directive == "ACPI_EXTRACT_PROCESSOR_END"):
offset = aml_processor_end(offset)
elif (directive == "ACPI_EXTRACT_PKG_START"):
offset = aml_package_start(offset)
else:
die("Unsupported directive %s" % directive)
if array not in output:
output[array] = []
output[array].append(offset)
debug = "at end of file"
def get_value_type(maxvalue):
#Use type large enough to fit the table
if (maxvalue >= 0x10000):
return "int"
elif (maxvalue >= 0x100):
return "short"
else:
return "char"
# Pretty print output
for array in output.keys():
otype = get_value_type(max(output[array]))
odata = []
for value in output[array]:
odata.append("0x%x" % value)
sys.stdout.write("static unsigned %s %s[] = {\n" % (otype, array))
sys.stdout.write(",\n".join(odata))
sys.stdout.write('\n};\n');

View File

@ -1,51 +0,0 @@
#!/usr/bin/python
# Copyright (C) 2011 Red Hat, Inc., 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/>.
# Read a preprocessed ASL listing and put each ACPI_EXTRACT
# directive in a comment, to make iasl skip it.
# We also put each directive on a new line, the machinery
# in tools/acpi_extract.py requires this.
import re;
import sys;
import fileinput;
def die(diag):
sys.stderr.write("Error: %s\n" % (diag))
sys.exit(1)
# Note: () around pattern make split return matched string as part of list
psplit = re.compile(r''' (
\b # At word boundary
ACPI_EXTRACT_\w+ # directive
\s+ # some whitespace
\w+ # array name
)''', re.VERBOSE);
lineno = 0
for line in fileinput.input():
# line number and debug string to output in case of errors
lineno = lineno + 1
debug = "input line %d: %s" % (lineno, line.rstrip())
s = psplit.split(line);
# The way split works, each odd item is the matching ACPI_EXTRACT directive.
# Put each in a comment, and on a line by itself.
for i in range(len(s)):
if (i % 2):
sys.stdout.write("\n/* %s */\n" % s[i])
else:
sys.stdout.write(s[i])

View File

@ -1,4 +0,0 @@
cd x86_64-softmmu
for file in hw/i386/*.hex; do
cp -f $file ../$file.generated
done

View File

@ -580,6 +580,22 @@ static void test_acpi_asl(test_data *data)
(gchar *)&signature,
sdt->asl_file, sdt->aml_file,
exp_sdt->asl_file, exp_sdt->aml_file);
if (getenv("V")) {
const char *diff_cmd = getenv("DIFF");
if (diff_cmd) {
int ret G_GNUC_UNUSED;
char *diff = g_strdup_printf("%s %s %s", diff_cmd,
exp_sdt->asl_file, sdt->asl_file);
ret = system(diff) ;
g_free(diff);
} else {
fprintf(stderr, "acpi-test: Warning. not showing "
"difference since no diff utility is specified. "
"Set 'DIFF' environment variable to a preferred "
"diff utility and run 'make V=1 check' again to "
"see ASL difference.");
}
}
}
}
g_string_free(asl, true);