From nobody Tue Feb 10 02:50:02 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=reject dis=none) header.from=citrix.com ARC-Seal: i=1; a=rsa-sha256; t=1616691179; cv=none; d=zohomail.com; s=zohoarc; b=nNGlo7t9Tmtxhm/LCla2YnhlhzCJ53ZQZVBLjR1KxvJHrgYV4WDqzg6MJSHXZvBt9OaxdAsxQjGCxpYEXLa2vhglEyb1EPPYlgB7XVgI24OaSlaBHkvWGliDbJVUWx7UZ1PkTgH5yQQ5VO4Pu8+stq1jvhZGAnllrypasu21ACw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1616691179; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=OA6nC7SY7kOe4uaLffD0cs8EwRSpVeL4NI83RRpLtk8=; b=ZzETjkWX11uAjPjik/oLJLZw7Exzq+KuuO8nKFSuLG6yLxbLl77sqlq3gIu1QmhWuLQ8HS/lpqDzgkhInNA6B3Lc5yV45ue1Ph7lwyT2cYyiKb59YMUtR1K+3IKPBeQyzkTUpc1NSTFDngAzqMm3hsqHgCdA+PqzU4CEimmcZMg= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=reject dis=none) header.from= Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 16166911791981007.68836966226; Thu, 25 Mar 2021 09:52:59 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.101471.194157 (Exim 4.92) (envelope-from ) id 1lPTDw-00089s-5Q; Thu, 25 Mar 2021 16:52:44 +0000 Received: by outflank-mailman (output) from mailman id 101471.194157; Thu, 25 Mar 2021 16:52:44 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1lPTDw-00089j-1P; Thu, 25 Mar 2021 16:52:44 +0000 Received: by outflank-mailman (input) for mailman id 101471; Thu, 25 Mar 2021 16:52:42 +0000 Received: from us1-rack-iad1.inumbo.com ([172.99.69.81]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1lPTDu-00086s-8e for xen-devel@lists.xenproject.org; Thu, 25 Mar 2021 16:52:42 +0000 Received: from esa2.hc3370-68.iphmx.com (unknown [216.71.145.153]) by us1-rack-iad1.inumbo.com (Halon) with ESMTPS id e47308dd-7b06-4e4a-843d-dac0c04026ed; Thu, 25 Mar 2021 16:52:37 +0000 (UTC) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: e47308dd-7b06-4e4a-843d-dac0c04026ed DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=citrix.com; s=securemail; t=1616691155; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=LF+lVlyKXExW6Io/IYUvBnZgXV3D7BVJSGsgMrjUOUs=; b=YHFLKxJKVx870MMzJ9EdWJauFtoOfUtV4BMe5sZa4y/O11Oz3qJ9ssat pLR0q8mOEuz6YcHvX8IVXIRc7l0RxitN2ztaKS4d8MwTgSQM+43/Llcwi yT8+n1jvMmE8liPTBGAWl5lKNGogLRgleDhOtkbFAQ+qzD9AqTBECa20D Y=; Authentication-Results: esa2.hc3370-68.iphmx.com; dkim=none (message not signed) header.i=none IronPort-SDR: bmaiUR7yfJ8R/GUMREX9NrRJ3FNleS1FK8wrw7uP7vcOwjdf38dLKs2dKsdtryATOcOR42Dtxd egzIL1EYDR/v3bbaxkTW2FT7oW5ZdN4H36o6JrRLlRCqCM8g/ldjIgk1nqpMG7fF8AFgKPnyTP tAf9vYOjlD7wdi7nfOAXbsiPxXX4uubMpbAvJXCkqlBd9381O2OA7ibyd/sPSL81D9WQ/6FzuE pKlin/tTdVp06HLPidV8DDD2LZTewcPtrvmc8c6MLxDhoNFJbvH3HHYUn1Buenqx0eBsLGcd7o Zkw= X-SBRS: 5.1 X-MesageID: 40150746 X-Ironport-Server: esa2.hc3370-68.iphmx.com X-Remote-IP: 162.221.158.21 X-Policy: $RELAYED IronPort-HdrOrdr: A9a23:1/9vfaGHtPdr4ZzmpLqFMpHXdLJzesId70hD6mlYVQFVfsuEl8 qngfQc0lvOhCwMXWw78OrsBICrR3TA+ZlppbQAJLvKZniChEKEDqFHqbHjzTrpBjHk+odmv5 tIXqBiBLTLYmRSot395GCDfeoI5Pmi3OSWifzFz3FrJDsaCZ1IywtiEA6UHglXaWB9ZaYRL5 aX6spZqzfIQx1+AviTPXUZQ/PF4+TCiZOOW3U7LiQ64wqDhy7A0s+YLzGk2H4lMg9n8PMZ3k Xu1yf44aiitP/T8G6n60bjq654tfGk5t9KBMmngtUYJDP2mm+TFflccozHhh8ZiqWC70srjc ntrn4bTrhOwkKURE6Zi1/M3BTtyzkn4XOK8y7mvVLT5fbXaRh/Lugpv/M8TjLpr3AOkfs57Y dwm0WejJZTBQOoplWE2/H4EytEu2DxnWAvioco/htieLpbUpB9h6oF8nhYFZ8RdRiKk7wPIa 1VAMbQ6O0+SyL9U1np+m1mwNmbVn8uBBuxQk8bpsyP0zRN9UoJtncl+A== X-IronPort-AV: E=Sophos;i="5.81,278,1610427600"; d="scan'208";a="40150746" From: Andrew Cooper To: Xen-devel CC: Andrew Cooper , Jan Beulich , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= , Wei Liu , Ian Jackson , =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?= , =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Pierret?= Subject: [PATCH 1/2] x86/hpet: Factor hpet_enable_legacy_replacement_mode() out of hpet_setup() Date: Thu, 25 Mar 2021 16:52:23 +0000 Message-ID: <20210325165224.10306-2-andrew.cooper3@citrix.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20210325165224.10306-1-andrew.cooper3@citrix.com> References: <20210325165224.10306-1-andrew.cooper3@citrix.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @citrix.com) ... in preparation to introduce a second caller. No functional change. Signed-off-by: Andrew Cooper Reviewed-by: Jan Beulich --- CC: Jan Beulich CC: Roger Pau Monn=C3=A9 CC: Wei Liu CC: Ian Jackson CC: Marek Marczykowski-G=C3=B3recki CC: Fr=C3=A9d=C3=A9ric Pierret For 4.15. Pre-req for trying to unbreak AMD Ryzen 1800X systems. --- xen/arch/x86/hpet.c | 116 ++++++++++++++++++++++++-----------------= ---- xen/include/asm-x86/hpet.h | 6 +++ 2 files changed, 68 insertions(+), 54 deletions(-) diff --git a/xen/arch/x86/hpet.c b/xen/arch/x86/hpet.c index 1ff005fb4a..c73135bb15 100644 --- a/xen/arch/x86/hpet.c +++ b/xen/arch/x86/hpet.c @@ -754,11 +754,70 @@ int hpet_legacy_irq_tick(void) } =20 static u32 *hpet_boot_cfg; +static u64 __initdata hpet_rate; + +bool __init hpet_enable_legacy_replacement_mode(void) +{ + unsigned int id, cfg, c0_cfg, ticks, count; + + if ( !hpet_rate || + !((id =3D hpet_read32(HPET_ID)) & HPET_ID_LEGSUP) || + (cfg =3D hpet_read32(HPET_CFG) & HPET_CFG_LEGACY) ) + return false; + + /* Stop the main counter. */ + hpet_write32(cfg & ~HPET_CFG_ENABLE, HPET_CFG); + + /* Reconfigure channel 0 to be 32bit periodic. */ + c0_cfg =3D hpet_read32(HPET_Tn_CFG(0)); + c0_cfg |=3D (HPET_TN_ENABLE | HPET_TN_PERIODIC | HPET_TN_SETVAL | + HPET_TN_32BIT); + hpet_write32(c0_cfg, HPET_Tn_CFG(0)); + + /* + * The exact period doesn't have to match a legacy PIT. All we need + * is an interrupt queued up via the IO-APIC to check routing. + * + * Use HZ as the frequency. + */ + ticks =3D ((SECONDS(1) / HZ) * div_sc(hpet_rate, SECONDS(1), 32)) >> 3= 2; + + count =3D hpet_read32(HPET_COUNTER); + + /* + * HPET_TN_SETVAL above is atrociously documented in the spec. + * + * Periodic HPET channels have a main comparator register, and + * separate "accumulator" register. Despite being named accumulator + * in the spec, this is not an accurate description of its behaviour + * or purpose. + * + * Each time an interrupt is generated, the "accumulator" register is + * re-added to the comparator set up the new period. + * + * Normally, writes to the CMP register update both registers. + * However, under these semantics, it is impossible to set up a + * periodic timer correctly without the main HPET counter being at 0. + * + * Instead, HPET_TN_SETVAL is a self-clearing control bit which we can + * use for periodic timers to mean that the second write to CMP + * updates the accumulator only, and not the absolute comparator + * value. + * + * This lets us set a period when the main counter isn't at 0. + */ + hpet_write32(count + ticks, HPET_Tn_CMP(0)); + hpet_write32(ticks, HPET_Tn_CMP(0)); + + /* Restart the main counter, and legacy mode. */ + hpet_write32(cfg | HPET_CFG_ENABLE | HPET_CFG_LEGACY, HPET_CFG); + + return true; +} =20 u64 __init hpet_setup(void) { - static u64 __initdata hpet_rate; - unsigned int hpet_id, hpet_period, hpet_cfg; + unsigned int hpet_id, hpet_period; unsigned int last, rem; =20 if ( hpet_rate ) @@ -805,58 +864,7 @@ u64 __init hpet_setup(void) * Reconfigure the HPET into legacy mode to re-establish the timer * interrupt. */ - if ( hpet_id & HPET_ID_LEGSUP && - !((hpet_cfg =3D hpet_read32(HPET_CFG)) & HPET_CFG_LEGACY) ) - { - unsigned int c0_cfg, ticks, count; - - /* Stop the main counter. */ - hpet_write32(hpet_cfg & ~HPET_CFG_ENABLE, HPET_CFG); - - /* Reconfigure channel 0 to be 32bit periodic. */ - c0_cfg =3D hpet_read32(HPET_Tn_CFG(0)); - c0_cfg |=3D (HPET_TN_ENABLE | HPET_TN_PERIODIC | HPET_TN_SETVAL | - HPET_TN_32BIT); - hpet_write32(c0_cfg, HPET_Tn_CFG(0)); - - /* - * The exact period doesn't have to match a legacy PIT. All we ne= ed - * is an interrupt queued up via the IO-APIC to check routing. - * - * Use HZ as the frequency. - */ - ticks =3D ((SECONDS(1) / HZ) * div_sc(hpet_rate, SECONDS(1), 32)) = >> 32; - - count =3D hpet_read32(HPET_COUNTER); - - /* - * HPET_TN_SETVAL above is atrociously documented in the spec. - * - * Periodic HPET channels have a main comparator register, and - * separate "accumulator" register. Despite being named accumulat= or - * in the spec, this is not an accurate description of its behavio= ur - * or purpose. - * - * Each time an interrupt is generated, the "accumulator" register= is - * re-added to the comparator set up the new period. - * - * Normally, writes to the CMP register update both registers. - * However, under these semantics, it is impossible to set up a - * periodic timer correctly without the main HPET counter being at= 0. - * - * Instead, HPET_TN_SETVAL is a self-clearing control bit which we= can - * use for periodic timers to mean that the second write to CMP - * updates the accumulator only, and not the absolute comparator - * value. - * - * This lets us set a period when the main counter isn't at 0. - */ - hpet_write32(count + ticks, HPET_Tn_CMP(0)); - hpet_write32(ticks, HPET_Tn_CMP(0)); - - /* Restart the main counter, and legacy mode. */ - hpet_write32(hpet_cfg | HPET_CFG_ENABLE | HPET_CFG_LEGACY, HPET_CF= G); - } + hpet_enable_legacy_replacement_mode(); =20 return hpet_rate; } diff --git a/xen/include/asm-x86/hpet.h b/xen/include/asm-x86/hpet.h index fb6bf05065..50176de3d2 100644 --- a/xen/include/asm-x86/hpet.h +++ b/xen/include/asm-x86/hpet.h @@ -73,6 +73,12 @@ void hpet_disable(void); int hpet_legacy_irq_tick(void); =20 /* + * Try to enable HPET Legacy Replacement mode. Returns a boolean indicati= ng + * whether the HPET configuration was changed. + */ +bool hpet_enable_legacy_replacement_mode(void); + +/* * Temporarily use an HPET event counter for timer interrupt handling, * rather than using the LAPIC timer. Used for Cx state entry. */ --=20 2.11.0