Author: andrew
Date: Thu Jun 11 15:45:33 2015
New Revision: 284273
URL: https://svnweb.freebsd.org/changeset/base/284273

Log:
  Add basic support for ACPI. It splits out the nexus driver to two new
  drivers, one for fdt, one for acpi. It then uses this to decide if it will
  use fdt or acpi.
  
  The GICv2 (interrupt controller) and Generic Timer drivers have been
  updated to handle both cases.
  
  As this is early code we still need FDT to find the kernel console, and
  some parts are still missing, including PCI support.
  
  Differential Revision:        https://reviews.freebsd.org/D2463
  Reviewed by:  jhb, jkim, emaste
  Obtained from:        ABT Systems Ltd
  Relnotes:     Yes
  Sponsored by: The FreeBSD Foundation

Added:
  head/sys/arm64/acpica/
  head/sys/arm64/acpica/OsdEnvironment.c   (contents, props changed)
  head/sys/arm64/acpica/acpi_machdep.c   (contents, props changed)
  head/sys/arm64/acpica/acpi_wakeup.c   (contents, props changed)
  head/sys/arm64/arm64/gic.h   (contents, props changed)
  head/sys/arm64/arm64/gic_acpi.c   (contents, props changed)
  head/sys/arm64/arm64/gic_fdt.c   (contents, props changed)
  head/sys/arm64/include/acpica_machdep.h   (contents, props changed)
  head/sys/arm64/include/iodev.h   (contents, props changed)
  head/sys/arm64/include/pci_cfgreg.h   (contents, props changed)
Modified:
  head/sys/arm/arm/generic_timer.c
  head/sys/arm64/arm64/gic.c
  head/sys/arm64/arm64/machdep.c
  head/sys/arm64/arm64/nexus.c
  head/sys/arm64/conf/GENERIC
  head/sys/arm64/include/pcpu.h
  head/sys/conf/files.arm64
  head/sys/dev/acpica/Osd/OsdHardware.c
  head/sys/dev/acpica/acpi_cpu.c

Modified: head/sys/arm/arm/generic_timer.c
==============================================================================
--- head/sys/arm/arm/generic_timer.c    Thu Jun 11 15:23:47 2015        
(r284272)
+++ head/sys/arm/arm/generic_timer.c    Thu Jun 11 15:45:33 2015        
(r284273)
@@ -34,6 +34,9 @@
  *      Cortex-A7, Cortex-A15, ARMv8 and later Generic Timer
  */
 
+#include "opt_acpi.h"
+#include "opt_platform.h"
+
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
@@ -51,12 +54,17 @@ __FBSDID("$FreeBSD$");
 #include <machine/cpu.h>
 #include <machine/intr.h>
 
+#ifdef FDT
 #include <dev/fdt/fdt_common.h>
 #include <dev/ofw/openfirm.h>
 #include <dev/ofw/ofw_bus.h>
 #include <dev/ofw/ofw_bus_subr.h>
+#endif
 
-#include <machine/bus.h>
+#ifdef DEV_ACPI
+#include <contrib/dev/acpica/include/acpi.h>
+#include <dev/acpica/acpivar.h>
+#endif
 
 #define        GT_CTRL_ENABLE          (1 << 0)
 #define        GT_CTRL_INT_MASK        (1 << 1)
@@ -247,8 +255,9 @@ arm_tmr_intr(void *arg)
        return (FILTER_HANDLED);
 }
 
+#ifdef FDT
 static int
-arm_tmr_probe(device_t dev)
+arm_tmr_fdt_probe(device_t dev)
 {
 
        if (!ofw_bus_status_okay(dev))
@@ -264,14 +273,62 @@ arm_tmr_probe(device_t dev)
 
        return (ENXIO);
 }
+#endif
+
+#ifdef DEV_ACPI
+static void
+arm_tmr_acpi_identify(driver_t *driver, device_t parent)
+{
+       ACPI_TABLE_GTDT *gtdt;
+       vm_paddr_t physaddr;
+       device_t dev;
+
+       physaddr = acpi_find_table(ACPI_SIG_GTDT);
+       if (physaddr == 0)
+               return;
+
+       gtdt = acpi_map_table(physaddr, ACPI_SIG_GTDT);
+       if (gtdt == NULL) {
+               device_printf(parent, "gic: Unable to map the GTDT\n");
+               return;
+       }
+
+       dev = BUS_ADD_CHILD(parent, BUS_PASS_TIMER + BUS_PASS_ORDER_MIDDLE,
+           "generic_timer", -1);
+       if (dev == NULL) {
+               device_printf(parent, "add gic child failed\n");
+               goto out;
+       }
+
+       BUS_SET_RESOURCE(parent, dev, SYS_RES_IRQ, 0,
+           gtdt->SecureEl1Interrupt, 1);
+       BUS_SET_RESOURCE(parent, dev, SYS_RES_IRQ, 1,
+           gtdt->NonSecureEl1Interrupt, 1);
+       BUS_SET_RESOURCE(parent, dev, SYS_RES_IRQ, 2,
+           gtdt->VirtualTimerInterrupt, 1);
+
+out:
+       acpi_unmap_table(gtdt);
+}
+
+static int
+arm_tmr_acpi_probe(device_t dev)
+{
+
+       device_set_desc(dev, "ARM Generic Timer");
+       return (BUS_PROBE_NOWILDCARD);
+}
+#endif
 
 
 static int
 arm_tmr_attach(device_t dev)
 {
        struct arm_tmr_softc *sc;
+#ifdef FDT
        phandle_t node;
        pcell_t clock;
+#endif
        int error;
        int i;
 
@@ -279,12 +336,17 @@ arm_tmr_attach(device_t dev)
        if (arm_tmr_sc)
                return (ENXIO);
 
+#ifdef FDT
        /* Get the base clock frequency */
        node = ofw_bus_get_node(dev);
-       error = OF_getprop(node, "clock-frequency", &clock, sizeof(clock));
-       if (error > 0) {
-               sc->clkfreq = fdt32_to_cpu(clock);
+       if (node > 0) {
+               error = OF_getprop(node, "clock-frequency", &clock,
+                   sizeof(clock));
+               if (error > 0) {
+                       sc->clkfreq = fdt32_to_cpu(clock);
+               }
        }
+#endif
 
        if (sc->clkfreq == 0) {
                /* Try to get clock frequency from timer */
@@ -339,24 +401,46 @@ arm_tmr_attach(device_t dev)
        return (0);
 }
 
-static device_method_t arm_tmr_methods[] = {
-       DEVMETHOD(device_probe,         arm_tmr_probe),
+#ifdef FDT
+static device_method_t arm_tmr_fdt_methods[] = {
+       DEVMETHOD(device_probe,         arm_tmr_fdt_probe),
        DEVMETHOD(device_attach,        arm_tmr_attach),
        { 0, 0 }
 };
 
-static driver_t arm_tmr_driver = {
+static driver_t arm_tmr_fdt_driver = {
        "generic_timer",
-       arm_tmr_methods,
+       arm_tmr_fdt_methods,
        sizeof(struct arm_tmr_softc),
 };
 
-static devclass_t arm_tmr_devclass;
+static devclass_t arm_tmr_fdt_devclass;
 
-EARLY_DRIVER_MODULE(timer, simplebus, arm_tmr_driver, arm_tmr_devclass, 0, 0,
-    BUS_PASS_TIMER + BUS_PASS_ORDER_MIDDLE);
-EARLY_DRIVER_MODULE(timer, ofwbus, arm_tmr_driver, arm_tmr_devclass, 0, 0,
-    BUS_PASS_TIMER + BUS_PASS_ORDER_MIDDLE);
+EARLY_DRIVER_MODULE(timer, simplebus, arm_tmr_fdt_driver, arm_tmr_fdt_devclass,
+    0, 0, BUS_PASS_TIMER + BUS_PASS_ORDER_MIDDLE);
+EARLY_DRIVER_MODULE(timer, ofwbus, arm_tmr_fdt_driver, arm_tmr_fdt_devclass,
+    0, 0, BUS_PASS_TIMER + BUS_PASS_ORDER_MIDDLE);
+#endif
+
+#ifdef DEV_ACPI
+static device_method_t arm_tmr_acpi_methods[] = {
+       DEVMETHOD(device_identify,      arm_tmr_acpi_identify),
+       DEVMETHOD(device_probe,         arm_tmr_acpi_probe),
+       DEVMETHOD(device_attach,        arm_tmr_attach),
+       { 0, 0 }
+};
+
+static driver_t arm_tmr_acpi_driver = {
+       "generic_timer",
+       arm_tmr_acpi_methods,
+       sizeof(struct arm_tmr_softc),
+};
+
+static devclass_t arm_tmr_acpi_devclass;
+
+EARLY_DRIVER_MODULE(timer, acpi, arm_tmr_acpi_driver, arm_tmr_acpi_devclass,
+    0, 0, BUS_PASS_TIMER + BUS_PASS_ORDER_MIDDLE);
+#endif
 
 void
 DELAY(int usec)

Added: head/sys/arm64/acpica/OsdEnvironment.c
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ head/sys/arm64/acpica/OsdEnvironment.c      Thu Jun 11 15:45:33 2015        
(r284273)
@@ -0,0 +1,76 @@
+/*-
+ * Copyright (c) 2000,2001 Michael Smith
+ * Copyright (c) 2000 BSDi
+ * All rights reserved.
+ *
+ * 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 AUTHOR 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 AUTHOR 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>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+#include <sys/bus.h>
+#include <sys/sysctl.h>
+
+#include <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/actables.h>
+
+static u_long acpi_root_phys;
+
+SYSCTL_ULONG(_machdep, OID_AUTO, acpi_root, CTLFLAG_RD, &acpi_root_phys, 0,
+    "The physical address of the RSDP");
+
+ACPI_STATUS
+AcpiOsInitialize(void)
+{
+
+       return (AE_OK);
+}
+
+ACPI_STATUS
+AcpiOsTerminate(void)
+{
+
+       return (AE_OK);
+}
+
+static u_long
+acpi_get_root_from_loader(void)
+{
+       long acpi_root;
+
+       if (resource_long_value("acpi", 0, "rsdp", &acpi_root) == 0)
+               return (acpi_root);
+
+       return (0);
+}
+
+ACPI_PHYSICAL_ADDRESS
+AcpiOsGetRootPointer(void)
+{
+
+       if (acpi_root_phys == 0)
+               acpi_root_phys = acpi_get_root_from_loader();
+
+       return (acpi_root_phys);
+}

Added: head/sys/arm64/acpica/acpi_machdep.c
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ head/sys/arm64/acpica/acpi_machdep.c        Thu Jun 11 15:45:33 2015        
(r284273)
@@ -0,0 +1,217 @@
+/*-
+ * Copyright (c) 2001 Mitsuru IWASAKI
+ * Copyright (c) 2015 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Andrew Turner under
+ * sponsorship from the FreeBSD Foundation.
+ *
+ * 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 AUTHOR 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 AUTHOR 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>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+
+#include <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/actables.h>
+
+#include <dev/acpica/acpivar.h>
+
+int
+acpi_machdep_init(device_t dev)
+{
+
+       return (0);
+}
+
+int
+acpi_machdep_quirks(int *quirks)
+{
+
+       return (0);
+}
+
+static void *
+map_table(vm_paddr_t pa, int offset, const char *sig)
+{
+       ACPI_TABLE_HEADER *header;
+       vm_offset_t length;
+       void *table;
+
+       header = pmap_mapbios(pa, sizeof(ACPI_TABLE_HEADER));
+       if (strncmp(header->Signature, sig, ACPI_NAME_SIZE) != 0) {
+               pmap_unmapbios((vm_offset_t)header, sizeof(ACPI_TABLE_HEADER));
+               return (NULL);
+       }
+       length = header->Length;
+       pmap_unmapbios((vm_offset_t)header, sizeof(ACPI_TABLE_HEADER));
+
+       table = pmap_mapbios(pa, length);
+       if (ACPI_FAILURE(AcpiTbChecksum(table, length))) {
+               if (bootverbose)
+                       printf("ACPI: Failed checksum for table %s\n", sig);
+#if (ACPI_CHECKSUM_ABORT)
+               pmap_unmapbios(table, length);
+               return (NULL);
+#endif
+       }
+       return (table);
+}
+
+/*
+ * See if a given ACPI table is the requested table.  Returns the
+ * length of the able if it matches or zero on failure.
+ */
+static int
+probe_table(vm_paddr_t address, const char *sig)
+{
+       ACPI_TABLE_HEADER *table;
+
+       table = pmap_mapbios(address, sizeof(ACPI_TABLE_HEADER));
+       if (table == NULL) {
+               if (bootverbose)
+                       printf("ACPI: Failed to map table at 0x%jx\n",
+                           (uintmax_t)address);
+               return (0);
+       }
+       if (bootverbose)
+               printf("Table '%.4s' at 0x%jx\n", table->Signature,
+                   (uintmax_t)address);
+
+       if (strncmp(table->Signature, sig, ACPI_NAME_SIZE) != 0) {
+               pmap_unmapbios((vm_offset_t)table, sizeof(ACPI_TABLE_HEADER));
+               return (0);
+       }
+       pmap_unmapbios((vm_offset_t)table, sizeof(ACPI_TABLE_HEADER));
+       return (1);
+}
+
+/* Unmap a table previously mapped via acpi_map_table(). */
+void
+acpi_unmap_table(void *table)
+{
+       ACPI_TABLE_HEADER *header;
+
+       header = (ACPI_TABLE_HEADER *)table;
+       pmap_unmapbios((vm_offset_t)table, header->Length);
+}
+
+/*
+ * Try to map a table at a given physical address previously returned
+ * by acpi_find_table().
+ */
+void *
+acpi_map_table(vm_paddr_t pa, const char *sig)
+{
+
+       return (map_table(pa, 0, sig));
+}
+
+/*
+ * Return the physical address of the requested table or zero if one
+ * is not found.
+ */
+vm_paddr_t
+acpi_find_table(const char *sig)
+{
+       ACPI_PHYSICAL_ADDRESS rsdp_ptr;
+       ACPI_TABLE_RSDP *rsdp;
+       ACPI_TABLE_XSDT *xsdt;
+       ACPI_TABLE_HEADER *table;
+       vm_paddr_t addr;
+       int i, count;
+
+       if (resource_disabled("acpi", 0))
+               return (0);
+
+       /*
+        * Map in the RSDP.  Since ACPI uses AcpiOsMapMemory() which in turn
+        * calls pmap_mapbios() to find the RSDP, we assume that we can use
+        * pmap_mapbios() to map the RSDP.
+        */
+       if ((rsdp_ptr = AcpiOsGetRootPointer()) == 0)
+               return (0);
+       rsdp = pmap_mapbios(rsdp_ptr, sizeof(ACPI_TABLE_RSDP));
+       if (rsdp == NULL) {
+               if (bootverbose)
+                       printf("ACPI: Failed to map RSDP\n");
+               return (0);
+       }
+
+       addr = 0;
+       if (rsdp->Revision >= 2 && rsdp->XsdtPhysicalAddress != 0) {
+               /*
+                * AcpiOsGetRootPointer only verifies the checksum for
+                * the version 1.0 portion of the RSDP.  Version 2.0 has
+                * an additional checksum that we verify first.
+                */
+               if (AcpiTbChecksum((UINT8 *)rsdp, ACPI_RSDP_XCHECKSUM_LENGTH)) {
+                       if (bootverbose)
+                               printf("ACPI: RSDP failed extended checksum\n");
+                       return (0);
+               }
+               xsdt = map_table(rsdp->XsdtPhysicalAddress, 2, ACPI_SIG_XSDT);
+               if (xsdt == NULL) {
+                       if (bootverbose)
+                               printf("ACPI: Failed to map XSDT\n");
+                       pmap_unmapbios((vm_offset_t)rsdp,
+                           sizeof(ACPI_TABLE_RSDP));
+                       return (0);
+               }
+               count = (xsdt->Header.Length - sizeof(ACPI_TABLE_HEADER)) /
+                   sizeof(UINT64);
+               for (i = 0; i < count; i++)
+                       if (probe_table(xsdt->TableOffsetEntry[i], sig)) {
+                               addr = xsdt->TableOffsetEntry[i];
+                               break;
+                       }
+               acpi_unmap_table(xsdt);
+       }
+       pmap_unmapbios((vm_offset_t)rsdp, sizeof(ACPI_TABLE_RSDP));
+
+       if (addr == 0) {
+               if (bootverbose)
+                       printf("ACPI: No %s table found\n", sig);
+               return (0);
+       }
+       if (bootverbose)
+               printf("%s: Found table at 0x%jx\n", sig, (uintmax_t)addr);
+
+       /*
+        * Verify that we can map the full table and that its checksum is
+        * correct, etc.
+        */
+       table = map_table(addr, 0, sig);
+       if (table == NULL)
+               return (0);
+       acpi_unmap_table(table);
+
+       return (addr);
+}

Added: head/sys/arm64/acpica/acpi_wakeup.c
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ head/sys/arm64/acpica/acpi_wakeup.c Thu Jun 11 15:45:33 2015        
(r284273)
@@ -0,0 +1,61 @@
+/*-
+ * Copyright (c) 2015 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Andrew Turner under
+ * sponsorship from the FreeBSD Foundation.
+ *
+ * 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 AUTHOR 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 AUTHOR 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>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+
+#include <contrib/dev/acpica/include/acpi.h>
+
+#include <dev/acpica/acpivar.h>
+
+/*
+ * ARM64TODO: Implement this.
+ */
+int
+acpi_sleep_machdep(struct acpi_softc *sc, int state)
+{
+
+       return (-1);
+}
+
+int
+acpi_wakeup_machdep(struct acpi_softc *sc, int state, int sleep_result,
+    int intr_enabled)
+{
+
+       /* ARM64TODO: We will need this with acpi_sleep_machdep */
+       KASSERT(sleep_result == -1,
+           ("acpi_wakeup_machdep: Invalid sleep result"));
+
+       return (sleep_result);
+}

Modified: head/sys/arm64/arm64/gic.c
==============================================================================
--- head/sys/arm64/arm64/gic.c  Thu Jun 11 15:23:47 2015        (r284272)
+++ head/sys/arm64/arm64/gic.c  Thu Jun 11 15:45:33 2015        (r284273)
@@ -51,11 +51,7 @@ __FBSDID("$FreeBSD$");
 #include <machine/intr.h>
 #include <machine/smp.h>
 
-#include <dev/fdt/fdt_common.h>
-#include <dev/ofw/openfirm.h>
-#include <dev/ofw/ofw_bus.h>
-#include <dev/ofw/ofw_bus_subr.h>
-
+#include <arm64/arm64/gic.h>
 
 #include "pic_if.h"
 
@@ -102,18 +98,6 @@ __FBSDID("$FreeBSD$");
 #define GICD_ICFGR_TRIG_EDGE   (1 << 1)
 #define GICD_ICFGR_TRIG_MASK   0x2
 
-struct arm_gic_softc {
-       device_t                gic_dev;
-       struct resource *       gic_res[3];
-       bus_space_tag_t         gic_c_bst;
-       bus_space_tag_t         gic_d_bst;
-       bus_space_handle_t      gic_c_bsh;
-       bus_space_handle_t      gic_d_bsh;
-       uint8_t                 ver;
-       struct mtx              mutex;
-       uint32_t                nirqs;
-};
-
 static struct resource_spec arm_gic_spec[] = {
        { SYS_RES_MEMORY,       0,      RF_ACTIVE },    /* Distributor 
registers */
        { SYS_RES_MEMORY,       1,      RF_ACTIVE },    /* CPU Interrupt Intf. 
registers */
@@ -136,31 +120,6 @@ static pic_eoi_t gic_eoi;
 static pic_mask_t gic_mask_irq;
 static pic_unmask_t gic_unmask_irq;
 
-static struct ofw_compat_data compat_data[] = {
-       {"arm,gic",             true},  /* Non-standard, used in FreeBSD dts. */
-       {"arm,gic-400",         true},
-       {"arm,cortex-a15-gic",  true},
-       {"arm,cortex-a9-gic",   true},
-       {"arm,cortex-a7-gic",   true},
-       {"arm,arm11mp-gic",     true},
-       {"brcm,brahma-b15-gic", true},
-       {NULL,                  false}
-};
-
-static int
-arm_gic_probe(device_t dev)
-{
-
-       if (!ofw_bus_status_okay(dev))
-               return (ENXIO);
-
-       if (!ofw_bus_search_compatible(dev, compat_data)->ocd_data)
-               return (ENXIO);
-
-       device_set_desc(dev, "ARM Generic Interrupt Controller");
-       return (BUS_PROBE_DEFAULT);
-}
-
 #ifdef SMP
 static void
 gic_init_secondary(device_t dev)
@@ -367,7 +326,6 @@ arm_gic_ipi_clear(device_t dev, int ipi)
 
 static device_method_t arm_gic_methods[] = {
        /* Device interface */
-       DEVMETHOD(device_probe,         arm_gic_probe),
        DEVMETHOD(device_attach,        arm_gic_attach),
 
        /* pic_if */
@@ -384,15 +342,5 @@ static device_method_t arm_gic_methods[]
        { 0, 0 }
 };
 
-static driver_t arm_gic_driver = {
-       "gic",
-       arm_gic_methods,
-       sizeof(struct arm_gic_softc),
-};
-
-static devclass_t arm_gic_devclass;
-
-EARLY_DRIVER_MODULE(gic, simplebus, arm_gic_driver, arm_gic_devclass, 0, 0,
-    BUS_PASS_INTERRUPT + BUS_PASS_ORDER_MIDDLE);
-EARLY_DRIVER_MODULE(gic, ofwbus, arm_gic_driver, arm_gic_devclass, 0, 0,
-    BUS_PASS_INTERRUPT + BUS_PASS_ORDER_MIDDLE);
+DEFINE_CLASS_0(gic, arm_gic_driver, arm_gic_methods,
+    sizeof(struct arm_gic_softc));

Added: head/sys/arm64/arm64/gic.h
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ head/sys/arm64/arm64/gic.h  Thu Jun 11 15:45:33 2015        (r284273)
@@ -0,0 +1,54 @@
+/*-
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * Copyright (c) 2014 Andrew Turner
+ * All rights reserved.
+ *
+ * Developed by Damjan Marion <damjan.mar...@gmail.com>
+ *
+ * Based on OMAP4 GIC code by Ben Gray
+ *
+ * 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.
+ * 3. The name of the company nor the name of the author may be used to
+ *    endorse or promote products derived from this software without specific
+ *    prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _ARM64_GIC_H_
+#define        _ARM64_GIC_H_
+
+DECLARE_CLASS(arm_gic_driver);
+
+struct arm_gic_softc {
+       device_t                gic_dev;
+       struct resource *       gic_res[3];
+       bus_space_tag_t         gic_c_bst;
+       bus_space_tag_t         gic_d_bst;
+       bus_space_handle_t      gic_c_bsh;
+       bus_space_handle_t      gic_d_bsh;
+       uint8_t                 ver;
+       struct mtx              mutex;
+       uint32_t                nirqs;
+};
+
+#endif

Added: head/sys/arm64/arm64/gic_acpi.c
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ head/sys/arm64/arm64/gic_acpi.c     Thu Jun 11 15:45:33 2015        
(r284273)
@@ -0,0 +1,161 @@
+/*-
+ * Copyright (c) 2015 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Andrew Turner under
+ * sponsorship from the FreeBSD Foundation.
+ *
+ * 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 AUTHOR 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 AUTHOR 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>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+
+#include <machine/bus.h>
+
+#include <arm64/arm64/gic.h>
+
+#include <contrib/dev/acpica/include/acpi.h>
+
+#include <dev/acpica/acpivar.h>
+
+struct arm_gic_acpi_softc {
+       struct arm_gic_softc gic_sc;
+       struct resource_list res;
+};
+
+struct madt_table_data {
+       device_t parent;
+       ACPI_MADT_GENERIC_DISTRIBUTOR *dist;
+       ACPI_MADT_GENERIC_INTERRUPT *intr;
+};
+
+static void
+madt_handler(ACPI_SUBTABLE_HEADER *entry, void *arg)
+{
+       struct madt_table_data *madt_data;
+
+       madt_data = (struct madt_table_data *)arg;
+
+       switch(entry->Type) {
+       case ACPI_MADT_TYPE_GENERIC_INTERRUPT:
+               if (madt_data->intr != NULL) {
+                       if (bootverbose)
+                               device_printf(madt_data->parent,
+                                   "gic: Already have an interrupt table");
+                       break;
+               }
+
+               madt_data->intr = (ACPI_MADT_GENERIC_INTERRUPT *)entry;
+               break;
+
+       case ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR:
+               if (madt_data->dist != NULL) {
+                       if (bootverbose)
+                               device_printf(madt_data->parent,
+                                   "gic: Already have a distributor table");
+                       break;
+               }
+
+               madt_data->dist = (ACPI_MADT_GENERIC_DISTRIBUTOR *)entry;
+               break;
+
+       default:
+               break;
+       }
+}
+
+static void
+arm_gic_acpi_identify(driver_t *driver, device_t parent)
+{
+       struct madt_table_data madt_data;
+       ACPI_TABLE_MADT *madt;
+       vm_paddr_t physaddr;
+       device_t dev;
+
+       physaddr = acpi_find_table(ACPI_SIG_MADT);
+       if (physaddr == 0)
+               return;
+
+       madt = acpi_map_table(physaddr, ACPI_SIG_MADT);
+       if (madt == NULL) {
+               device_printf(parent, "gic: Unable to map the MADT\n");
+               return;
+       }
+
+       madt_data.parent = parent;
+       madt_data.dist = NULL;
+       madt_data.intr = NULL;
+
+       acpi_walk_subtables(madt + 1, (char *)madt + madt->Header.Length,
+           madt_handler, &madt_data);
+       if (madt_data.intr == NULL || madt_data.dist == NULL) {
+               device_printf(parent,
+                   "No gic interrupt or distributor table\n");
+               goto out;
+       }
+
+       dev = BUS_ADD_CHILD(parent, BUS_PASS_INTERRUPT + BUS_PASS_ORDER_MIDDLE,
+           "gic", -1);
+       if (dev == NULL) {
+               device_printf(parent, "add gic child failed\n");
+               goto out;
+       }
+
+       /* Add the MADT data */
+       BUS_SET_RESOURCE(parent, dev, SYS_RES_MEMORY, 0,
+           madt_data.dist->BaseAddress, PAGE_SIZE);
+       BUS_SET_RESOURCE(parent, dev, SYS_RES_MEMORY, 1,
+           madt_data.intr->BaseAddress, PAGE_SIZE);
+
+out:
+       acpi_unmap_table(madt);
+}
+
+static int
+arm_gic_acpi_probe(device_t dev)
+{
+
+       device_set_desc(dev, "ARM Generic Interrupt Controller");
+       return (BUS_PROBE_NOWILDCARD);
+}
+
+static device_method_t arm_gic_acpi_methods[] = {
+       /* Device interface */
+       DEVMETHOD(device_identify,      arm_gic_acpi_identify),
+       DEVMETHOD(device_probe,         arm_gic_acpi_probe),
+
+       DEVMETHOD_END
+};
+
+DEFINE_CLASS_1(gic, arm_gic_acpi_driver, arm_gic_acpi_methods,
+    sizeof(struct arm_gic_acpi_softc), arm_gic_driver);
+
+static devclass_t arm_gic_acpi_devclass;
+
+EARLY_DRIVER_MODULE(gic, acpi, arm_gic_acpi_driver,
+    arm_gic_acpi_devclass, 0, 0, BUS_PASS_INTERRUPT + BUS_PASS_ORDER_MIDDLE);

Added: head/sys/arm64/arm64/gic_fdt.c
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ head/sys/arm64/arm64/gic_fdt.c      Thu Jun 11 15:45:33 2015        
(r284273)
@@ -0,0 +1,87 @@
+/*-
+ * Copyright (c) 2015 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Andrew Turner under
+ * sponsorship from the FreeBSD Foundation.
+ *
+ * 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 AUTHOR 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 AUTHOR 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>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+
+#include <machine/bus.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <arm64/arm64/gic.h>
+
+static struct ofw_compat_data compat_data[] = {
+       {"arm,gic",             true},  /* Non-standard, used in FreeBSD dts. */
+       {"arm,gic-400",         true},
+       {"arm,cortex-a15-gic",  true},
+       {"arm,cortex-a9-gic",   true},
+       {"arm,cortex-a7-gic",   true},
+       {"arm,arm11mp-gic",     true},
+       {"brcm,brahma-b15-gic", true},
+       {NULL,                  false}
+};
+
+static int
+arm_gic_fdt_probe(device_t dev)
+{
+
+       if (!ofw_bus_status_okay(dev))
+               return (ENXIO);
+
+       if (!ofw_bus_search_compatible(dev, compat_data)->ocd_data)
+               return (ENXIO);
+
+       device_set_desc(dev, "ARM Generic Interrupt Controller");
+       return (BUS_PROBE_DEFAULT);
+}
+
+static device_method_t arm_gic_fdt_methods[] = {
+       /* Device interface */
+       DEVMETHOD(device_probe,         arm_gic_fdt_probe),
+
+       DEVMETHOD_END
+};
+
+DEFINE_CLASS_1(gic, arm_gic_fdt_driver, arm_gic_fdt_methods,
+    sizeof(struct arm_gic_softc), arm_gic_driver);
+
+static devclass_t arm_gic_fdt_devclass;
+
+EARLY_DRIVER_MODULE(gic, simplebus, arm_gic_fdt_driver,
+    arm_gic_fdt_devclass, 0, 0, BUS_PASS_INTERRUPT + BUS_PASS_ORDER_MIDDLE);
+EARLY_DRIVER_MODULE(gic, ofwbus, arm_gic_fdt_driver, arm_gic_fdt_devclass,
+    0, 0, BUS_PASS_INTERRUPT + BUS_PASS_ORDER_MIDDLE);

Modified: head/sys/arm64/arm64/machdep.c
==============================================================================
--- head/sys/arm64/arm64/machdep.c      Thu Jun 11 15:23:47 2015        
(r284272)
+++ head/sys/arm64/arm64/machdep.c      Thu Jun 11 15:45:33 2015        
(r284273)
@@ -392,6 +392,8 @@ cpu_est_clockrate(int cpu_id, uint64_t *
 void
 cpu_pcpu_init(struct pcpu *pcpu, int cpuid, size_t size)
 {
+
+       pcpu->pc_acpi_id = 0xffffffff;
 }
 
 void

Modified: head/sys/arm64/arm64/nexus.c
==============================================================================
--- head/sys/arm64/arm64/nexus.c        Thu Jun 11 15:23:47 2015        
(r284272)
+++ head/sys/arm64/arm64/nexus.c        Thu Jun 11 15:45:33 2015        
(r284273)
@@ -60,12 +60,17 @@ __FBSDID("$FreeBSD$");
 #include <machine/resource.h>
 #include <machine/intr.h>
 
+#include "opt_acpi.h"
 #include "opt_platform.h"
 
 #ifdef FDT
 #include <dev/fdt/fdt_common.h>
 #include "ofw_bus_if.h"
 #endif
+#ifdef DEV_ACPI
+#include <contrib/dev/acpica/include/acpi.h>
+#include <dev/acpica/acpivar.h>
+#endif
 
 extern struct bus_space memmap_bus;
 
@@ -78,9 +83,19 @@ struct nexus_device {
 #define DEVTONX(dev)   ((struct nexus_device *)device_get_ivars(dev))
 
 static struct rman mem_rman;
+static struct rman irq_rman;
 
-static int nexus_probe(device_t);
 static int nexus_attach(device_t);
+
+#ifdef FDT
+static device_probe_t  nexus_fdt_probe;
+static device_attach_t nexus_fdt_attach;
+#endif
+#ifdef DEV_ACPI
+static device_probe_t  nexus_acpi_probe;
+static device_attach_t nexus_acpi_attach;
+#endif
+
 static int nexus_print_child(device_t, device_t);
 static device_t nexus_add_child(device_t, u_int, const char *, int);
 static struct resource *nexus_alloc_resource(device_t, device_t, int, int *,

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to