NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
kern/59521: Fix arm64 32bit pcc for cpu-freq scaling
>Number: 59521
>Category: kern
>Synopsis: Fix arm64 32bit pcc for cpu-freq scaling
>Confidential: no
>Severity: critical
>Priority: high
>Responsible: kern-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Wed Jul 09 00:15:00 +0000 2025
>Originator: zhuge
>Release: 10.1
>Organization:
cherry-embedded
>Environment:
NetBSD arm64 10.1_STABLE NetBSD 10.1_STABLE (GENERIC64) #14: Tue Jul 8 06:26:17 CST 2025
>Description:
This PR is to fix cpu frequency scaling in some arm64 platform
1): the current acpi_pcc.c do not handle for reg->BitWidth = 32 case,therefore some arm64 platform failed with Data aligment abort when init cppc
2): the current acpi_pcc.c mis-use mask when write new cpu freq into pcc channel
>How-To-Repeat:
boot 32-bit pcc channel ARM64 PC with CPPC enabled
>Fix:
diff --git a/sys/dev/acpi/acpi_pcc.c b/sys/dev/acpi/acpi_pcc.c
index 0d9c0c618..b3afcb11a 100644
--- a/sys/dev/acpi/acpi_pcc.c
+++ b/sys/dev/acpi/acpi_pcc.c
@@ -265,7 +265,6 @@ pcc_send_command(struct pcc_subspace *ss, ACPI_GENERIC_ADDRESS *reg,
{
volatile ACPI_PCCT_SHARED_MEMORY *shmem = ss->ss_data;
uint8_t *data = __UNVOLATILE(shmem + 1);
- UINT64 tmp, mask;
KASSERT(ss->ss_type == ACPI_PCCT_TYPE_GENERIC_SUBSPACE ||
ss->ss_type == ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE ||
@@ -274,12 +273,27 @@ pcc_send_command(struct pcc_subspace *ss, ACPI_GENERIC_ADDRESS *reg,
shmem->Signature = PCC_SIGNATURE(ss->ss_id);
shmem->Command = command & 0xff;
if ((flags & PCC_WRITE) != 0) {
- mask = __BITS(reg->BitOffset + reg->BitWidth - 1,
- reg->BitOffset);
- ACPI_MOVE_64_TO_64(&tmp, data + reg->Address);
- tmp &= mask;
- tmp |= __SHIFTIN(val, mask);
- ACPI_MOVE_64_TO_64(data + reg->Address, &tmp);
+ if (reg->BitWidth == 32U) {
+ UINT32 tmp32, mask32, val32;
+ val32 = (UINT32)val;
+ mask32 = __BITS(reg->BitOffset + reg->BitWidth - 1,
+ reg->BitOffset);
+ ACPI_MOVE_32_TO_32(&tmp32, data + reg->Address);
+ tmp32 &= ~mask32;
+ tmp32 |= __SHIFTIN(val32, mask32);
+ aprint_normal("%s PCC32 write %d %ld mask 0x%x\n", __func__, tmp32, val, mask32);
+ ACPI_MOVE_32_TO_32(data + reg->Address, &tmp32);
+ } else if (reg->BitWidth == 64U) {
+ UINT64 tmp, mask;
+ mask = __BITS(reg->BitOffset + reg->BitWidth - 1,
+ reg->BitOffset);
+ ACPI_MOVE_64_TO_64(&tmp, data + reg->Address);
+ tmp &= ~mask;
+ tmp |= __SHIFTIN(val, mask);
+ ACPI_MOVE_64_TO_64(data + reg->Address, &tmp);
+ } else {
+ panic("PCC %d bit not support\n", reg->BitWidth);
+ }
}
PCC_MEMORY_BARRIER();
shmem->Status &= ~(PCC_STATUS_COMMAND_COMPLETE |
@@ -300,7 +314,6 @@ pcc_receive_response(struct pcc_subspace *ss, ACPI_GENERIC_ADDRESS *reg,
{
volatile ACPI_PCCT_SHARED_MEMORY *shmem = ss->ss_data;
const uint8_t *data = __UNVOLATILE(shmem + 1);
- UINT64 tmp, mask;
KASSERT(ss->ss_type == ACPI_PCCT_TYPE_GENERIC_SUBSPACE ||
ss->ss_type == ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE ||
@@ -313,10 +326,23 @@ pcc_receive_response(struct pcc_subspace *ss, ACPI_GENERIC_ADDRESS *reg,
}
if ((flags & PCC_READ) != 0) {
- mask = __BITS(reg->BitOffset + reg->BitWidth - 1,
- reg->BitOffset);
- ACPI_MOVE_64_TO_64(&tmp, data + reg->Address);
- *val = __SHIFTOUT(tmp, mask);
+ if (reg->BitWidth == 32U) {
+ UINT32 tmp32, mask32, val32;
+ mask32 = __BITS(reg->BitOffset + reg->BitWidth - 1,
+ reg->BitOffset);
+ ACPI_MOVE_32_TO_32(&tmp32, data + reg->Address);
+ val32 = __SHIFTOUT(tmp32, mask32);
+ *val = (UINT64)val32;
+ aprint_normal("%s PCC32 read %d %ld mask 0x%x\n", __func__, tmp32, *val, mask32);
+ } else if (reg->BitWidth == 64U) {
+ UINT64 tmp, mask;
+ mask = __BITS(reg->BitOffset + reg->BitWidth - 1,
+ reg->BitOffset);
+ ACPI_MOVE_64_TO_64(&tmp, data + reg->Address);
+ *val = __SHIFTOUT(tmp, mask);
+ } else {
+ panic("PCC %d bit not support\n", reg->BitWidth);
+ }
}
return AE_OK;
Home |
Main Index |
Thread Index |
Old Index