Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F136525986
D2463.id5526.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
46 KB
Referenced Files
None
Subscribers
None
D2463.id5526.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D2463: Add ACPI support for arm64
Attached
Detach File
Event Timeline
Log In to Comment