[Bug 236513] HP Thin clients T620/T730 ACPI: Only CPU core 0 detects C2 state

bugzilla-noreply at freebsd.org bugzilla-noreply at freebsd.org
Thu Mar 28 08:25:57 UTC 2019


https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=236513

--- Comment #34 from Andriy Gapon <avg at FreeBSD.org> ---
(In reply to stockhausen from comment #32)
1. Ah, you are right, I forgot that modern processors intercept C-state I/O
accesses at a core level.
Just to clarify, I assume that on your T620 cpucontrol -m 0xC0010073
/dev/cpuctl0 gives 0x414?

3.b(2) The root bridge has a range that covers 0x414, so that's okay.

A. I do not think so.  I think that the code currently expects BIOS to set up
everything correctly. We could try to think about how FreeBSD ACPI code could
work around not having Cx I/O ports in the system resources...

By the way, I see why acpi cpu devices cannot share a resource if it's not an
acpi system resource.  If a resource is a system resource then it is allocated
from the nexus (very early) and the acpi bus manages it on its own.  That means
that acpi_set_resource() -> resource_list_reserve(flags=0) ->
resource_list_alloc() -> BUS_ALLOC_RESOURCE() -> nexus_alloc_resource() ->
rman_reserve_resource(flags=0) would always fail.  But that's okay, because
acpi_alloc_resource() has a fallback to acpi_alloc_sysres().  And if the
resource is consistently allocated with RF_SHARED, then all allocations of it
succeed.
If a resource is _not_ a system resource, then the resource is not allocated by
the acpi bus in the nexus as the acpi bus is unaware of it.  Then, when the
first cpu calls acpi_PkgGas() -> acpi_bus_alloc_gas() -> bus_set_resource() ->
acpi_set_resource() -> resource_list_reserve(flags=0) ->
resource_list_alloc(flags=0) -> BUS_ALLOC_RESOURCE(flags=0) ->
nexus_alloc_resource(flags=0) -> rman_reserve_resource(flags=0), the resource
is allocated in the nexus and it is allocated without RF_SHARED flag.  Because
the allocation is successful, the resource is added to the device's resource
list.  After bus_set_resource(), acpi_bus_alloc_gas() calls
bus_alloc_resource_any() -> acpi_alloc_resource(flags=RF_ACTIVE|RF_SHARED) ->
resource_list_alloc().
Because the resource already exists in the device's resource list,
resource_list_alloc() would simply activate it and return. So, for the first
cpu acpi_bus_alloc_gas() is successful.
For any subsequent cpu, this call chain acpi_PkgGas() -> acpi_bus_alloc_gas()
-> bus_set_resource() -> acpi_set_resource() -> resource_list_reserve(flags=0)
-> resource_list_alloc(flags=0) -> BUS_ALLOC_RESOURCE(flags=0) ->
nexus_alloc_resource(flags=0) -> rman_reserve_resource(flags=0) would fail
because the resource is already allocated in nexus and it is not shared.  Thus,
the resource would not be created in the device's resource list.  Thus, the
subsequent call to bus_alloc_resource_any() ->
acpi_alloc_resource(flags=RF_ACTIVE|RF_SHARED) -> resource_list_alloc() would
not find that resource and it would have to call BUS_ALLOC_RESOURCE() ->
nexus_alloc_resource() -> rman_reserve_resource() and that would fail again for
the same reason.  And, in this case, acpi_alloc_resource()'s fallback to
acpi_alloc_sysres() would also fail, because the resource is not a system
resource.  In the end, acpi_PkgGas() -> acpi_bus_alloc_gas() fails just as you
have seen.

B. I would add 0x414 to CRS of Device S900.  E.g. using 0x040B as an example, I
would add this just after it:
IO (Decode16,
    0x0414,             // Range Minimum
    0x0414,             // Range Maximum
    0x00,               // Alignment
    0x04,               // Length
    )

-- 
You are receiving this mail because:
You are the assignee for the bug.


More information about the freebsd-bugs mailing list