Index: sys/arm/arm/generic_timer.c =================================================================== --- sys/arm/arm/generic_timer.c +++ sys/arm/arm/generic_timer.c @@ -86,6 +86,13 @@ #define GT_CNTKCTL_PL0VCTEN (1 << 1) /* PL0 CNTVCT and CNTFRQ access */ #define GT_CNTKCTL_PL0PCTEN (1 << 0) /* PL0 CNTPCT and CNTFRQ access */ +#define GT_PHYS_SECURE 0 +#define GT_PHYS_NONSECURE 1 +#define GT_VIRT 2 +#define GT_HYP 3 + +extern char hypmode_enabled[]; + struct arm_tmr_softc { struct resource *res[4]; void *ihl[4]; @@ -97,10 +104,10 @@ 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 | RF_OPTIONAL }, /* Virt */ - { SYS_RES_IRQ, 3, RF_ACTIVE | RF_OPTIONAL }, /* Hyp */ + { SYS_RES_IRQ, GT_PHYS_SECURE, RF_ACTIVE }, /* Secure */ + { SYS_RES_IRQ, GT_PHYS_NONSECURE, RF_ACTIVE }, /* Non-secure */ + { SYS_RES_IRQ, GT_VIRT, RF_ACTIVE | RF_OPTIONAL }, /* Virt */ + { SYS_RES_IRQ, GT_HYP, RF_ACTIVE | RF_OPTIONAL }, /* Hyp */ { -1, 0 } }; @@ -108,9 +115,10 @@ struct timecounter *tc); static void arm_tmr_do_delay(int usec, void *); +static uint64_t get_cntxct(bool physical); static timecounter_get_t arm_tmr_get_timecount; -static struct timecounter arm_tmr_timecount = { +struct timecounter arm_tmr_timecount = { .tc_name = "ARM MPCore Timecounter", .tc_get_timecount = arm_tmr_get_timecount, .tc_poll_pps = NULL, @@ -118,6 +126,7 @@ .tc_frequency = 0, .tc_quality = 1000, .tc_fill_vdso_timehands = arm_tmr_fill_vdso_timehands, + .tc_priv = get_cntxct, }; #ifdef __arm__ @@ -138,7 +147,7 @@ return (get_el0(cntfrq)); } -static long +static uint64_t get_cntxct(bool physical) { uint64_t val; @@ -307,6 +316,7 @@ static void arm_tmr_acpi_identify(driver_t *driver, device_t parent) { + struct arm_tmr_softc *sc; ACPI_TABLE_GTDT *gtdt; vm_paddr_t physaddr; device_t dev; @@ -328,12 +338,16 @@ 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); + sc = device_get_softc(dev); + if (sc->physical) { + BUS_SET_RESOURCE(parent, dev, SYS_RES_IRQ, GT_PHYS_SECURE, + gtdt->SecureEl1Interrupt, 1); + BUS_SET_RESOURCE(parent, dev, SYS_RES_IRQ, GT_PHYS_NONSECURE, + gtdt->NonSecureEl1Interrupt, 1); + } else { + BUS_SET_RESOURCE(parent, dev, SYS_RES_IRQ, GT_VIRT, + gtdt->VirtualTimerInterrupt, 1); + } out: acpi_unmap_table(gtdt); @@ -390,22 +404,25 @@ return (ENXIO); } -#ifdef __arm__ - sc->physical = true; -#else /* __aarch64__ */ - /* 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]); + sc->physical = (sc->res[GT_VIRT] == NULL) || (hypmode_enabled[0] == 0); + + if (sc->physical) { + for (i = GT_PHYS_SECURE; i <= GT_PHYS_NONSECURE; 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) { + device_printf(dev, "Unable to alloc int resource.\n"); + return (ENXIO); + } + } + } else { + error = bus_setup_intr(dev, sc->res[GT_VIRT], INTR_TYPE_CLK, + arm_tmr_intr, NULL, sc, &sc->ihl[GT_VIRT]); if (error) { device_printf(dev, "Unable to alloc int resource.\n"); return (ENXIO);