Mon Oct 15 11:35:03 2018 UTC ()
Add ARM ACPI PCI support.


(jmcneill)
diff -r1.1 -r1.2 src/sys/arch/arm/acpi/acpi_machdep.c
diff -r1.1 -r1.2 src/sys/arch/arm/acpi/files.acpi
diff -r0 -r1.1 src/sys/arch/arm/acpi/acpi_pci_machdep.c
diff -r0 -r1.1 src/sys/arch/arm/acpi/acpi_pci_machdep.h
diff -r0 -r1.1 src/sys/arch/arm/acpi/acpipchb.c
diff -r1.2 -r1.3 src/sys/arch/arm/fdt/acpi_fdt.c

cvs diff -r1.1 -r1.2 src/sys/arch/arm/acpi/acpi_machdep.c (expand / switch to unified diff)

--- src/sys/arch/arm/acpi/acpi_machdep.c 2018/10/12 22:12:11 1.1
+++ src/sys/arch/arm/acpi/acpi_machdep.c 2018/10/15 11:35:03 1.2
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: acpi_machdep.c,v 1.1 2018/10/12 22:12:11 jmcneill Exp $ */ 1/* $NetBSD: acpi_machdep.c,v 1.2 2018/10/15 11:35:03 jmcneill Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2018 The NetBSD Foundation, Inc. 4 * Copyright (c) 2018 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Jared McNeill <jmcneill@invisible.ca>. 8 * by Jared McNeill <jmcneill@invisible.ca>.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -20,40 +20,41 @@ @@ -20,40 +20,41 @@
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32#include <sys/cdefs.h> 32#include <sys/cdefs.h>
33__KERNEL_RCSID(0, "$NetBSD: acpi_machdep.c,v 1.1 2018/10/12 22:12:11 jmcneill Exp $"); 33__KERNEL_RCSID(0, "$NetBSD: acpi_machdep.c,v 1.2 2018/10/15 11:35:03 jmcneill Exp $");
34 34
35#include <sys/param.h> 35#include <sys/param.h>
36#include <sys/systm.h> 36#include <sys/systm.h>
37#include <sys/bus.h> 37#include <sys/bus.h>
38#include <sys/cpu.h> 38#include <sys/cpu.h>
39#include <sys/device.h> 39#include <sys/device.h>
40 40
41#include <uvm/uvm_extern.h> 41#include <uvm/uvm_extern.h>
42 42
43#include <dev/fdt/fdtvar.h> 43#include <dev/fdt/fdtvar.h>
44 44
45#include <dev/acpi/acpica.h> 45#include <dev/acpi/acpica.h>
46#include <dev/acpi/acpivar.h> 46#include <dev/acpi/acpivar.h>
 47#include <dev/acpi/acpi_mcfg.h>
47 48
48#include <arm/pic/picvar.h> 49#include <arm/pic/picvar.h>
49 50
50#include <arm/locore.h> 51#include <arm/locore.h>
51 52
52#include <machine/acpi_machdep.h> 53#include <machine/acpi_machdep.h>
53 54
54extern struct bus_space arm_generic_bs_tag; 55extern struct bus_space arm_generic_bs_tag;
55 56
56ACPI_STATUS 57ACPI_STATUS
57acpi_md_OsInitialize(void) 58acpi_md_OsInitialize(void)
58{ 59{
59 return AE_OK; 60 return AE_OK;
@@ -229,26 +230,28 @@ acpi_md_gtdt_probe(ACPI_GTDT_HEADER *hdr @@ -229,26 +230,28 @@ acpi_md_gtdt_probe(ACPI_GTDT_HEADER *hdr
229{ 230{
230 struct acpi_softc * const sc = aux; 231 struct acpi_softc * const sc = aux;
231 232
232 config_found_ia(sc->sc_dev, "acpigtdtbus", hdrp, NULL); 233 config_found_ia(sc->sc_dev, "acpigtdtbus", hdrp, NULL);
233 234
234 return AE_OK; 235 return AE_OK;
235} 236}
236 237
237void 238void
238acpi_md_callback(struct acpi_softc *sc) 239acpi_md_callback(struct acpi_softc *sc)
239{ 240{
240 ACPI_TABLE_HEADER *hdrp; 241 ACPI_TABLE_HEADER *hdrp;
241 242
 243 acpimcfg_init(&arm_generic_bs_tag, NULL);
 244
242 if (acpi_madt_map() != AE_OK) 245 if (acpi_madt_map() != AE_OK)
243 panic("Failed to map MADT"); 246 panic("Failed to map MADT");
244 acpi_madt_walk(acpi_md_madt_probe, sc); 247 acpi_madt_walk(acpi_md_madt_probe, sc);
245 acpi_madt_unmap(); 248 acpi_madt_unmap();
246 249
247 if (acpi_gtdt_map() != AE_OK) 250 if (acpi_gtdt_map() != AE_OK)
248 panic("Failed to map GTDT"); 251 panic("Failed to map GTDT");
249 acpi_gtdt_walk(acpi_md_gtdt_probe, sc); 252 acpi_gtdt_walk(acpi_md_gtdt_probe, sc);
250 acpi_gtdt_unmap(); 253 acpi_gtdt_unmap();
251 254
252 if (ACPI_SUCCESS(AcpiGetTable(ACPI_SIG_GTDT, 0, &hdrp))) 255 if (ACPI_SUCCESS(AcpiGetTable(ACPI_SIG_GTDT, 0, &hdrp)))
253 config_found_ia(sc->sc_dev, "acpisdtbus", hdrp, NULL); 256 config_found_ia(sc->sc_dev, "acpisdtbus", hdrp, NULL);
254} 257}

cvs diff -r1.1 -r1.2 src/sys/arch/arm/acpi/files.acpi (expand / switch to unified diff)

--- src/sys/arch/arm/acpi/files.acpi 2018/10/12 22:20:04 1.1
+++ src/sys/arch/arm/acpi/files.acpi 2018/10/15 11:35:03 1.2
@@ -1,27 +1,32 @@ @@ -1,27 +1,32 @@
1# $NetBSD: files.acpi,v 1.1 2018/10/12 22:20:04 jmcneill Exp $ 1# $NetBSD: files.acpi,v 1.2 2018/10/15 11:35:03 jmcneill Exp $
2# 2#
3# Configuration info for ACPI compliant ARM boards. 3# Configuration info for ACPI compliant ARM boards.
4# 4#
5# 5#
6 6
7device fdc { drive = -1 } # XXX 7device fdc { drive = -1 } # XXX
8include "dev/apm/files.apm" # XXX 8include "dev/apm/files.apm" # XXX
9defflag opt_pcifixup.h ACPI_PCI_FIXUP 9defflag opt_pcifixup.h ACPI_PCI_FIXUP
10 10
11include "dev/acpi/files.acpi" 11include "dev/acpi/files.acpi"
12 12
13file arch/arm/acpi/acpi_machdep.c acpi 13file arch/arm/acpi/acpi_machdep.c acpi
 14file arch/arm/acpi/acpi_pci_machdep.c acpi
14file arch/arm/acpi/acpi_platform.c acpi 15file arch/arm/acpi/acpi_platform.c acpi
15file arch/arm/acpi/acpi_table.c acpi 16file arch/arm/acpi/acpi_table.c acpi
16 17
17attach cpu at acpimadtbus with cpu_acpi 18attach cpu at acpimadtbus with cpu_acpi
18file arch/arm/acpi/cpu_acpi.c cpu_acpi 19file arch/arm/acpi/cpu_acpi.c cpu_acpi
19 20
20attach gic at acpimadtbus with gic_acpi 21attach gic at acpimadtbus with gic_acpi
21file arch/arm/acpi/gic_acpi.c gic_acpi 22file arch/arm/acpi/gic_acpi.c gic_acpi
22 23
23attach gtmr at acpisdtbus with gtmr_acpi 24attach gtmr at acpisdtbus with gtmr_acpi
24file arch/arm/acpi/gtmr_acpi.c gtmr_acpi 25file arch/arm/acpi/gtmr_acpi.c gtmr_acpi
25 26
26attach plcom at acpinodebus with plcom_acpi 27attach plcom at acpinodebus with plcom_acpi
27file arch/arm/acpi/plcom_acpi.c plcom_acpi 28file arch/arm/acpi/plcom_acpi.c plcom_acpi
 29
 30device acpipchb: pcibus
 31attach acpipchb at acpinodebus
 32file arch/arm/acpi/acpipchb.c acpipchb

File Added: src/sys/arch/arm/acpi/acpi_pci_machdep.c
/* $NetBSD: acpi_pci_machdep.c,v 1.1 2018/10/15 11:35:03 jmcneill Exp $ */

/*-
 * Copyright (c) 2018 The NetBSD Foundation, Inc.
 * All rights reserved.
 *
 * This code is derived from software contributed to The NetBSD Foundation
 * by Jared McNeill <jmcneill@invisible.ca>.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: acpi_pci_machdep.c,v 1.1 2018/10/15 11:35:03 jmcneill Exp $");

#include <sys/param.h>
#include <sys/bus.h>
#include <sys/device.h>
#include <sys/intr.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/extent.h>
#include <sys/queue.h>
#include <sys/mutex.h>
#include <sys/kmem.h>

#include <machine/cpu.h>

#include <arm/cpufunc.h>

#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pciconf.h>

#include <dev/acpi/acpivar.h>
#include <dev/acpi/acpi_mcfg.h>
#include <dev/acpi/acpi_pci.h>

#define	IH_INDEX_MASK			0x0000ffff
#define	IH_MPSAFE			0x80000000

struct acpi_pci_prt {
	u_int				prt_bus;
	ACPI_HANDLE			prt_handle;
	TAILQ_ENTRY(acpi_pci_prt)	prt_list;
};

static TAILQ_HEAD(, acpi_pci_prt) acpi_pci_irq_routes =
    TAILQ_HEAD_INITIALIZER(acpi_pci_irq_routes);

static void	acpi_pci_md_attach_hook(device_t, device_t,
				       struct pcibus_attach_args *);
static int	acpi_pci_md_bus_maxdevs(void *, int);
static pcitag_t	acpi_pci_md_make_tag(void *, int, int, int);
static void	acpi_pci_md_decompose_tag(void *, pcitag_t, int *, int *, int *);
static pcireg_t	acpi_pci_md_conf_read(void *, pcitag_t, int);
static void	acpi_pci_md_conf_write(void *, pcitag_t, int, pcireg_t);
static int	acpi_pci_md_conf_hook(void *, int, int, int, pcireg_t);
static void	acpi_pci_md_conf_interrupt(void *, int, int, int, int, int *);

static int	acpi_pci_md_intr_map(const struct pci_attach_args *,
				    pci_intr_handle_t *);
static const char *acpi_pci_md_intr_string(void *, pci_intr_handle_t,
					  char *, size_t);
static const struct evcnt *acpi_pci_md_intr_evcnt(void *, pci_intr_handle_t);
static int	acpi_pci_md_intr_setattr(void *, pci_intr_handle_t *, int,
					uint64_t);
static void *	acpi_pci_md_intr_establish(void *, pci_intr_handle_t,
					 int, int (*)(void *), void *);
static void	acpi_pci_md_intr_disestablish(void *, void *);

struct arm32_pci_chipset arm_acpi_pci_chipset = {
	.pc_attach_hook = acpi_pci_md_attach_hook,
	.pc_bus_maxdevs = acpi_pci_md_bus_maxdevs,
	.pc_make_tag = acpi_pci_md_make_tag,
	.pc_decompose_tag = acpi_pci_md_decompose_tag,
	.pc_conf_read = acpi_pci_md_conf_read,
	.pc_conf_write = acpi_pci_md_conf_write,
	.pc_conf_hook = acpi_pci_md_conf_hook,
	.pc_conf_interrupt = acpi_pci_md_conf_interrupt,

	.pc_intr_map = acpi_pci_md_intr_map,
	.pc_intr_string = acpi_pci_md_intr_string,
	.pc_intr_evcnt = acpi_pci_md_intr_evcnt,
	.pc_intr_setattr = acpi_pci_md_intr_setattr,
	.pc_intr_establish = acpi_pci_md_intr_establish,
	.pc_intr_disestablish = acpi_pci_md_intr_disestablish,
};

static ACPI_STATUS
acpi_pci_md_pci_link(ACPI_HANDLE handle, int bus)
{
	ACPI_PCI_ROUTING_TABLE *prt;
	ACPI_HANDLE linksrc;
	ACPI_BUFFER buf;
	ACPI_STATUS rv;
	void *linkdev;

	rv = acpi_get(handle, &buf, AcpiGetIrqRoutingTable);
	if (ACPI_FAILURE(rv))
		return rv;

	for (char *p = buf.Pointer; ; p += prt->Length) {
		prt = (ACPI_PCI_ROUTING_TABLE *)p;
		if (prt->Length == 0)
			break;

		const u_int dev = ACPI_HIWORD(prt->Address);
		if (prt->Source[0] != 0) {
			aprint_debug("ACPI: %s dev %u INT%c on lnkdev %s\n",
			    acpi_name(handle), dev, 'A' + (prt->Pin & 3), prt->Source);
			rv = AcpiGetHandle(ACPI_ROOT_OBJECT, prt->Source, &linksrc);
			if (ACPI_FAILURE(rv)) {
				aprint_debug("ACPI: AcpiGetHandle failed for '%s': %s\n",
				    prt->Source, AcpiFormatException(rv));
				continue;
			}

			linkdev = acpi_pci_link_devbyhandle(linksrc);
			acpi_pci_link_add_reference(linkdev, 0, bus, dev, prt->Pin & 3);
		} else {
			aprint_debug("ACPI: %s dev %u INT%c on globint %d\n",
			    acpi_name(handle), dev, 'A' + (prt->Pin & 3), prt->SourceIndex);
		}
	}

	return AE_OK;
}

static void
acpi_pci_md_attach_hook(device_t parent, device_t self,
    struct pcibus_attach_args *pba)
{
	struct acpi_pci_prt *prt, *prtp;
	struct acpi_devnode *ad;
	ACPI_HANDLE handle;
	int seg, bus, dev, func;

	seg = 0;	/* XXX segment */
	handle = NULL;

	if (pba->pba_bridgetag) {
		/*
		 * Find the PCI address of our parent bridge and look for the
		 * corresponding ACPI device node. If there is no node for this
		 * bus, use the parent bridge routing information.
		 */
		acpi_pci_md_decompose_tag(NULL, *pba->pba_bridgetag, &bus, &dev, &func);
		ad = acpi_pcidev_find(seg, bus, dev, func);
		if (ad != NULL) {
			handle = ad->ad_handle;
		} else {
			/* No routes defined for this bus, copy from parent */
			TAILQ_FOREACH(prtp, &acpi_pci_irq_routes, prt_list)
				if (prtp->prt_bus == bus) {
					handle = prtp->prt_handle;
					break;
				}
		}
	} else {
		/*
		 * Lookup the ACPI device node for the root bus.
		 */
		ad = acpi_pciroot_find(seg, 0);
		if (ad != NULL)
			handle = ad->ad_handle;
	}

	if (ad != NULL) {
		/*
		 * This is a new ACPI managed bus. Add PCI link references.
		 */
		acpi_pci_md_pci_link(ad->ad_handle, pba->pba_bus);
	}

	if (handle != NULL) {
		prt = kmem_alloc(sizeof(*prt), KM_SLEEP);
		prt->prt_bus = pba->pba_bus;
		prt->prt_handle = handle;
		TAILQ_INSERT_TAIL(&acpi_pci_irq_routes, prt, prt_list);
	}

	acpimcfg_map_bus(self, pba->pba_pc, pba->pba_bus);
}

static int
acpi_pci_md_bus_maxdevs(void *v, int busno)
{
	return 32;
}

static pcitag_t
acpi_pci_md_make_tag(void *v, int b, int d, int f)
{
	return (b << 16) | (d << 11) | (f << 8);
}

static void
acpi_pci_md_decompose_tag(void *v, pcitag_t tag, int *bp, int *dp, int *fp)
{
	if (bp)
		*bp = (tag >> 16) & 0xff;
	if (dp)
		*dp = (tag >> 11) & 0x1f;
	if (fp)
		*fp = (tag >> 8) & 0x7;
}

static pcireg_t
acpi_pci_md_conf_read(void *v, pcitag_t tag, int offset)
{
	pcireg_t val;

	if (offset < 0 || offset >= PCI_EXTCONF_SIZE)
		return (pcireg_t) -1;

	acpimcfg_conf_read(&arm_acpi_pci_chipset, tag, offset, &val);

	return val;
}

static void
acpi_pci_md_conf_write(void *v, pcitag_t tag, int offset, pcireg_t val)
{
	if (offset < 0 || offset >= PCI_EXTCONF_SIZE)
		return;

	acpimcfg_conf_write(&arm_acpi_pci_chipset, tag, offset, val);
}

static int
acpi_pci_md_conf_hook(void *v, int b, int d, int f, pcireg_t id)
{
	return PCI_CONF_DEFAULT;
}

static void
acpi_pci_md_conf_interrupt(void *v, int bus, int dev, int ipin, int sqiz, int *ilinep)
{
}

static struct acpi_pci_prt *
acpi_pci_md_intr_find_prt(u_int bus)
{
	struct acpi_pci_prt *prt, *prtp;

	prt = NULL;
	TAILQ_FOREACH(prtp, &acpi_pci_irq_routes, prt_list)
		if (prtp->prt_bus == bus) {
			prt = prtp;
			break;
		}

	return prt;
}

static int
acpi_pci_md_intr_map(const struct pci_attach_args *pa, pci_intr_handle_t *ih)
{
	struct acpi_pci_prt *prt;
	ACPI_PCI_ROUTING_TABLE *tab;
	int line, pol, trig, error;
	ACPI_HANDLE linksrc;
	ACPI_BUFFER buf;
	void *linkdev;

	if (pa->pa_intrpin == PCI_INTERRUPT_PIN_NONE)
		return EINVAL;

	prt = acpi_pci_md_intr_find_prt(pa->pa_bus);
	if (prt == NULL)
		return ENXIO;

	if (ACPI_FAILURE(acpi_get(prt->prt_handle, &buf, AcpiGetIrqRoutingTable)))
		return EIO;

	error = ENOENT;
	for (char *p = buf.Pointer; ; p += tab->Length) {
		tab = (ACPI_PCI_ROUTING_TABLE *)p;
		if (tab->Length == 0)
			break;

		if (pa->pa_device == ACPI_HIWORD(tab->Address) &&
		    (pa->pa_intrpin - 1) == (tab->Pin & 3)) {
			if (tab->Source[0] != 0) {
				if (ACPI_FAILURE(AcpiGetHandle(ACPI_ROOT_OBJECT, tab->Source, &linksrc)))
					goto done;
				linkdev = acpi_pci_link_devbyhandle(linksrc);
				*ih = acpi_pci_link_route_interrupt(linkdev, tab->SourceIndex,
				    &line, &pol, &trig);
				error = 0;
				goto done;
			} else {
				*ih = tab->SourceIndex;
				error = 0;
				goto done;
			}
		}
	}

done:
	ACPI_FREE(buf.Pointer);
	return error;
}

static const char *
acpi_pci_md_intr_string(void *v, pci_intr_handle_t ih, char *buf, size_t len)
{
	snprintf(buf, len, "irq %d", (int)(ih & IH_INDEX_MASK));
	return buf;
}

static const struct evcnt *
acpi_pci_md_intr_evcnt(void *v, pci_intr_handle_t ih)
{
	return NULL;
}

static int
acpi_pci_md_intr_setattr(void *v, pci_intr_handle_t *ih, int attr, uint64_t data)
{
	switch (attr) {
	case PCI_INTR_MPSAFE:
		if (data)
			*ih |= IH_MPSAFE;
		else
			*ih &= ~IH_MPSAFE;
		return 0;
	default:
		return ENODEV;
	}
}

static void *
acpi_pci_md_intr_establish(void *v, pci_intr_handle_t ih, int ipl,
    int (*callback)(void *), void *arg)
{
	const int irq = ih & IH_INDEX_MASK;
	const int mpsafe = (ih & IH_MPSAFE) ? IST_MPSAFE : 0;

	return intr_establish(irq, ipl, IST_LEVEL | mpsafe, callback, arg);
}

static void
acpi_pci_md_intr_disestablish(void *v, void *vih)
{
	intr_disestablish(vih);
}

File Added: src/sys/arch/arm/acpi/acpi_pci_machdep.h
/* $NetBSD: acpi_pci_machdep.h,v 1.1 2018/10/15 11:35:03 jmcneill Exp $ */

/*-
 * Copyright (c) 2018 The NetBSD Foundation, Inc.
 * All rights reserved.
 *
 * This code is derived from software contributed to The NetBSD Foundation
 * by Jared McNeill <jmcneill@invisible.ca>.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef _ARM_ACPI_PCI_MACHDEP_H
#define _ARM_ACPI_PCI_MACHDEP_H

extern struct arm32_pci_chipset arm_acpi_pci_chipset;

#endif /* !_ARM_ACPI_PCI_MACHDEP_H */

File Added: src/sys/arch/arm/acpi/acpipchb.c
/* $NetBSD: acpipchb.c,v 1.1 2018/10/15 11:35:03 jmcneill Exp $ */

/*-
 * Copyright (c) 2018 The NetBSD Foundation, Inc.
 * All rights reserved.
 *
 * This code is derived from software contributed to The NetBSD Foundation
 * by Jared McNeill <jmcneill@invisible.ca>.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: acpipchb.c,v 1.1 2018/10/15 11:35:03 jmcneill Exp $");

#include <sys/param.h>
#include <sys/bus.h>
#include <sys/device.h>
#include <sys/intr.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/extent.h>
#include <sys/queue.h>
#include <sys/mutex.h>
#include <sys/kmem.h>

#include <machine/cpu.h>

#include <arm/cpufunc.h>

#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pciconf.h>

#include <dev/acpi/acpivar.h>
#include <dev/acpi/acpi_mcfg.h>

#define	PCIHOST_CACHELINE_SIZE		arm_dcache_align

struct acpipchb_softc {
	device_t		sc_dev;

	struct arm32_bus_dma_tag sc_dmat;

	ACPI_HANDLE		sc_handle;
	ACPI_INTEGER		sc_bus;
};

static struct arm32_dma_range ahcipchb_coherent_ranges[] = {
	[0] = {
		.dr_sysbase = 0,
		.dr_busbase = 0,
		.dr_len = UINTPTR_MAX,
		.dr_flags = _BUS_DMAMAP_COHERENT,
	}
};

static int	acpipchb_match(device_t, cfdata_t, void *);
static void	acpipchb_attach(device_t, device_t, void *);

CFATTACH_DECL_NEW(acpipchb, sizeof(struct acpipchb_softc),
	acpipchb_match, acpipchb_attach, NULL, NULL);

static const char * const compatible[] = {
	"PNP0A08",
	NULL
};

static int
acpipchb_match(device_t parent, cfdata_t cf, void *aux)
{
	struct acpi_attach_args *aa = aux;

	if (aa->aa_node->ad_type != ACPI_TYPE_DEVICE)
		return 0;

	return acpi_match_hid(aa->aa_node->ad_devinfo, compatible);
}

static void
acpipchb_attach(device_t parent, device_t self, void *aux)
{
	struct acpipchb_softc * const sc = device_private(self);
	struct acpi_attach_args *aa = aux;
	struct pcibus_attach_args pba;
	ACPI_INTEGER cca;

	sc->sc_dev = self;
	sc->sc_handle = aa->aa_node->ad_handle;

	if (ACPI_FAILURE(acpi_eval_integer(sc->sc_handle, "_BBN", &sc->sc_bus)))
		sc->sc_bus = 0;

	if (ACPI_FAILURE(acpi_eval_integer(sc->sc_handle, "_CCA", &cca)))
		cca = 0;

	aprint_naive("\n");
	aprint_normal(": PCI Express Host Bridge\n");

	if (acpimcfg_configure_bus(self, aa->aa_pc, sc->sc_handle, sc->sc_bus, PCIHOST_CACHELINE_SIZE) != 0) {
		aprint_error_dev(self, "failed to configure PCI bus\n");
		return;
	}

	sc->sc_dmat = *aa->aa_dmat;
	if (cca) {
		sc->sc_dmat._ranges = ahcipchb_coherent_ranges;
		sc->sc_dmat._nranges = __arraycount(ahcipchb_coherent_ranges);
	}

	memset(&pba, 0, sizeof(pba));
	pba.pba_flags = aa->aa_pciflags;
	pba.pba_iot = aa->aa_iot;
	pba.pba_memt = aa->aa_memt;
	pba.pba_dmat = &sc->sc_dmat;
#ifdef _PCI_HAVE_DMA64
	pba.pba_dmat64 = &sc->sc_dmat;
#endif
	pba.pba_pc = aa->aa_pc;
	pba.pba_bus = sc->sc_bus;

	config_found_ia(self, "pcibus", &pba, pcibusprint);
}

cvs diff -r1.2 -r1.3 src/sys/arch/arm/fdt/acpi_fdt.c (expand / switch to unified diff)

--- src/sys/arch/arm/fdt/acpi_fdt.c 2018/10/13 00:15:10 1.2
+++ src/sys/arch/arm/fdt/acpi_fdt.c 2018/10/15 11:35:03 1.3
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: acpi_fdt.c,v 1.2 2018/10/13 00:15:10 jmcneill Exp $ */ 1/* $NetBSD: acpi_fdt.c,v 1.3 2018/10/15 11:35:03 jmcneill Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2015-2017 Jared McNeill <jmcneill@invisible.ca> 4 * Copyright (c) 2015-2017 Jared McNeill <jmcneill@invisible.ca>
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -17,45 +17,47 @@ @@ -17,45 +17,47 @@
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE. 26 * SUCH DAMAGE.
27 */ 27 */
28 28
29#include <sys/cdefs.h> 29#include <sys/cdefs.h>
30__KERNEL_RCSID(0, "$NetBSD: acpi_fdt.c,v 1.2 2018/10/13 00:15:10 jmcneill Exp $"); 30__KERNEL_RCSID(0, "$NetBSD: acpi_fdt.c,v 1.3 2018/10/15 11:35:03 jmcneill Exp $");
31 31
32#include <sys/param.h> 32#include <sys/param.h>
33#include <sys/bus.h> 33#include <sys/bus.h>
34#include <sys/device.h> 34#include <sys/device.h>
35#include <sys/intr.h> 35#include <sys/intr.h>
36#include <sys/systm.h> 36#include <sys/systm.h>
37#include <sys/kernel.h> 37#include <sys/kernel.h>
38#include <sys/lwp.h> 38#include <sys/lwp.h>
39#include <sys/kmem.h> 39#include <sys/kmem.h>
40#include <sys/queue.h> 40#include <sys/queue.h>
41 41
42#include <dev/fdt/fdtvar.h> 42#include <dev/fdt/fdtvar.h>
43 43
44#include <dev/acpi/acpivar.h> 44#include <dev/acpi/acpivar.h>
45#include <dev/pci/pcivar.h> 45#include <dev/pci/pcivar.h>
46 46
47#include <arm/arm/psci.h> 47#include <arm/arm/psci.h>
48 48
 49#include <arm/acpi/acpi_pci_machdep.h>
 50
49static int acpi_fdt_match(device_t, cfdata_t, void *); 51static int acpi_fdt_match(device_t, cfdata_t, void *);
50static void acpi_fdt_attach(device_t, device_t, void *); 52static void acpi_fdt_attach(device_t, device_t, void *);
51 53
52static void acpi_fdt_poweroff(device_t); 54static void acpi_fdt_poweroff(device_t);
53 55
54static const char * const compatible[] = { 56static const char * const compatible[] = {
55 "netbsd,acpi", 57 "netbsd,acpi",
56 NULL 58 NULL
57}; 59};
58 60
59static const struct fdtbus_power_controller_func acpi_fdt_power_funcs = { 61static const struct fdtbus_power_controller_func acpi_fdt_power_funcs = {
60 .poweroff = acpi_fdt_poweroff, 62 .poweroff = acpi_fdt_poweroff,
61}; 63};
@@ -77,29 +79,29 @@ acpi_fdt_attach(device_t parent, device_ @@ -77,29 +79,29 @@ acpi_fdt_attach(device_t parent, device_
77 struct acpibus_attach_args aa; 79 struct acpibus_attach_args aa;
78 80
79 aprint_naive("\n"); 81 aprint_naive("\n");
80 aprint_normal(": ACPI Platform support\n"); 82 aprint_normal(": ACPI Platform support\n");
81 83
82 fdtbus_register_power_controller(self, faa->faa_phandle, 84 fdtbus_register_power_controller(self, faa->faa_phandle,
83 &acpi_fdt_power_funcs); 85 &acpi_fdt_power_funcs);
84 86
85 if (!acpi_probe()) 87 if (!acpi_probe())
86 aprint_error_dev(self, "failed to probe ACPI\n"); 88 aprint_error_dev(self, "failed to probe ACPI\n");
87 89
88 aa.aa_iot = 0; 90 aa.aa_iot = 0;
89 aa.aa_memt = faa->faa_bst; 91 aa.aa_memt = faa->faa_bst;
90 aa.aa_pc = NULL; 92 aa.aa_pc = &arm_acpi_pci_chipset;
91 aa.aa_pciflags = 93 aa.aa_pciflags =
92 PCI_FLAGS_IO_OKAY | PCI_FLAGS_MEM_OKAY | 94 /*PCI_FLAGS_IO_OKAY |*/ PCI_FLAGS_MEM_OKAY |
93 PCI_FLAGS_MRL_OKAY | PCI_FLAGS_MRM_OKAY |  95 PCI_FLAGS_MRL_OKAY | PCI_FLAGS_MRM_OKAY |
94 PCI_FLAGS_MWI_OKAY; 96 PCI_FLAGS_MWI_OKAY;
95 aa.aa_ic = 0; 97 aa.aa_ic = 0;
96 aa.aa_dmat = faa->faa_dmat; 98 aa.aa_dmat = faa->faa_dmat;
97#ifdef _PCI_HAVE_DMA64 99#ifdef _PCI_HAVE_DMA64
98 aa.aa_dmat64 = faa->faa_dmat; 100 aa.aa_dmat64 = faa->faa_dmat;
99#endif 101#endif
100 config_found_ia(self, "acpibus", &aa, 0); 102 config_found_ia(self, "acpibus", &aa, 0);
101} 103}
102 104
103static void 105static void
104acpi_fdt_poweroff(device_t dev) 106acpi_fdt_poweroff(device_t dev)
105{ 107{