The branch main has been updated by markj:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=964bf2f902c5e05381018532e5d9d456979d4bf7

commit 964bf2f902c5e05381018532e5d9d456979d4bf7
Author:     John F. Carr <j...@mit.edu>
AuthorDate: 2022-03-19 22:51:43 +0000
Commit:     Mark Johnston <ma...@freebsd.org>
CommitDate: 2022-03-28 15:23:45 +0000

    hpet: Allow a MMIO window smaller than 1K
    
    Some new AMD systems provide a HPET MMIO region smaller than the 1KB
    specified, and a correspondingly small number of timers.  Handle this in
    the HPET driver rather than requiring a 1KB window.  This allows the
    HPET driver to attach on such systems.
    
    PR:             262638
    Reviewed by:    markj
    MFC after:      1 month
---
 sys/dev/acpica/acpi_hpet.c | 20 +++++++++++++++++---
 sys/dev/acpica/acpi_hpet.h |  1 +
 2 files changed, 18 insertions(+), 3 deletions(-)

diff --git a/sys/dev/acpica/acpi_hpet.c b/sys/dev/acpica/acpi_hpet.c
index 0f0a16f336f2..e35e3808a980 100644
--- a/sys/dev/acpica/acpi_hpet.c
+++ b/sys/dev/acpica/acpi_hpet.c
@@ -477,6 +477,7 @@ hpet_attach(device_t dev)
        struct make_dev_args mda;
        int i, j, num_msi, num_timers, num_percpu_et, num_percpu_t, cur_cpu;
        int pcpu_master, error;
+       rman_res_t hpet_region_size;
        static int maxhpetet = 0;
        uint32_t val, val2, cvectors, dvectors;
        uint16_t vendor, rev;
@@ -493,10 +494,11 @@ hpet_attach(device_t dev)
        if (sc->mem_res == NULL)
                return (ENOMEM);
 
-       /* Validate that we can access the whole region. */
-       if (rman_get_size(sc->mem_res) < HPET_MEM_WIDTH) {
+       hpet_region_size = rman_get_size(sc->mem_res);
+       /* Validate that the region is big enough for the control registers. */
+       if (hpet_region_size < HPET_MEM_MIN_WIDTH) {
                device_printf(dev, "memory region width %jd too small\n",
-                   rman_get_size(sc->mem_res));
+                   hpet_region_size);
                bus_free_resource(dev, SYS_RES_MEMORY, sc->mem_res);
                return (ENXIO);
        }
@@ -526,6 +528,18 @@ hpet_attach(device_t dev)
         */
        if (vendor == HPET_VENDID_AMD && rev < 0x10 && num_timers > 0)
                num_timers--;
+       /*
+        * Now validate that the region is big enough to address all counters.
+        */
+       if (hpet_region_size < HPET_TIMER_CAP_CNF(num_timers)) {
+               device_printf(dev,
+                   "memory region width %jd too small for %d timers\n",
+                   hpet_region_size, num_timers);
+               hpet_disable(sc);
+               bus_free_resource(dev, SYS_RES_MEMORY, sc->mem_res);
+               return (ENXIO);
+       }
+
        sc->num_timers = num_timers;
        if (bootverbose) {
                device_printf(dev,
diff --git a/sys/dev/acpica/acpi_hpet.h b/sys/dev/acpica/acpi_hpet.h
index c3941c39a89a..1d6a6022230e 100644
--- a/sys/dev/acpica/acpi_hpet.h
+++ b/sys/dev/acpica/acpi_hpet.h
@@ -30,6 +30,7 @@
 #define        __ACPI_HPET_H__
 
 #define HPET_MEM_WIDTH         0x400   /* Expected memory region size */
+#define HPET_MEM_MIN_WIDTH     0x100   /* Minimum memory region size */
 
 /* General registers */
 #define HPET_CAPABILITIES      0x0     /* General capabilities and ID */

Reply via email to