From patchwork Wed Sep 16 09:25:53 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Avi Kivity X-Patchwork-Id: 47876 Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id n8G9QY0s009632 for ; Wed, 16 Sep 2009 09:26:34 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1758500AbZIPJ01 (ORCPT ); Wed, 16 Sep 2009 05:26:27 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1758479AbZIPJ01 (ORCPT ); Wed, 16 Sep 2009 05:26:27 -0400 Received: from mx1.redhat.com ([209.132.183.28]:9388 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1758272AbZIPJ0K (ORCPT ); Wed, 16 Sep 2009 05:26:10 -0400 Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id n8G9QE2X010889 for ; Wed, 16 Sep 2009 05:26:14 -0400 Received: from cleopatra.tlv.redhat.com (cleopatra.tlv.redhat.com [10.35.255.11]) by int-mx02.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id n8G9QCMA022862; Wed, 16 Sep 2009 05:26:14 -0400 Received: from localhost.localdomain (cleopatra.tlv.redhat.com [10.35.255.11]) by cleopatra.tlv.redhat.com (Postfix) with ESMTP id 841D3250AD6; Wed, 16 Sep 2009 12:26:11 +0300 (IDT) From: Avi Kivity To: Marcelo Tosatti Cc: kvm@vger.kernel.org Subject: [PATCH QEMU-KVM 18/34] test: add x2apic test Date: Wed, 16 Sep 2009 12:25:53 +0300 Message-Id: <1253093169-1423-19-git-send-email-avi@redhat.com> In-Reply-To: <1253093169-1423-1-git-send-email-avi@redhat.com> References: <1253093169-1423-1-git-send-email-avi@redhat.com> X-Scanned-By: MIMEDefang 2.67 on 10.5.11.12 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Signed-off-by: Avi Kivity --- kvm/user/test/x86/apic.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 46 insertions(+), 0 deletions(-) diff --git a/kvm/user/test/x86/apic.c b/kvm/user/test/x86/apic.c index fdeec4c..504def2 100644 --- a/kvm/user/test/x86/apic.c +++ b/kvm/user/test/x86/apic.c @@ -9,6 +9,7 @@ typedef unsigned char u8; typedef unsigned short u16; typedef unsigned u32; typedef unsigned long ulong; +typedef unsigned long long u64; typedef struct { unsigned short offset0; @@ -147,6 +148,31 @@ static const struct apic_ops xapic_ops = { static const struct apic_ops *apic_ops = &xapic_ops; +static u32 x2apic_read(unsigned reg) +{ + unsigned a, d; + + asm volatile ("rdmsr" : "=a"(a), "=d"(d) : "c"(APIC_BASE_MSR + reg/16)); + return a | (u64)d << 32; +} + +static void x2apic_write(unsigned reg, u32 val) +{ + asm volatile ("wrmsr" : : "a"(val), "d"(0), "c"(APIC_BASE_MSR + reg/16)); +} + +static void x2apic_icr_write(u32 val, u32 dest) +{ + asm volatile ("wrmsr" : : "a"(val), "d"(dest), + "c"(APIC_BASE_MSR + APIC_ICR/16)); +} + +static const struct apic_ops x2apic_ops = { + .reg_read = x2apic_read, + .reg_write = x2apic_write, + .icr_write = x2apic_icr_write, +}; + static u32 apic_read(unsigned reg) { return apic_ops->reg_read(reg); @@ -171,6 +197,25 @@ static void test_lapic_existence(void) report("apic existence", (u16)lvr == 0x14); } +#define MSR_APIC_BASE 0x0000001b + +static void enable_x2apic(void) +{ + unsigned a, b, c, d; + + asm ("cpuid" : "=a"(a), "=b"(b), "=c"(c), "=d"(d) : "0"(1)); + + if (c & (1 << 21)) { + asm ("rdmsr" : "=a"(a), "=d"(d) : "c"(MSR_APIC_BASE)); + a |= 1 << 10; + asm ("wrmsr" : : "a"(a), "d"(d), "c"(MSR_APIC_BASE)); + apic_ops = &x2apic_ops; + printf("x2apic enabled\n"); + } else { + printf("x2apic not detected\n"); + } +} + static u16 read_cs(void) { u16 v; @@ -388,6 +433,7 @@ int main() mask_pic_interrupts(); enable_apic(); + enable_x2apic(); init_idt(); test_self_ipi();