summaryrefslogtreecommitdiffstats
path: root/sys/arm
diff options
context:
space:
mode:
authorbz <bz@FreeBSD.org>2016-05-04 16:15:39 +0000
committerbz <bz@FreeBSD.org>2016-05-04 16:15:39 +0000
commit64ae5d371f0ee7f0b0d74b0784b299d3bd90c1b7 (patch)
tree8e860d8c38324f0ccdf106d3804c70c65da4367a /sys/arm
parenta3bf622b6a79aed42ea15ff970771a99c251027b (diff)
downloadFreeBSD-src-64ae5d371f0ee7f0b0d74b0784b299d3bd90c1b7.zip
FreeBSD-src-64ae5d371f0ee7f0b0d74b0784b299d3bd90c1b7.tar.gz
The virtual timer is optional on ARM64. Properly handle that condition. [1]
In case we do not have an interrupt assignment for the virtual timer, force the physical timer. Also skip resource allocation for any timer we do not have an interrupt assignment for. In collaboration with: andrew Submitted by: br ([1] from his gem5 arm64 work) Sponsored by: DARPA/AFRL Reviewed by: andrew MFC after: 2 weeks Differential Revision: https://reviews.freebsd.org/D6203
Diffstat (limited to 'sys/arm')
-rw-r--r--sys/arm/arm/generic_timer.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/sys/arm/arm/generic_timer.c b/sys/arm/arm/generic_timer.c
index ba612dc..dcf48bc 100644
--- a/sys/arm/arm/generic_timer.c
+++ b/sys/arm/arm/generic_timer.c
@@ -100,7 +100,7 @@ static struct arm_tmr_softc *arm_tmr_sc = NULL;
static struct resource_spec timer_spec[] = {
{ SYS_RES_IRQ, 0, RF_ACTIVE }, /* Secure */
{ SYS_RES_IRQ, 1, RF_ACTIVE }, /* Non-secure */
- { SYS_RES_IRQ, 2, RF_ACTIVE }, /* Virt */
+ { SYS_RES_IRQ, 2, RF_ACTIVE | RF_OPTIONAL }, /* Virt */
{ SYS_RES_IRQ, 3, RF_ACTIVE | RF_OPTIONAL }, /* Hyp */
{ -1, 0 }
};
@@ -392,13 +392,17 @@ arm_tmr_attach(device_t dev)
#ifdef __arm__
sc->physical = true;
#else /* __aarch64__ */
- sc->physical = false;
+ /* If we do not have a virtual timer use the physical. */
+ sc->physical = (sc->res[2] == NULL) ? true : false;
#endif
arm_tmr_sc = sc;
/* Setup secure, non-secure and virtual IRQs handler */
for (i = 0; i < 3; i++) {
+ /* If we do not have the interrupt, skip it. */
+ if (sc->res[i] == NULL)
+ continue;
error = bus_setup_intr(dev, sc->res[i], INTR_TYPE_CLK,
arm_tmr_intr, NULL, sc, &sc->ihl[i]);
if (error) {
OpenPOWER on IntegriCloud