Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F143167298
D8617.id.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
9 KB
Referenced Files
None
Subscribers
None
D8617.id.diff
View Options
Index: head/sys/arm/arm/generic_timer.c
===================================================================
--- head/sys/arm/arm/generic_timer.c
+++ head/sys/arm/arm/generic_timer.c
@@ -72,6 +72,7 @@
#ifdef DEV_ACPI
#include <contrib/dev/acpica/include/acpi.h>
#include <dev/acpica/acpivar.h>
+#include "acpi_bus_if.h"
#endif
#define GT_CTRL_ENABLE (1 << 0)
@@ -313,6 +314,15 @@
#ifdef DEV_ACPI
static void
+arm_tmr_acpi_add_irq(device_t parent, device_t dev, int rid, u_int irq)
+{
+
+ irq = ACPI_BUS_MAP_INTR(parent, dev, irq,
+ INTR_TRIGGER_LEVEL, INTR_POLARITY_HIGH);
+ BUS_SET_RESOURCE(parent, dev, SYS_RES_IRQ, rid, irq, 1);
+}
+
+static void
arm_tmr_acpi_identify(driver_t *driver, device_t parent)
{
ACPI_TABLE_GTDT *gtdt;
@@ -336,12 +346,9 @@
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);
+ arm_tmr_acpi_add_irq(parent, dev, 0, gtdt->SecureEl1Interrupt);
+ arm_tmr_acpi_add_irq(parent, dev, 1, gtdt->NonSecureEl1Interrupt);
+ arm_tmr_acpi_add_irq(parent, dev, 2, gtdt->VirtualTimerInterrupt);
out:
acpi_unmap_table(gtdt);
Index: head/sys/arm64/arm64/nexus.c
===================================================================
--- head/sys/arm64/arm64/nexus.c
+++ head/sys/arm64/arm64/nexus.c
@@ -72,6 +72,7 @@
#ifdef DEV_ACPI
#include <contrib/dev/acpica/include/acpi.h>
#include <dev/acpica/acpivar.h>
+#include "acpi_bus_if.h"
#endif
extern struct bus_space memmap_bus;
@@ -460,11 +461,16 @@
#endif
#ifdef DEV_ACPI
+static int nexus_acpi_map_intr(device_t dev, device_t child, u_int irq, int trig, int pol);
+
static device_method_t nexus_acpi_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, nexus_acpi_probe),
DEVMETHOD(device_attach, nexus_acpi_attach),
+ /* ACPI interface */
+ DEVMETHOD(acpi_bus_map_intr, nexus_acpi_map_intr),
+
DEVMETHOD_END,
};
@@ -494,5 +500,31 @@
nexus_add_child(dev, 10, "acpi", 0);
return (nexus_attach(dev));
+}
+
+static int
+nexus_acpi_map_intr(device_t dev, device_t child, u_int irq, int trig, int pol)
+{
+ struct intr_map_data_acpi *acpi_data;
+ size_t len;
+
+ len = sizeof(*acpi_data);
+ acpi_data = (struct intr_map_data_acpi *)intr_alloc_map_data(
+ INTR_MAP_DATA_ACPI, len, M_WAITOK | M_ZERO);
+ acpi_data->irq = irq;
+ acpi_data->pol = pol;
+ acpi_data->trig = trig;
+
+ /*
+ * TODO: This will only handle a single interrupt controller.
+ * ACPI will map multiple controllers into a single virtual IRQ
+ * space. Each controller has a System Vector Base to hold the
+ * first irq it handles in this space. As such the correct way
+ * to handle interrupts with ACPI is to search through the
+ * controllers for the largest base value that is no larger than
+ * the IRQ value.
+ */
+ irq = intr_map_irq(NULL, 0, (struct intr_map_data *)acpi_data);
+ return (irq);
}
#endif
Index: head/sys/conf/files.arm64
===================================================================
--- head/sys/conf/files.arm64
+++ head/sys/conf/files.arm64
@@ -167,6 +167,7 @@
clean "armv8_crypto_wrap.o"
crypto/blowfish/bf_enc.c optional crypto | ipsec | ipsec_support
crypto/des/des_enc.c optional crypto | ipsec | ipsec_support | netsmb
+dev/acpica/acpi_bus_if.m optional acpi
dev/acpica/acpi_if.m optional acpi
dev/ahci/ahci_generic.c optional ahci
dev/axgbe/if_axgbe.c optional axgbe
Index: head/sys/dev/acpica/acpi.c
===================================================================
--- head/sys/dev/acpica/acpi.c
+++ head/sys/dev/acpica/acpi.c
@@ -1358,7 +1358,9 @@
acpi_alloc_resource(device_t bus, device_t child, int type, int *rid,
rman_res_t start, rman_res_t end, rman_res_t count, u_int flags)
{
+#ifndef INTRNG
ACPI_RESOURCE ares;
+#endif
struct acpi_device *ad;
struct resource_list_entry *rle;
struct resource_list *rl;
@@ -1385,6 +1387,7 @@
resource_list_add(rl, type, *rid, start, end, count);
res = resource_list_alloc(rl, bus, child, type, rid, start, end, count,
flags);
+#ifndef INTRNG
if (res != NULL && type == SYS_RES_IRQ) {
/*
* Since bus_config_intr() takes immediate effect, we cannot
@@ -1397,6 +1400,7 @@
if (ACPI_SUCCESS(acpi_lookup_irq_resource(child, *rid, res, &ares)))
acpi_config_intr(child, &ares);
}
+#endif
/*
* If this is an allocation of the "default" range for a given
Index: head/sys/dev/acpica/acpi_bus_if.m
===================================================================
--- head/sys/dev/acpica/acpi_bus_if.m
+++ head/sys/dev/acpica/acpi_bus_if.m
@@ -0,0 +1,67 @@
+#-
+# Copyright (c) 2016 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.
+#
+# $FreeBSD$
+
+#include <sys/types.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+
+INTERFACE acpi_bus;
+
+CODE {
+ static acpi_bus_map_intr_t acpi_bus_default_map_intr;
+
+ int
+ acpi_bus_default_map_intr(device_t bus, device_t dev, u_int irq,
+ int trig, int pol)
+ {
+ device_t parent;
+
+ /* Pass up the hierarchy */
+ parent = device_get_parent(bus);
+ if (parent != NULL)
+ return (ACPI_BUS_MAP_INTR(parent, dev, irq, trig, pol));
+
+ panic("Unable to map interrupt %u", irq);
+ }
+};
+
+# Map an interrupt from ACPI space to the FreeBSD IRQ space. Note that
+# both of these may be different than the pysical interrupt space as this
+# may be local to each interrupt controller.
+#
+# This method also associates interrupt metadata with the interrupt,
+# removing the need for a post hoc configure step.
+METHOD int map_intr {
+ device_t bus;
+ device_t dev;
+ u_int irq;
+ int trig;
+ int pol;
+} DEFAULT acpi_bus_default_map_intr;
Index: head/sys/dev/acpica/acpi_resource.c
===================================================================
--- head/sys/dev/acpica/acpi_resource.c
+++ head/sys/dev/acpica/acpi_resource.c
@@ -45,6 +45,10 @@
#include <dev/acpica/acpivar.h>
+#ifdef INTRNG
+#include "acpi_bus_if.h"
+#endif
+
/* Hooks for the ACPI CA debugging infrastructure */
#define _COMPONENT ACPI_BUS
ACPI_MODULE_NAME("RESOURCE")
@@ -556,6 +560,7 @@
int trig, int pol)
{
struct acpi_res_context *cp = (struct acpi_res_context *)context;
+ rman_res_t intr;
if (cp == NULL || irq == NULL)
return;
@@ -564,7 +569,14 @@
if (count != 1)
return;
- bus_set_resource(dev, SYS_RES_IRQ, cp->ar_nirq++, *irq, 1);
+#ifdef INTRNG
+ intr = ACPI_BUS_MAP_INTR(device_get_parent(dev), dev, *irq,
+ (trig == ACPI_EDGE_SENSITIVE) ? INTR_TRIGGER_EDGE : INTR_TRIGGER_LEVEL,
+ (pol == ACPI_ACTIVE_HIGH) ? INTR_POLARITY_HIGH : INTR_POLARITY_LOW);
+#else
+ intr = *irq;
+#endif
+ bus_set_resource(dev, SYS_RES_IRQ, cp->ar_nirq++, intr, 1);
}
static void
@@ -572,6 +584,7 @@
int trig, int pol)
{
struct acpi_res_context *cp = (struct acpi_res_context *)context;
+ rman_res_t intr;
if (cp == NULL || irq == NULL)
return;
@@ -580,7 +593,14 @@
if (count != 1)
return;
- bus_set_resource(dev, SYS_RES_IRQ, cp->ar_nirq++, *irq, 1);
+#ifdef INTRNG
+ intr = ACPI_BUS_MAP_INTR(device_get_parent(dev), dev, *irq,
+ (trig == ACPI_EDGE_SENSITIVE) ? INTR_TRIGGER_EDGE : INTR_TRIGGER_LEVEL,
+ (pol == ACPI_ACTIVE_HIGH) ? INTR_POLARITY_HIGH : INTR_POLARITY_LOW);
+#else
+ intr = *irq;
+#endif
+ bus_set_resource(dev, SYS_RES_IRQ, cp->ar_nirq++, intr, 1);
}
static void
Index: head/sys/dev/acpica/acpivar.h
===================================================================
--- head/sys/dev/acpica/acpivar.h
+++ head/sys/dev/acpica/acpivar.h
@@ -36,6 +36,9 @@
#include "acpi_if.h"
#include "bus_if.h"
#include <sys/eventhandler.h>
+#ifdef INTRNG
+#include <sys/intr.h>
+#endif
#include <sys/ktr.h>
#include <sys/lock.h>
#include <sys/mutex.h>
@@ -90,6 +93,16 @@
/* Resources */
struct resource_list ad_rl;
};
+
+#ifdef INTRNG
+struct intr_map_data_acpi {
+ struct intr_map_data hdr;
+ u_int irq;
+ u_int pol;
+ u_int trig;
+};
+
+#endif
/* Track device (/dev/{apm,apmctl} and /dev/acpi) notification status. */
struct apm_clone_data {
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Jan 27, 8:38 PM (3 h, 27 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28060069
Default Alt Text
D8617.id.diff (9 KB)
Attached To
Mode
D8617: Add ACPI support to INTRNG.
Attached
Detach File
Event Timeline
Log In to Comment