From patchwork Tue Jul 18 17:16:35 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anthony PERARD X-Patchwork-Id: 9849179 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id B889660392 for ; Tue, 18 Jul 2017 17:18:21 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9AB0B285D3 for ; Tue, 18 Jul 2017 17:18:21 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8F72C285D4; Tue, 18 Jul 2017 17:18:21 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 1DC7E285CD for ; Tue, 18 Jul 2017 17:18:21 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1dXW72-0004gJ-Kf; Tue, 18 Jul 2017 17:16:44 +0000 Received: from mail6.bemta6.messagelabs.com ([193.109.254.103]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1dXW70-0004g3-UK for xen-devel@lists.xenproject.org; Tue, 18 Jul 2017 17:16:43 +0000 Received: from [193.109.254.147] by server-10.bemta-6.messagelabs.com id 89/9D-03582-A724E695; Tue, 18 Jul 2017 17:16:42 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFprGIsWRWlGSWpSXmKPExsXitHSDvW6lU16 kQecWeYvvWyYzOTB6HP5whSWAMYo1My8pvyKBNaNn81Xmghn6FV/X9zI1ML5T7WLk5JAQ8JdY tegTG4jNJmAgsWL6VcYuRg4OEQEVidt7DUDCzAJREu0t9xhBbGEBN4mV1/rAylkEVCXetZ8Fs 3kF7CRmHV3LCjFSXmJi7zSwek4Be4lJh2+A1QgB1ex5dosRwlaTuLFwGQtEr6DEyZlPWCB2SU gcfPGCeQIj7ywkqVlIUgsYmVYxahSnFpWlFukaG+slFWWmZ5TkJmbm6BoamOnlphYXJ6an5iQ mFesl5+duYgSGDgMQ7GDcuT7wEKMkB5OSKO9W5bxIIb6k/JTKjMTijPii0pzU4kOMMhwcShK8 VxyAcoJFqempFWmZOcAghklLcPAoifCqOgKleYsLEnOLM9MhUqcYjTleTfj/jYmj6fvH70xCL Hn5ealS4rwnQSYJgJRmlObBDYJF1yVGWSlhXkag04R4ClKLcjNLUOVfMYpzMCoJ8yaCLOTJzC uB2/cK6BQmoFOEfXNATilJREhJNTBm3S98Xvb0otjHtyu3Tmaw97vbuf8TV8Xpt0/OZT15WiB 28+be+RJ/zmY1C3RUSbhvb7qyL05+5vol32+837M7vM9ak3WH8xfXu3Xtk5dXqge+qmVO/+S1 R/+g551TCdlSJzY9WKRctkei48QShmSPNUZqV9k3ii1LXDMvr+HmHeaHO2Ue7BWwVWIpzkg01 GIuKk4EAIzdupCpAgAA X-Env-Sender: prvs=365e4ded5=anthony.perard@citrix.com X-Msg-Ref: server-8.tower-27.messagelabs.com!1500398199!97475954!1 X-Originating-IP: [66.165.176.63] X-SpamReason: No, hits=0.0 required=7.0 tests=sa_preprocessor: VHJ1c3RlZCBJUDogNjYuMTY1LjE3Ni42MyA9PiAzMDYwNDg=\n, received_headers: No Received headers X-StarScan-Received: X-StarScan-Version: 9.4.25; banners=-,-,- X-VirusChecked: Checked Received: (qmail 47863 invoked from network); 18 Jul 2017 17:16:41 -0000 Received: from smtp02.citrix.com (HELO SMTP02.CITRIX.COM) (66.165.176.63) by server-8.tower-27.messagelabs.com with RC4-SHA encrypted SMTP; 18 Jul 2017 17:16:41 -0000 X-IronPort-AV: E=Sophos;i="5.40,378,1496102400"; d="scan'208";a="440336284" From: Anthony PERARD To: Date: Tue, 18 Jul 2017 18:16:35 +0100 Message-ID: <20170718171637.26038-2-anthony.perard@citrix.com> X-Mailer: git-send-email 2.13.3 In-Reply-To: <20170718171637.26038-1-anthony.perard@citrix.com> References: <20170718171637.26038-1-anthony.perard@citrix.com> MIME-Version: 1.0 Cc: Anthony PERARD , Andrew Cooper Subject: [Xen-devel] [XTF PATCH v2 1/3] vlapic-timer: Introduce vLAPIC Timer tests X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xen.org Sender: "Xen-devel" X-Virus-Scanned: ClamAV using ClamSMTP Start by testing one-shot and periodic timer modes. The behavior of TMICT and TMCCT while switching between periodic and one-shot timer modes check in this test is mostly base on observation of baremetal. Intel SDM gives little details about it. Signed-off-by: Anthony PERARD --- arch/x86/include/arch/apic.h | 8 +++ tests/vlapic-timer/Makefile | 9 +++ tests/vlapic-timer/main.c | 151 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 168 insertions(+) create mode 100644 tests/vlapic-timer/Makefile create mode 100644 tests/vlapic-timer/main.c diff --git a/arch/x86/include/arch/apic.h b/arch/x86/include/arch/apic.h index 1389f70..4cb262d 100644 --- a/arch/x86/include/arch/apic.h +++ b/arch/x86/include/arch/apic.h @@ -24,6 +24,14 @@ #define APIC_DEST_SELF 0x40000 #define APIC_ICR2 0x310 +#define APIC_LVTT 0x320 +#define APIC_TIMER_MODE_MASK (0x3<<17) +#define APIC_TIMER_MODE_ONESHOT (0x0<<17) +#define APIC_TIMER_MODE_PERIODIC (0x1<<17) + +#define APIC_TMICT 0x380 +#define APIC_TMCCT 0x390 + #define APIC_DEFAULT_BASE 0xfee00000ul diff --git a/tests/vlapic-timer/Makefile b/tests/vlapic-timer/Makefile new file mode 100644 index 0000000..f2a61cb --- /dev/null +++ b/tests/vlapic-timer/Makefile @@ -0,0 +1,9 @@ +include $(ROOT)/build/common.mk + +NAME := vlapic-timer +CATEGORY := functional +TEST-ENVS := hvm64 + +obj-perenv += main.o + +include $(ROOT)/build/gen.mk diff --git a/tests/vlapic-timer/main.c b/tests/vlapic-timer/main.c new file mode 100644 index 0000000..47836a8 --- /dev/null +++ b/tests/vlapic-timer/main.c @@ -0,0 +1,151 @@ +/** + * @file tests/vlapic-timer/main.c + * @ref test-vlapic-timer - LAPIC Timer Emulation + * + * @page test-vlapic-timer LAPIC Timer Emulation + * + * Tests the behavior of the vlapic timer emulation by Xen. + * + * These tests are mostly base on observation made on baremetal, Intel SDM does + * not describe everything. + * + * It is testing switch between different mode, one-shot and periodic, as well + * a the TSC-Deadline mode. + * + * @see tests/vlapic-timer/main.c + */ +#include +#include + +const char test_title[] = "Test vlapic-timer"; + +static inline void change_mode(unsigned long new_mode) +{ + uint32_t lvtt; + + lvtt = apic_read(APIC_LVTT); + apic_write(APIC_LVTT, (lvtt & ~APIC_TIMER_MODE_MASK) | new_mode); +} + +void wait_tmcct_count_down(uint32_t initial_count, bool stop_when_half) +{ + uint32_t tmcct = apic_read(APIC_TMCCT); + + if ( tmcct ) + { + while ( tmcct > (initial_count / 2) ) + tmcct = apic_read(APIC_TMCCT); + + if ( stop_when_half ) + return; + + /* Wait until the counter reach 0 or wrap-around */ + while ( tmcct <= (initial_count / 2) && tmcct > 0 ) + tmcct = apic_read(APIC_TMCCT); + } +} + +static inline void wait_until_tmcct_is_zero(uint32_t initial_count) +{ + wait_tmcct_count_down(initial_count, false); +} +static inline void wait_until_tmcct_is_half_down(uint32_t initial_count) +{ + wait_tmcct_count_down(initial_count, true); +} + +void testing_oneshot_and_periodic_mode(void) +{ + uint32_t tmict = 0x9999999; + + /* Start in one-shot mode */ + change_mode(APIC_TIMER_MODE_ONESHOT); + + apic_write(APIC_TMICT, tmict); + + /* On mode change one-shot -> periodic, TMICT is not reset on baremetal */ + change_mode(APIC_TIMER_MODE_PERIODIC); + if ( apic_read(APIC_TMICT) != tmict ) + xtf_failure("Fail: TMICT value reset\n"); + + /* + * Testing one-shot + */ + printk("Testing one-shot mode\n"); + change_mode(APIC_TIMER_MODE_ONESHOT); + + /* Testing TMCCT after setting TMICT */ + apic_write(APIC_TMICT, tmict); + if ( !apic_read(APIC_TMCCT) ) + xtf_failure("Fail: TMCCT should have a non-zero value\n"); + + wait_until_tmcct_is_zero(tmict); + if ( apic_read(APIC_TMCCT) ) + xtf_failure("Fail: TMCCT should have reached 0\n"); + + /* + * Testing periodic timer mode + * + * Write TMICT before changing mode one-shot -> periodic, + * check that TMCCT keeps counting down after this mode change + */ + apic_write(APIC_TMICT, tmict); + wait_until_tmcct_is_half_down(tmict); + + printk("Testing periodic mode\n"); + change_mode(APIC_TIMER_MODE_PERIODIC); + + if ( !apic_read(APIC_TMCCT) ) + xtf_failure("Fail: TMCCT should have a non-zero value\n"); + + if ( apic_read(APIC_TMCCT) > (tmict / 2) ) + xtf_failure("Fail: TMCCT should not be reset to TMICT value\n"); + + /* Check that the TMCCT is reset to TMICT */ + wait_until_tmcct_is_zero(tmict); + if ( apic_read(APIC_TMCCT) < (tmict / 2) ) + xtf_failure("Fail: TMCCT should be reset to TMICT periodically\n"); + + wait_until_tmcct_is_half_down(tmict); + + /* + * Keep the same TMICT and change timer mode periodic -> one-shot + * Check that TMCCT keeps counting down and is not reset. + */ + printk("Testing one-shot after periodic (with same tmict)\n"); + change_mode(APIC_TIMER_MODE_ONESHOT); + + if ( !apic_read(APIC_TMCCT) ) + xtf_failure("Fail: TMCCT should have a non-zero value\n"); + if ( apic_read(APIC_TMCCT) > (tmict / 2) ) + xtf_failure("Fail: TMCCT should not be reset to init\n"); + + wait_until_tmcct_is_zero(tmict); + if ( apic_read(APIC_TMCCT) ) + xtf_failure("Fail: TMCCT should have reach zero\n"); + + /* Now TMCCT == 0 and TMICT != 0 */ + change_mode(APIC_TIMER_MODE_PERIODIC); + if ( apic_read(APIC_TMCCT) ) + xtf_failure("Fail: TMCCT should stay at zero\n"); +} + +void test_main(void) +{ + if ( apic_init(APIC_MODE_XAPIC) ) + return xtf_skip("No APIC support"); + + testing_oneshot_and_periodic_mode(); + + xtf_success(NULL); +} + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */