NetBSD Problem Report #59521

From www@netbsd.org  Wed Jul  9 00:10:28 2025
Return-Path: <www@netbsd.org>
Received: from mail.netbsd.org (mail.netbsd.org [199.233.217.200])
	(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
	 key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256
	 client-signature RSA-PSS (2048 bits) client-digest SHA256)
	(Client CN "mail.NetBSD.org", Issuer "mail.NetBSD.org CA" (not verified))
	by mollari.NetBSD.org (Postfix) with ESMTPS id 343041A923C
	for <gnats-bugs@gnats.NetBSD.org>; Wed,  9 Jul 2025 00:10:28 +0000 (UTC)
Message-Id: <20250709001026.D166F1A923E@mollari.NetBSD.org>
Date: Wed,  9 Jul 2025 00:10:26 +0000 (UTC)
From: zhugengyu2023@gmail.com
Reply-To: zhugengyu2023@gmail.com
To: gnats-bugs@NetBSD.org
Subject: Fix arm64 32bit pcc for cpu-freq scaling 
X-Send-Pr-Version: www-1.0

>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&#65292;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;

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.47 2022/09/11 19:34:41 kim Exp $
$NetBSD: gnats_config.sh,v 1.9 2014/08/02 14:16:04 spz Exp $
Copyright © 1994-2025 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.