Page MenuHomeFreeBSD

D2463.id5526.diff
No OneTemporary

D2463.id5526.diff

Index: sys/arm/arm/generic_timer.c
===================================================================
--- sys/arm/arm/generic_timer.c
+++ sys/arm/arm/generic_timer.c
@@ -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 @@
#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 @@
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,68 @@
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)
+{
+
+ if (device_get_unit(dev) != 0)
+ return (ENXIO);
+
+ if (acpi_get_type(dev) != ACPI_TYPE_NOT_FOUND)
+ return (ENXIO);
+
+ device_set_desc(dev, "ARM Generic Timer");
+ return (BUS_PROBE_DEFAULT);
+}
+#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 +342,17 @@
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 +407,46 @@
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_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
-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);
+#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)
Index: sys/arm64/acpica/OsdEnvironment.c
===================================================================
--- sys/arm64/acpica/OsdEnvironment.c
+++ sys/arm64/acpica/OsdEnvironment.c
@@ -1,5 +1,6 @@
/*-
- * Copyright (c) 1999 Luoqi Chen <luoqi@freebsd.org>
+ * Copyright (c) 2000,2001 Michael Smith
+ * Copyright (c) 2000 BSDi
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -22,53 +23,54 @@
* 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.
- *
- * from: FreeBSD: src/sys/i386/include/globaldata.h,v 1.27 2001/04/27
- * $FreeBSD$
*/
-#ifndef _MACHINE_PCPU_H_
-#define _MACHINE_PCPU_H_
-
-#include <machine/cpu.h>
-#include <machine/cpufunc.h>
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: head/sys/x86/acpica/OsdEnvironment.c 281475 2015-04-12 22:40:27Z jkim $");
-#define ALT_STACK_SIZE 128
+#include <sys/types.h>
+#include <sys/bus.h>
+#include <sys/sysctl.h>
-#define PCPU_MD_FIELDS \
- char __pad[129]
+#include <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/actables.h>
-#ifdef _KERNEL
+static u_long acpi_root_phys;
-struct pcb;
-struct pcpu;
+SYSCTL_ULONG(_machdep, OID_AUTO, acpi_root, CTLFLAG_RD, &acpi_root_phys, 0,
+ "The physical address of the RSDP");
-static inline struct pcpu *
-get_pcpu(void)
+ACPI_STATUS
+AcpiOsInitialize(void)
{
- struct pcpu *pcpu;
- __asm __volatile("mov %0, x18" : "=&r"(pcpu));
- return (pcpu);
+ return (AE_OK);
}
-static inline struct thread *
-get_curthread(void)
+ACPI_STATUS
+AcpiOsTerminate(void)
{
- struct thread *td;
- __asm __volatile("ldr %0, [x18]" : "=&r"(td));
- return (td);
+ return (AE_OK);
}
-#define curthread get_curthread()
+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);
-#define PCPU_GET(member) (get_pcpu()->pc_ ## member)
-#define PCPU_ADD(member, value) (get_pcpu()->pc_ ## member += (value))
-#define PCPU_INC(member) PCPU_ADD(member, 1)
-#define PCPU_PTR(member) (&get_pcpu()->pc_ ## member)
-#define PCPU_SET(member,value) (get_pcpu()->pc_ ## member = (value))
+ return (0);
+}
+
+ACPI_PHYSICAL_ADDRESS
+AcpiOsGetRootPointer(void)
+{
-#endif /* _KERNEL */
+ if (acpi_root_phys == 0)
+ acpi_root_phys = acpi_get_root_from_loader();
-#endif /* !_MACHINE_PCPU_H_ */
+ return (acpi_root_phys);
+}
Index: sys/arm64/acpica/acpi_machdep.c
===================================================================
--- /dev/null
+++ sys/arm64/acpica/acpi_machdep.c
@@ -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);
+}
Index: sys/arm64/acpica/acpi_wakeup.c
===================================================================
--- sys/arm64/acpica/acpi_wakeup.c
+++ sys/arm64/acpica/acpi_wakeup.c
@@ -1,7 +1,10 @@
/*-
- * Copyright (c) 1999 Luoqi Chen <luoqi@freebsd.org>
+ * 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:
@@ -22,53 +25,37 @@
* 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.
- *
- * from: FreeBSD: src/sys/i386/include/globaldata.h,v 1.27 2001/04/27
- * $FreeBSD$
*/
-#ifndef _MACHINE_PCPU_H_
-#define _MACHINE_PCPU_H_
-
-#include <machine/cpu.h>
-#include <machine/cpufunc.h>
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
-#define ALT_STACK_SIZE 128
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
-#define PCPU_MD_FIELDS \
- char __pad[129]
+#include <contrib/dev/acpica/include/acpi.h>
-#ifdef _KERNEL
+#include <dev/acpica/acpivar.h>
-struct pcb;
-struct pcpu;
-
-static inline struct pcpu *
-get_pcpu(void)
+/*
+ * ARM64TODO: Implement this.
+ */
+int
+acpi_sleep_machdep(struct acpi_softc *sc, int state)
{
- struct pcpu *pcpu;
- __asm __volatile("mov %0, x18" : "=&r"(pcpu));
- return (pcpu);
+ return (-1);
}
-static inline struct thread *
-get_curthread(void)
+int
+acpi_wakeup_machdep(struct acpi_softc *sc, int state, int sleep_result,
+ int intr_enabled)
{
- struct thread *td;
- __asm __volatile("ldr %0, [x18]" : "=&r"(td));
- return (td);
-}
-
-#define curthread get_curthread()
-
-#define PCPU_GET(member) (get_pcpu()->pc_ ## member)
-#define PCPU_ADD(member, value) (get_pcpu()->pc_ ## member += (value))
-#define PCPU_INC(member) PCPU_ADD(member, 1)
-#define PCPU_PTR(member) (&get_pcpu()->pc_ ## member)
-#define PCPU_SET(member,value) (get_pcpu()->pc_ ## member = (value))
+ /* ARM64TODO: We will need this with acpi_sleep_machdep */
+ KASSERT(sleep_result == -1,
+ ("acpi_wakeup_machdep: Invalid sleep result"));
-#endif /* _KERNEL */
-
-#endif /* !_MACHINE_PCPU_H_ */
+ return (sleep_result);
+}
Index: sys/arm64/arm64/gic.h
===================================================================
--- sys/arm64/arm64/gic.h
+++ sys/arm64/arm64/gic.h
@@ -1,7 +1,12 @@
/*-
- * Copyright (c) 1999 Luoqi Chen <luoqi@freebsd.org>
+ * 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:
@@ -10,11 +15,14 @@
* 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
+ * 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)
@@ -22,53 +30,23 @@
* 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.
- *
- * from: FreeBSD: src/sys/i386/include/globaldata.h,v 1.27 2001/04/27
- * $FreeBSD$
*/
-#ifndef _MACHINE_PCPU_H_
-#define _MACHINE_PCPU_H_
-
-#include <machine/cpu.h>
-#include <machine/cpufunc.h>
-
-#define ALT_STACK_SIZE 128
-
-#define PCPU_MD_FIELDS \
- char __pad[129]
-
-#ifdef _KERNEL
-
-struct pcb;
-struct pcpu;
-
-static inline struct pcpu *
-get_pcpu(void)
-{
- struct pcpu *pcpu;
-
- __asm __volatile("mov %0, x18" : "=&r"(pcpu));
- return (pcpu);
-}
-
-static inline struct thread *
-get_curthread(void)
-{
- struct thread *td;
-
- __asm __volatile("ldr %0, [x18]" : "=&r"(td));
- return (td);
-}
-
-#define curthread get_curthread()
+#ifndef _ARM64_GIC_H_
+#define _ARM64_GIC_H_
-#define PCPU_GET(member) (get_pcpu()->pc_ ## member)
-#define PCPU_ADD(member, value) (get_pcpu()->pc_ ## member += (value))
-#define PCPU_INC(member) PCPU_ADD(member, 1)
-#define PCPU_PTR(member) (&get_pcpu()->pc_ ## member)
-#define PCPU_SET(member,value) (get_pcpu()->pc_ ## member = (value))
+DECLARE_CLASS(arm_gic_driver);
-#endif /* _KERNEL */
+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 /* !_MACHINE_PCPU_H_ */
+#endif
Index: sys/arm64/arm64/gic.c
===================================================================
--- sys/arm64/arm64/gic.c
+++ sys/arm64/arm64/gic.c
@@ -51,11 +51,7 @@
#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 @@
#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_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 @@
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 @@
{ 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));
Index: sys/arm64/arm64/gic_acpi.c
===================================================================
--- /dev/null
+++ sys/arm64/arm64/gic_acpi.c
@@ -0,0 +1,167 @@
+/*-
+ * 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)
+{
+
+ if (device_get_unit(dev) != 0)
+ return (ENXIO);
+
+ if (acpi_get_type(dev) != ACPI_TYPE_NOT_FOUND)
+ return (ENXIO);
+
+ device_set_desc(dev, "ARM Generic Interrupt Controller");
+ return (BUS_PROBE_DEFAULT);
+}
+
+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);
Index: sys/arm64/arm64/gic_fdt.c
===================================================================
--- /dev/null
+++ sys/arm64/arm64/gic_fdt.c
@@ -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);
Index: sys/arm64/arm64/machdep.c
===================================================================
--- sys/arm64/arm64/machdep.c
+++ sys/arm64/arm64/machdep.c
@@ -392,6 +392,8 @@
void
cpu_pcpu_init(struct pcpu *pcpu, int cpuid, size_t size)
{
+
+ pcpu->pc_acpi_id = 0xffffffff;
}
void
Index: sys/arm64/arm64/nexus.c
===================================================================
--- sys/arm64/arm64/nexus.c
+++ sys/arm64/arm64/nexus.c
@@ -60,12 +60,17 @@
#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 @@
#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 *,
@@ -89,6 +104,8 @@
struct resource *);
static int nexus_config_intr(device_t dev, int irq, enum intr_trigger trig,
enum intr_polarity pol);
+static struct resource_list *nexus_get_reslist(device_t, device_t);
+static int nexus_set_resource(device_t, device_t, int, int, u_long, u_long);
static int nexus_deactivate_resource(device_t, device_t, int, int,
struct resource *);
@@ -102,21 +119,18 @@
#endif
static device_method_t nexus_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, nexus_probe),
- DEVMETHOD(device_attach, nexus_attach),
/* Bus interface */
DEVMETHOD(bus_print_child, nexus_print_child),
DEVMETHOD(bus_add_child, nexus_add_child),
DEVMETHOD(bus_alloc_resource, nexus_alloc_resource),
DEVMETHOD(bus_activate_resource, nexus_activate_resource),
DEVMETHOD(bus_config_intr, nexus_config_intr),
+ DEVMETHOD(bus_get_resource_list, nexus_get_reslist),
+ DEVMETHOD(bus_set_resource, nexus_set_resource),
DEVMETHOD(bus_deactivate_resource, nexus_deactivate_resource),
DEVMETHOD(bus_setup_intr, nexus_setup_intr),
DEVMETHOD(bus_teardown_intr, nexus_teardown_intr),
-#ifdef FDT
- DEVMETHOD(ofw_bus_map_intr, nexus_ofw_map_intr),
-#endif
+
{ 0, 0 }
};
@@ -129,15 +143,6 @@
DRIVER_MODULE(nexus, root, nexus_driver, nexus_devclass, 0, 0);
static int
-nexus_probe(device_t dev)
-{
-
- device_quiet(dev); /* suppress attach message for neatness */
-
- return (BUS_PROBE_DEFAULT);
-}
-
-static int
nexus_attach(device_t dev)
{
@@ -146,15 +151,14 @@
mem_rman.rm_type = RMAN_ARRAY;
mem_rman.rm_descr = "I/O memory addresses";
if (rman_init(&mem_rman) || rman_manage_region(&mem_rman, 0, ~0))
- panic("nexus_probe mem_rman");
-
- /* Add the ofwbus device */
- /* ARM64TODO: Alternatively add acpi */
- nexus_add_child(dev, 10, "ofwbus", 0);
+ panic("nexus_attach mem_rman");
+ irq_rman.rm_start = 0;
+ irq_rman.rm_end = ~0ul;
+ irq_rman.rm_type = RMAN_ARRAY;
+ irq_rman.rm_descr = "Interrupts";
+ if (rman_init(&irq_rman) || rman_manage_region(&irq_rman, 0, ~0))
+ panic("nexus_attach irq_rman");
- /*
- * First, deal with the children we know about already
- */
bus_generic_probe(dev);
bus_generic_attach(dev);
@@ -201,11 +205,34 @@
nexus_alloc_resource(device_t bus, device_t child, int type, int *rid,
u_long start, u_long end, u_long count, u_int flags)
{
+ struct nexus_device *ndev = DEVTONX(child);
struct resource *rv;
+ struct resource_list_entry *rle;
struct rman *rm;
int needactivate = flags & RF_ACTIVE;
+ /*
+ * If this is an allocation of the "default" range for a given
+ * RID, and we know what the resources for this device are
+ * (ie. they aren't maintained by a child bus), then work out
+ * the start/end values.
+ */
+ if ((start == 0UL) && (end == ~0UL) && (count == 1)) {
+ if (device_get_parent(child) != bus || ndev == NULL)
+ return(NULL);
+ rle = resource_list_find(&ndev->nx_resources, type, *rid);
+ if (rle == NULL)
+ return(NULL);
+ start = rle->start;
+ end = rle->end;
+ count = rle->count;
+ }
+
switch (type) {
+ case SYS_RES_IRQ:
+ rm = &irq_rman;
+ break;
+
case SYS_RES_MEMORY:
case SYS_RES_IOPORT:
rm = &mem_rman;
@@ -297,6 +324,28 @@
return (0);
}
+static struct resource_list *
+nexus_get_reslist(device_t dev, device_t child)
+{
+ struct nexus_device *ndev = DEVTONX(child);
+
+ return (&ndev->nx_resources);
+}
+
+static int
+nexus_set_resource(device_t dev, device_t child, int type, int rid,
+ u_long start, u_long count)
+{
+ struct nexus_device *ndev = DEVTONX(child);
+ struct resource_list *rl = &ndev->nx_resources;
+
+ /* XXX this should return a success/failure indicator */
+ resource_list_add(rl, type, rid, start, start + count - 1, count);
+
+ return(0);
+}
+
+
static int
nexus_deactivate_resource(device_t bus, device_t child, int type, int rid,
struct resource *r)
@@ -317,6 +366,41 @@
}
#ifdef FDT
+static device_method_t nexus_fdt_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, nexus_fdt_probe),
+ DEVMETHOD(device_attach, nexus_fdt_attach),
+
+ /* OFW interface */
+ DEVMETHOD(ofw_bus_map_intr, nexus_ofw_map_intr),
+};
+
+#define nexus_baseclasses nexus_fdt_baseclasses
+DEFINE_CLASS_1(nexus, nexus_fdt_driver, nexus_fdt_methods, 1, nexus_driver);
+#undef nexus_baseclasses
+static devclass_t nexus_fdt_devclass;
+
+DRIVER_MODULE(nexus_fdt, root, nexus_fdt_driver, nexus_fdt_devclass, 0, 0);
+
+static int
+nexus_fdt_probe(device_t dev)
+{
+
+ if (OF_peer(0) == 0)
+ return (ENXIO);
+
+ device_quiet(dev);
+ return (BUS_PROBE_DEFAULT);
+}
+
+static int
+nexus_fdt_attach(device_t dev)
+{
+
+ nexus_add_child(dev, 10, "ofwbus", 0);
+ return (nexus_attach(dev));
+}
+
static int
nexus_ofw_map_intr(device_t dev, device_t child, phandle_t iparent, int icells,
pcell_t *intr)
@@ -336,3 +420,37 @@
}
#endif
+#ifdef DEV_ACPI
+static device_method_t nexus_acpi_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, nexus_acpi_probe),
+ DEVMETHOD(device_attach, nexus_acpi_attach),
+};
+
+#define nexus_baseclasses nexus_acpi_baseclasses
+DEFINE_CLASS_1(nexus, nexus_acpi_driver, nexus_acpi_methods, 1,
+ nexus_driver);
+#undef nexus_baseclasses
+static devclass_t nexus_acpi_devclass;
+
+DRIVER_MODULE(nexus_acpi, root, nexus_acpi_driver, nexus_acpi_devclass, 0, 0);
+
+static int
+nexus_acpi_probe(device_t dev)
+{
+
+ if (acpi_identify() != 0)
+ return (ENXIO);
+
+ device_quiet(dev);
+ return (BUS_PROBE_LOW_PRIORITY);
+}
+
+static int
+nexus_acpi_attach(device_t dev)
+{
+
+ nexus_add_child(dev, 10, "acpi", 0);
+ return (nexus_attach(dev));
+}
+#endif
Index: sys/arm64/conf/GENERIC
===================================================================
--- sys/arm64/conf/GENERIC
+++ sys/arm64/conf/GENERIC
@@ -95,3 +95,4 @@
device bpf # Berkeley packet filter
options FDT
+device acpi
Index: sys/arm64/include/acpica_machdep.h
===================================================================
--- /dev/null
+++ sys/arm64/include/acpica_machdep.h
@@ -0,0 +1,94 @@
+/*-
+ * Copyright (c) 2002 Mitsuru IWASAKI
+ * 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.
+ *
+ * $FreeBSD$
+ */
+
+/******************************************************************************
+ *
+ * Name: acpica_machdep.h - arch-specific defines, etc.
+ * $Revision$
+ *
+ *****************************************************************************/
+
+#ifndef __ACPICA_MACHDEP_H__
+#define __ACPICA_MACHDEP_H__
+
+
+#ifdef _KERNEL
+/*
+ * Calling conventions:
+ *
+ * ACPI_SYSTEM_XFACE - Interfaces to host OS (handlers, threads)
+ * ACPI_EXTERNAL_XFACE - External ACPI interfaces
+ * ACPI_INTERNAL_XFACE - Internal ACPI interfaces
+ * ACPI_INTERNAL_VAR_XFACE - Internal variable-parameter list interfaces
+ */
+#if 0
+#define ACPI_SYSTEM_XFACE
+#define ACPI_EXTERNAL_XFACE
+#define ACPI_INTERNAL_XFACE
+#define ACPI_INTERNAL_VAR_XFACE
+
+/* Asm macros */
+
+#define ACPI_ASM_MACROS
+#define BREAKPOINT3
+#define ACPI_DISABLE_IRQS() disable_intr()
+#define ACPI_ENABLE_IRQS() enable_intr()
+
+#define ACPI_FLUSH_CPU_CACHE() wbinvd()
+#endif
+
+/* Section 5.2.10.1: global lock acquire/release functions */
+int acpi_acquire_global_lock(volatile uint32_t *);
+int acpi_release_global_lock(volatile uint32_t *);
+#if 0
+#define ACPI_ACQUIRE_GLOBAL_LOCK(GLptr, Acq) do { \
+ (Acq) = acpi_acquire_global_lock(&((GLptr)->GlobalLock)); \
+} while (0)
+#define ACPI_RELEASE_GLOBAL_LOCK(GLptr, Acq) do { \
+ (Acq) = acpi_release_global_lock(&((GLptr)->GlobalLock)); \
+} while (0)
+
+enum intr_trigger;
+enum intr_polarity;
+
+void acpi_SetDefaultIntrModel(int model);
+void acpi_cpu_c1(void);
+#endif
+void *acpi_map_table(vm_paddr_t pa, const char *sig);
+void acpi_unmap_table(void *table);
+vm_paddr_t acpi_find_table(const char *sig);
+#if 0
+void madt_parse_interrupt_values(void *entry,
+ enum intr_trigger *trig, enum intr_polarity *pol);
+
+extern int madt_found_sci_override;
+#endif /* 0 */
+
+#endif /* _KERNEL */
+
+#endif /* __ACPICA_MACHDEP_H__ */
Index: sys/arm64/include/iodev.h
===================================================================
--- sys/arm64/include/iodev.h
+++ sys/arm64/include/iodev.h
@@ -1,7 +1,10 @@
/*-
- * Copyright (c) 1999 Luoqi Chen <luoqi@freebsd.org>
+ * 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:
@@ -23,52 +26,40 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * from: FreeBSD: src/sys/i386/include/globaldata.h,v 1.27 2001/04/27
* $FreeBSD$
*/
-#ifndef _MACHINE_PCPU_H_
-#define _MACHINE_PCPU_H_
-
-#include <machine/cpu.h>
-#include <machine/cpufunc.h>
-
-#define ALT_STACK_SIZE 128
-
-#define PCPU_MD_FIELDS \
- char __pad[129]
-
-#ifdef _KERNEL
-
-struct pcb;
-struct pcpu;
-
-static inline struct pcpu *
-get_pcpu(void)
-{
- struct pcpu *pcpu;
+#ifndef _MACHINE_IODEV_H_
+#define _MACHINE_IODEV_H_
- __asm __volatile("mov %0, x18" : "=&r"(pcpu));
- return (pcpu);
-}
+#define iodev_read_1(a) \
+({ \
+ uint8_t val; \
+ __asm __volatile("ldrb %w0, [%1]" : "=&r" (val) : "r"(a)); \
+ val; \
+})
-static inline struct thread *
-get_curthread(void)
-{
- struct thread *td;
+#define iodev_read_2(a) \
+({ \
+ uint16_t val; \
+ __asm __volatile("ldrh %w0, [%1]" : "=&r" (val) : "r"(a)); \
+ val; \
+})
- __asm __volatile("ldr %0, [x18]" : "=&r"(td));
- return (td);
-}
+#define iodev_read_4(a) \
+({ \
+ uint32_t val; \
+ __asm __volatile("ldr %w0, [%1]" : "=&r" (val) : "r"(a)); \
+ val; \
+})
-#define curthread get_curthread()
+#define iodev_write_1(a, v) \
+ __asm __volatile("strb %w0, [%1]" :: "r" (v), "r"(a))
-#define PCPU_GET(member) (get_pcpu()->pc_ ## member)
-#define PCPU_ADD(member, value) (get_pcpu()->pc_ ## member += (value))
-#define PCPU_INC(member) PCPU_ADD(member, 1)
-#define PCPU_PTR(member) (&get_pcpu()->pc_ ## member)
-#define PCPU_SET(member,value) (get_pcpu()->pc_ ## member = (value))
+#define iodev_write_2(a, v) \
+ __asm __volatile("strh %w0, [%1]" :: "r" (v), "r"(a))
-#endif /* _KERNEL */
+#define iodev_write_4(a, v) \
+ __asm __volatile("str %w0, [%1]" :: "r" (v), "r"(a))
-#endif /* !_MACHINE_PCPU_H_ */
+#endif /* _MACHINE_IODEV_H_ */
Index: sys/arm64/include/pci_cfgreg.h
===================================================================
--- /dev/null
+++ sys/arm64/include/pci_cfgreg.h
@@ -0,0 +1 @@
+/* $FreeBSD$ */
Index: sys/arm64/include/pcpu.h
===================================================================
--- sys/arm64/include/pcpu.h
+++ sys/arm64/include/pcpu.h
@@ -36,7 +36,8 @@
#define ALT_STACK_SIZE 128
#define PCPU_MD_FIELDS \
- char __pad[129]
+ u_int pc_acpi_id; /* ACPI CPU id */ \
+ char __pad[125]
#ifdef _KERNEL
Index: sys/conf/Makefile.arm64
===================================================================
--- sys/conf/Makefile.arm64
+++ sys/conf/Makefile.arm64
@@ -33,6 +33,9 @@
# Reserve x18 for pcpu data
CFLAGS += -ffixed-x18
+# Only use the reduced hardware model
+CFLAGS += -DACPI_REDUCED_HARDWARE
+
.if !empty(DDB_ENABLED)
CFLAGS += -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer
.endif
Index: sys/conf/files.arm64
===================================================================
--- sys/conf/files.arm64
+++ sys/conf/files.arm64
@@ -2,6 +2,9 @@
arm/arm/devmap.c standard
arm/arm/generic_timer.c standard
arm/arm/pmu.c standard
+arm64/acpica/acpi_machdep.c optional acpi
+arm64/acpica/OsdEnvironment.c optional acpi
+arm64/acpica/acpi_wakeup.c optional acpi
arm64/arm64/autoconf.c standard
arm64/arm64/bcopy.c standard
arm64/arm64/bus_machdep.c standard
@@ -20,6 +23,8 @@
arm64/arm64/elf_machdep.c standard
arm64/arm64/exception.S standard
arm64/arm64/gic.c standard
+arm64/arm64/gic_acpi.c optional acpi
+arm64/arm64/gic_fdt.c optional fdt
arm64/arm64/gic_v3.c standard
arm64/arm64/gic_v3_fdt.c optional fdt
arm64/arm64/identcpu.c standard
@@ -40,6 +45,7 @@
arm64/arm64/uio_machdep.c standard
arm64/arm64/vfp.c standard
arm64/arm64/vm_machdep.c standard
+dev/acpica/acpi_if.m optional acpi
dev/fdt/fdt_arm64.c optional fdt
dev/hwpmc/hwpmc_arm64.c optional hwpmc
dev/hwpmc/hwpmc_arm64_md.c optional hwpmc
Index: sys/dev/acpica/Osd/OsdHardware.c
===================================================================
--- sys/dev/acpica/Osd/OsdHardware.c
+++ sys/dev/acpica/Osd/OsdHardware.c
@@ -89,6 +89,10 @@
UINT32 Width)
{
+#ifdef __aarch64__
+ /* ARM64TODO: Add pci support */
+ return (AE_SUPPORT);
+#else
if (Width == 64)
return (AE_SUPPORT);
@@ -99,6 +103,7 @@
PciId->Function, Register, Width / 8);
return (AE_OK);
+#endif
}
@@ -107,6 +112,10 @@
UINT64 Value, UINT32 Width)
{
+#ifdef __aarch64__
+ /* ARM64TODO: Add pci support */
+ return (AE_SUPPORT);
+#else
if (Width == 64)
return (AE_SUPPORT);
@@ -117,4 +126,5 @@
Value, Width / 8);
return (AE_OK);
+#endif
}
Index: sys/dev/acpica/acpi_cpu.c
===================================================================
--- sys/dev/acpica/acpi_cpu.c
+++ sys/dev/acpica/acpi_cpu.c
@@ -183,7 +183,9 @@
static void acpi_cpu_startup(void *arg);
static void acpi_cpu_startup_cx(struct acpi_cpu_softc *sc);
static void acpi_cpu_cx_list(struct acpi_cpu_softc *sc);
+#if defined(__i386__) || defined(__amd64__)
static void acpi_cpu_idle(sbintime_t sbt);
+#endif
static void acpi_cpu_notify(ACPI_HANDLE h, UINT32 notify, void *context);
static int acpi_cpu_quirks(void);
static int acpi_cpu_usage_sysctl(SYSCTL_HANDLER_ARGS);
@@ -474,12 +476,14 @@
sc->cpu_disable_idle = FALSE;
}
+#if defined(__i386__) || defined(__amd64__)
static int
is_idle_disabled(struct acpi_cpu_softc *sc)
{
return (sc->cpu_disable_idle);
}
+#endif
/*
* Disable any entry to the idle function during suspend and re-enable it
@@ -998,7 +1002,9 @@
sc = device_get_softc(cpu_devices[i]);
enable_idle(sc);
}
+#if defined(__i386__) || defined(__amd64__)
cpu_idle_hook = acpi_cpu_idle;
+#endif
}
static void
@@ -1060,6 +1066,7 @@
}
}
+#if defined(__i386__) || defined(__amd64__)
/*
* Idle the CPU in the lowest state possible. This function is called with
* interrupts disabled. Note that once it re-enables interrupts, a task
@@ -1206,6 +1213,7 @@
sc->cpu_prev_sleep = (sc->cpu_prev_sleep * 3 + PM_USEC(end_time)) / 4;
}
+#endif
/*
* Re-evaluate the _CST object when we are notified that it changed.
@@ -1242,8 +1250,10 @@
static int
acpi_cpu_quirks(void)
{
+#if defined(__i386__) || defined(__amd64__)
device_t acpi_dev;
uint32_t val;
+#endif
ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
@@ -1277,6 +1287,7 @@
"acpi_cpu: SMP, using flush cache mode for C3\n"));
}
+#if defined(__i386__) || defined(__amd64__)
/* Look for various quirks of the PIIX4 part. */
acpi_dev = pci_find_device(PCI_VENDOR_INTEL, PCI_DEVICE_82371AB_3);
if (acpi_dev != NULL) {
@@ -1326,6 +1337,7 @@
break;
}
}
+#endif
return (0);
}
Index: sys/dev/acpica/acpi_throttle.c
===================================================================
--- sys/dev/acpica/acpi_throttle.c
+++ sys/dev/acpica/acpi_throttle.c
@@ -317,6 +317,7 @@
static int
acpi_throttle_quirks(struct acpi_throttle_softc *sc)
{
+#if defined(__i386__) || defined(__amd64__)
device_t acpi_dev;
/* Look for various quirks of the PIIX4 part. */
@@ -339,6 +340,7 @@
break;
}
}
+#endif
return (0);
}

File Metadata

Mime Type
text/plain
Expires
Wed, Nov 19, 4:30 AM (3 h, 35 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
25594486
Default Alt Text
D2463.id5526.diff (46 KB)

Event Timeline