Date: Thu, 11 Jun 2015 15:45:33 +0000 (UTC) From: Andrew Turner <andrew@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r284273 - in head/sys: arm/arm arm64/acpica arm64/arm64 arm64/conf arm64/include conf dev/acpica dev/acpica/Osd Message-ID: <201506111545.t5BFjX0L038127@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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.marion@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 ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201506111545.t5BFjX0L038127>