From patchwork Mon Feb 17 14:51:39 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Gabriel L. Somlo" X-Patchwork-Id: 321027 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3D7442C00B3 for ; Tue, 18 Feb 2014 01:53:59 +1100 (EST) Received: from localhost ([::1]:41271 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WFPa1-0007cB-4o for incoming@patchwork.ozlabs.org; Mon, 17 Feb 2014 09:53:57 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:47419) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WFPZd-0007bY-OR for qemu-devel@nongnu.org; Mon, 17 Feb 2014 09:53:39 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1WFPZX-0007kQ-Sl for qemu-devel@nongnu.org; Mon, 17 Feb 2014 09:53:33 -0500 Received: from mail-qc0-x22f.google.com ([2607:f8b0:400d:c01::22f]:42393) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WFPZX-0007kC-N6 for qemu-devel@nongnu.org; Mon, 17 Feb 2014 09:53:27 -0500 Received: by mail-qc0-f175.google.com with SMTP id x13so23531058qcv.6 for ; Mon, 17 Feb 2014 06:53:26 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=date:from:to:cc:subject:message-id:references:mime-version :content-type:content-disposition:in-reply-to:user-agent; bh=r87MxmAgLkCU+oq1uUPjODQwk+aSftgFDv6Y3FAIJEc=; b=Wlbk+1KYDbJ/NLVsRckmHj14d10MUiUn72bjV7BOpp2WNjO5qJOZAaaaCqDgfGisz/ SUx48BDHa8IlKr5WyeS0ToG1Uvxms5p4wzLCJIk6VP2Ipe+w+0vqX9OO2RDB321PCUQE N/VGppitxC2ewaB8M5sayamJ+u3xBD7SnaBnyktGEmFGUQ4R8x9LMHdBJbaoXtoQwCJo Rl9r9s75BFQsBNJkm0XObSFPp1RBLNOmJxdV8D/Sq6lvtjaaqZz7tYd/aP8jELGiYCus oVh/FwS1NS5CzG8NP7F+S9SOSZWFKWZqOGJIlcnyHG4LQlReOmCb0GJzEtPzClYSZ8ON 40DA== X-Received: by 10.224.166.137 with SMTP id m9mr2975039qay.81.1392648806793; Mon, 17 Feb 2014 06:53:26 -0800 (PST) Received: from ERROL.INI.CMU.EDU (ERROL.INI.CMU.EDU. [128.2.16.43]) by mx.google.com with ESMTPSA id r40sm22297840qga.23.2014.02.17.06.53.26 for (version=TLSv1 cipher=RC4-SHA bits=128/128); Mon, 17 Feb 2014 06:53:26 -0800 (PST) Date: Mon, 17 Feb 2014 09:51:39 -0500 From: "Gabriel L. Somlo" To: "Michael S. Tsirkin" Message-ID: <20140217145138.GJ29329@ERROL.INI.CMU.EDU> References: <1392647087-23020-1-git-send-email-mst@redhat.com> <1392647087-23020-2-git-send-email-mst@redhat.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <1392647087-23020-2-git-send-email-mst@redhat.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2607:f8b0:400d:c01::22f Cc: Peter Maydell , qemu-devel@nongnu.org, Anthony Liguori Subject: Re: [Qemu-devel] [PULL 1/5] acpi-build: append description for non-hotplug X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Michael, On Mon, Feb 17, 2014 at 04:25:26PM +0200, Michael S. Tsirkin wrote: > As reported in > http://article.gmane.org/gmane.comp.emulators.qemu/253987 > Mac OSX actually requires describing all occupied slots > in ACPI - even if hotplug isn't enabled. > > I didn't expect this so I dropped description of all > non hotpluggable slots from ACPI. > As a result: before > commit 99fd437dee468609de8218f0eb3b16621fb6a9c9 (enable > hotplug for pci bridges), PCI cards show up in the "device tree" of OS X > (System Information). E.g., on MountainLion users have: > > ... > > Ethernet still works, but it's not showing up on the PCI bus, and it > no longer thinks it's plugged in to slot #2, as it used to before the > change. > > To fix, append description for all occupied non hotpluggable PCI slots. > > One need to be careful when doing this: VGA and ISA device were already > described, so we need to drop description from DSDT. > > Reported-by: Gabriel L. Somlo > Signed-off-by: Michael S. Tsirkin > --- > ... With this latest version of your patch, I crash during OS X boot with "unable to find driver for this platform:\"ACPI\".\n"@/SourceCache/xnu/xnu-2050.48.12/iokit/Kernel/IOPlatformExpert.cpp:1514" Your original patch (slightly doctored since it no longer applies cleanly to the current qemu git master) is included below, and still works for me. Thanks, --Gabriel diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index b1a7ebb..4cc8a92 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -643,6 +643,13 @@ static inline char acpi_get_hex(uint32_t val) #define ACPI_PCIHP_SIZEOF (*ssdt_pcihp_end - *ssdt_pcihp_start) #define ACPI_PCIHP_AML (ssdp_pcihp_aml + *ssdt_pcihp_start) +#define ACPI_PCINOHP_OFFSET_HEX (*ssdt_pcinohp_name - *ssdt_pcinohp_start + 1) +#define ACPI_PCINOHP_OFFSET_ID (*ssdt_pcinohp_id - *ssdt_pcinohp_start) +#define ACPI_PCINOHP_OFFSET_ADR (*ssdt_pcinohp_adr - *ssdt_pcinohp_start) +#define ACPI_PCINOHP_OFFSET_EJ0 (*ssdt_pcinohp_ej0 - *ssdt_pcinohp_start) +#define ACPI_PCINOHP_SIZEOF (*ssdt_pcinohp_end - *ssdt_pcinohp_start) +#define ACPI_PCINOHP_AML (ssdp_pcihp_aml + *ssdt_pcinohp_start) + #define ACPI_SSDT_SIGNATURE 0x54445353 /* SSDT */ #define ACPI_SSDT_HEADER_LENGTH 36 @@ -677,6 +684,16 @@ static void patch_pcihp(int slot, uint8_t *ssdt_ptr) ssdt_ptr[ACPI_PCIHP_OFFSET_ADR + 2] = slot; } +static void patch_pcinohp(int slot, uint8_t *ssdt_ptr) +{ + unsigned devfn = PCI_DEVFN(slot, 0); + + ssdt_ptr[ACPI_PCINOHP_OFFSET_HEX] = acpi_get_hex(devfn >> 4); + ssdt_ptr[ACPI_PCINOHP_OFFSET_HEX + 1] = acpi_get_hex(devfn); + ssdt_ptr[ACPI_PCINOHP_OFFSET_ID] = slot; + ssdt_ptr[ACPI_PCINOHP_OFFSET_ADR + 2] = slot; +} + /* Assign BSEL property to all buses. In the future, this can be changed * to only assign to buses that support hotplug. */ @@ -737,6 +754,7 @@ static void build_pci_bus_end(PCIBus *bus, void *bus_state) AcpiBuildPciBusHotplugState *parent = child->parent; GArray *bus_table = build_alloc_array(); DECLARE_BITMAP(slot_hotplug_enable, PCI_SLOT_MAX); + DECLARE_BITMAP(slot_device_present, PCI_SLOT_MAX); uint8_t op; int i; QObject *bsel; @@ -764,40 +782,51 @@ static void build_pci_bus_end(PCIBus *bus, void *bus_state) build_append_byte(bus_table, 0x08); /* NameOp */ build_append_nameseg(bus_table, "BSEL"); build_append_int(bus_table, qint_get_int(qobject_to_qint(bsel))); + } - memset(slot_hotplug_enable, 0xff, sizeof slot_hotplug_enable); + memset(slot_hotplug_enable, 0xff, sizeof slot_hotplug_enable); + memset(slot_device_present, 0x00, sizeof slot_device_present); - for (i = 0; i < ARRAY_SIZE(bus->devices); ++i) { - DeviceClass *dc; - PCIDeviceClass *pc; - PCIDevice *pdev = bus->devices[i]; + for (i = 0; i < ARRAY_SIZE(bus->devices); ++i) { + DeviceClass *dc; + PCIDeviceClass *pc; + PCIDevice *pdev = bus->devices[i]; + int slot = PCI_SLOT(i); - if (!pdev) { - continue; - } + if (!pdev) { + continue; + } - pc = PCI_DEVICE_GET_CLASS(pdev); - dc = DEVICE_GET_CLASS(pdev); + set_bit(slot, slot_device_present); + pc = PCI_DEVICE_GET_CLASS(pdev); + dc = DEVICE_GET_CLASS(pdev); - if (!dc->hotpluggable || pc->is_bridge) { - int slot = PCI_SLOT(i); + if (!dc->hotpluggable || pc->is_bridge) { + int slot = PCI_SLOT(i); - clear_bit(slot, slot_hotplug_enable); - } + clear_bit(slot, slot_hotplug_enable); } + } - /* Append Device object for each slot which supports eject */ - for (i = 0; i < PCI_SLOT_MAX; i++) { - bool can_eject = test_bit(i, slot_hotplug_enable); - if (can_eject) { - void *pcihp = acpi_data_push(bus_table, - ACPI_PCIHP_SIZEOF); - memcpy(pcihp, ACPI_PCIHP_AML, ACPI_PCIHP_SIZEOF); - patch_pcihp(i, pcihp); - bus_hotplug_support = true; - } + /* Append Device object for each slot which supports eject */ + for (i = 0; i < PCI_SLOT_MAX; i++) { + bool can_eject = test_bit(i, slot_hotplug_enable); + bool present = test_bit(i, slot_device_present); + if (can_eject) { + void *pcihp = acpi_data_push(bus_table, + ACPI_PCIHP_SIZEOF); + memcpy(pcihp, ACPI_PCIHP_AML, ACPI_PCIHP_SIZEOF); + patch_pcihp(i, pcihp); + bus_hotplug_support = true; + } else if (present) { + void *pcihp = acpi_data_push(bus_table, + ACPI_PCIHP_SIZEOF); + memcpy(pcihp, ACPI_PCINOHP_AML, ACPI_PCINOHP_SIZEOF); + patch_pcinohp(i, pcihp); } + } + if (bsel) { method = build_alloc_method("DVNT", 2); for (i = 0; i < PCI_SLOT_MAX; i++) { @@ -976,7 +1005,14 @@ build_ssdt(GArray *table_data, GArray *linker, { AcpiBuildPciBusHotplugState hotplug_state; - PCIBus *bus = find_i440fx(); /* TODO: Q35 support */ + Object *pci_host; + PCIBus *bus = NULL; + bool ambiguous; + + pci_host = object_resolve_path_type("", TYPE_PCI_HOST_BRIDGE, &ambiguous); + if (!ambiguous && pci_host) { + bus = PCI_HOST_BRIDGE(pci_host)->bus; + } build_pci_bus_state_init(&hotplug_state, NULL); diff --git a/hw/i386/ssdt-pcihp.dsl b/hw/i386/ssdt-pcihp.dsl index cc245c3..ea4b9e1 100644 --- a/hw/i386/ssdt-pcihp.dsl +++ b/hw/i386/ssdt-pcihp.dsl @@ -46,5 +46,17 @@ DefinitionBlock ("ssdt-pcihp.aml", "SSDT", 0x01, "BXPC", "BXSSDTPCIHP", 0x1) } } + ACPI_EXTRACT_DEVICE_START ssdt_pcinohp_start + ACPI_EXTRACT_DEVICE_END ssdt_pcinohp_end + ACPI_EXTRACT_DEVICE_STRING ssdt_pcinohp_name + + // Extract the offsets of the device name, address dword and the slot + // name byte - we fill them in for each device. + Device(SBB) { + ACPI_EXTRACT_NAME_BYTE_CONST ssdt_pcinohp_id + Name(_SUN, 0xAA) + ACPI_EXTRACT_NAME_DWORD_CONST ssdt_pcinohp_adr + Name(_ADR, 0xAA0000) + } } }