All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/2] Testing vlapic timer
@ 2017-03-20 14:38 Anthony PERARD
  2017-03-20 14:38 ` [PATCH 1/2] Import apicdef.h from xen.git Anthony PERARD
  2017-03-20 14:38 ` [PATCH 2/2] Add vlapic timer checks Anthony PERARD
  0 siblings, 2 replies; 6+ messages in thread
From: Anthony PERARD @ 2017-03-20 14:38 UTC (permalink / raw)
  To: xen-devel; +Cc: Anthony PERARD, Andrew Cooper

Hi,

This list of check should work on baremetal, but Xen emulation vlapic does
not behave like baremetal, so this XTF tests would fail at first, until a fix
for Xen that I'm working on is pushed.

I don't check TSC deadline yet, but I will give a look as well. For now, it's
only one-shot and periodic timer.

Thanks,

Anthony PERARD (2):
  Import apicdef.h from xen.git
  Add vlapic timer checks

 arch/x86/include/arch/apicdef.h | 392 ++++++++++++++++++++++++++++++++++++++++
 tests/vlapic-timer/Makefile     |   9 +
 tests/vlapic-timer/main.c       | 131 ++++++++++++++
 3 files changed, 532 insertions(+)
 create mode 100644 arch/x86/include/arch/apicdef.h
 create mode 100644 tests/vlapic-timer/Makefile
 create mode 100644 tests/vlapic-timer/main.c

-- 
Anthony PERARD


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 1/2] Import apicdef.h from xen.git
  2017-03-20 14:38 [PATCH 0/2] Testing vlapic timer Anthony PERARD
@ 2017-03-20 14:38 ` Anthony PERARD
  2017-03-20 14:51   ` Roger Pau Monné
  2017-03-29 12:43   ` Andrew Cooper
  2017-03-20 14:38 ` [PATCH 2/2] Add vlapic timer checks Anthony PERARD
  1 sibling, 2 replies; 6+ messages in thread
From: Anthony PERARD @ 2017-03-20 14:38 UTC (permalink / raw)
  To: xen-devel; +Cc: Anthony PERARD, Andrew Cooper

Have only changed the value of APIC_BASE.

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
---
 arch/x86/include/arch/apicdef.h | 392 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 392 insertions(+)
 create mode 100644 arch/x86/include/arch/apicdef.h

diff --git a/arch/x86/include/arch/apicdef.h b/arch/x86/include/arch/apicdef.h
new file mode 100644
index 0000000..242c45e
--- /dev/null
+++ b/arch/x86/include/arch/apicdef.h
@@ -0,0 +1,392 @@
+#ifndef __ASM_APICDEF_H
+#define __ASM_APICDEF_H
+
+/*
+ * Constants for various Intel APICs. (local APIC, IOAPIC, etc.)
+ *
+ * Alan Cox <Alan.Cox@linux.org>, 1995.
+ * Ingo Molnar <mingo@redhat.com>, 1999, 2000
+ */
+
+#define		APIC_DEFAULT_PHYS_BASE	0xfee00000
+ 
+#define		APIC_ID		0x20
+#define			APIC_ID_MASK		(0xFFu<<24)
+#define			GET_xAPIC_ID(x)		(((x)>>24)&0xFFu)
+#define			SET_xAPIC_ID(x)		(((x)<<24))
+#define		APIC_LVR	0x30
+#define			APIC_LVR_MASK		0xFF00FF
+#define			APIC_LVR_DIRECTED_EOI	(1 << 24)
+#define			GET_APIC_VERSION(x)	((x)&0xFF)
+#define			GET_APIC_MAXLVT(x)	(((x)>>16)&0xFF)
+#define			APIC_INTEGRATED(x)	((x)&0xF0)
+#define			APIC_XAPIC(x)		((x) >= 0x14)
+#define		APIC_TASKPRI	0x80
+#define			APIC_TPRI_MASK		0xFF
+#define		APIC_ARBPRI	0x90
+#define			APIC_ARBPRI_MASK	0xFF
+#define		APIC_PROCPRI	0xA0
+#define		APIC_EOI	0xB0
+#define			APIC_EIO_ACK		0x0		/* Write this to the EOI register */
+#define		APIC_RRR	0xC0
+#define		APIC_LDR	0xD0
+#define			APIC_LDR_MASK		(0xFFu<<24)
+#define			GET_xAPIC_LOGICAL_ID(x)	(((x)>>24)&0xFF)
+#define			SET_xAPIC_LOGICAL_ID(x)	(((x)<<24))
+#define			APIC_ALL_CPUS		0xFF
+#define		APIC_DFR	0xE0
+#define			APIC_DFR_CLUSTER		0x0FFFFFFFul
+#define			APIC_DFR_FLAT			0xFFFFFFFFul
+#define		APIC_SPIV	0xF0
+#define			APIC_SPIV_FOCUS_DISABLED	(1<<9)
+#define			APIC_SPIV_APIC_ENABLED		(1<<8)
+#define			APIC_SPIV_DIRECTED_EOI		(1<<12)
+#define		APIC_ISR	0x100
+#define         APIC_ISR_NR     0x8     /* Number of 32 bit ISR registers. */
+#define		APIC_TMR	0x180
+#define 	APIC_IRR	0x200
+#define 	APIC_ESR	0x280
+#define			APIC_ESR_SEND_CS	0x00001
+#define			APIC_ESR_RECV_CS	0x00002
+#define			APIC_ESR_SEND_ACC	0x00004
+#define			APIC_ESR_RECV_ACC	0x00008
+#define			APIC_ESR_SENDILL	0x00020
+#define			APIC_ESR_RECVILL	0x00040
+#define			APIC_ESR_ILLREGA	0x00080
+#define		APIC_ICR	0x300
+#define			APIC_DEST_NOSHORT	0x00000
+#define			APIC_DEST_SELF		0x40000
+#define			APIC_DEST_ALLINC	0x80000
+#define			APIC_DEST_ALLBUT	0xC0000
+#define			APIC_SHORT_MASK		0xC0000
+#define			APIC_ICR_RR_MASK	0x30000
+#define			APIC_ICR_RR_INVALID	0x00000
+#define			APIC_ICR_RR_INPROG	0x10000
+#define			APIC_ICR_RR_VALID	0x20000
+#define			APIC_INT_LEVELTRIG	0x08000
+#define			APIC_INT_ASSERT		0x04000
+#define			APIC_ICR_BUSY		0x01000
+#define			APIC_DEST_MASK		0x00800
+#define			APIC_DEST_LOGICAL	0x00800
+#define			APIC_DEST_PHYSICAL	0x00000
+#define			APIC_DM_FIXED		0x00000
+#define			APIC_DM_LOWEST		0x00100
+#define			APIC_DM_SMI		0x00200
+#define			APIC_DM_REMRD		0x00300
+#define			APIC_DM_NMI		0x00400
+#define			APIC_DM_INIT		0x00500
+#define			APIC_DM_STARTUP		0x00600
+#define			APIC_DM_EXTINT		0x00700
+#define			APIC_VECTOR_MASK	0x000FF
+#define		APIC_ICR2	0x310
+#define			GET_xAPIC_DEST_FIELD(x)	(((x)>>24)&0xFF)
+#define			SET_xAPIC_DEST_FIELD(x)	((x)<<24)
+#define		APIC_LVTT	0x320
+#define		APIC_LVTTHMR	0x330
+#define		APIC_LVTPC	0x340
+#define		APIC_LVT0	0x350
+#define		APIC_CMCI	0x2F0
+
+#define			APIC_TIMER_MODE_MASK		(0x3<<17)
+#define			APIC_TIMER_MODE_ONESHOT		(0x0<<17)
+#define			APIC_TIMER_MODE_PERIODIC	(0x1<<17)
+#define			APIC_TIMER_MODE_TSC_DEADLINE	(0x2<<17)
+#define			APIC_LVT_MASKED			(1<<16)
+#define			APIC_LVT_LEVEL_TRIGGER		(1<<15)
+#define			APIC_LVT_REMOTE_IRR		(1<<14)
+#define			APIC_INPUT_POLARITY		(1<<13)
+#define			APIC_SEND_PENDING		(1<<12)
+#define			APIC_MODE_MASK			0x700
+#define			GET_APIC_DELIVERY_MODE(x)	(((x)>>8)&0x7)
+#define			SET_APIC_DELIVERY_MODE(x,y)	(((x)&~0x700)|((y)<<8))
+#define				APIC_MODE_FIXED		0x0
+#define				APIC_MODE_NMI		0x4
+#define				APIC_MODE_EXTINT	0x7
+#define 	APIC_LVT1	0x360
+#define		APIC_LVTERR	0x370
+#define		APIC_TMICT	0x380
+#define		APIC_TMCCT	0x390
+#define		APIC_TDCR	0x3E0
+#define			APIC_TDR_DIV_TMBASE	(1<<2)
+#define			APIC_TDR_DIV_1		0xB
+#define			APIC_TDR_DIV_2		0x0
+#define			APIC_TDR_DIV_4		0x1
+#define			APIC_TDR_DIV_8		0x2
+#define			APIC_TDR_DIV_16		0x3
+#define			APIC_TDR_DIV_32		0x8
+#define			APIC_TDR_DIV_64		0x9
+#define			APIC_TDR_DIV_128	0xA
+
+/* Only available in x2APIC mode */
+#define		APIC_SELF_IPI	0x3F0
+
+#define APIC_BASE 0xfee00000
+
+/* It's only used in x2APIC mode of an x2APIC unit. */
+#define APIC_MSR_BASE 0x800
+
+#define MAX_IO_APICS 128
+
+/*
+ * the local APIC register structure, memory mapped. Not terribly well
+ * tested, but we might eventually use this one in the future - the
+ * problem why we cannot use it right now is the P5 APIC, it has an
+ * errata which cannot take 8-bit reads and writes, only 32-bit ones ...
+ */
+#define u32 unsigned int
+
+#define lapic ((volatile struct local_apic *)APIC_BASE)
+
+#ifndef __ASSEMBLY__
+struct __packed local_apic {
+
+/*000*/	struct { u32 __reserved[4]; } __reserved_01;
+
+/*010*/	struct { u32 __reserved[4]; } __reserved_02;
+
+/*020*/	struct { /* APIC ID Register */
+		u32   __reserved_1	: 24,
+			phys_apic_id	:  4,
+			__reserved_2	:  4;
+		u32 __reserved[3];
+	} id;
+
+/*030*/	const
+	struct { /* APIC Version Register */
+		u32   version		:  8,
+			__reserved_1	:  8,
+			max_lvt		:  8,
+			__reserved_2	:  8;
+		u32 __reserved[3];
+	} version;
+
+/*040*/	struct { u32 __reserved[4]; } __reserved_03;
+
+/*050*/	struct { u32 __reserved[4]; } __reserved_04;
+
+/*060*/	struct { u32 __reserved[4]; } __reserved_05;
+
+/*070*/	struct { u32 __reserved[4]; } __reserved_06;
+
+/*080*/	struct { /* Task Priority Register */
+		u32   priority	:  8,
+			__reserved_1	: 24;
+		u32 __reserved_2[3];
+	} tpr;
+
+/*090*/	const
+	struct { /* Arbitration Priority Register */
+		u32   priority	:  8,
+			__reserved_1	: 24;
+		u32 __reserved_2[3];
+	} apr;
+
+/*0A0*/	const
+	struct { /* Processor Priority Register */
+		u32   priority	:  8,
+			__reserved_1	: 24;
+		u32 __reserved_2[3];
+	} ppr;
+
+/*0B0*/	struct { /* End Of Interrupt Register */
+		u32   eoi;
+		u32 __reserved[3];
+	} eoi;
+
+/*0C0*/	struct { u32 __reserved[4]; } __reserved_07;
+
+/*0D0*/	struct { /* Logical Destination Register */
+		u32   __reserved_1	: 24,
+			logical_dest	:  8;
+		u32 __reserved_2[3];
+	} ldr;
+
+/*0E0*/	struct { /* Destination Format Register */
+		u32   __reserved_1	: 28,
+			model		:  4;
+		u32 __reserved_2[3];
+	} dfr;
+
+/*0F0*/	struct { /* Spurious Interrupt Vector Register */
+		u32	spurious_vector	:  8,
+			apic_enabled	:  1,
+			focus_cpu	:  1,
+			__reserved_2	: 22;
+		u32 __reserved_3[3];
+	} svr;
+
+/*100*/	struct { /* In Service Register */
+/*170*/		u32 bitfield;
+		u32 __reserved[3];
+	} isr [8];
+
+/*180*/	struct { /* Trigger Mode Register */
+/*1F0*/		u32 bitfield;
+		u32 __reserved[3];
+	} tmr [8];
+
+/*200*/	struct { /* Interrupt Request Register */
+/*270*/		u32 bitfield;
+		u32 __reserved[3];
+	} irr [8];
+
+/*280*/	union { /* Error Status Register */
+		struct {
+			u32   send_cs_error			:  1,
+				receive_cs_error		:  1,
+				send_accept_error		:  1,
+				receive_accept_error		:  1,
+				__reserved_1			:  1,
+				send_illegal_vector		:  1,
+				receive_illegal_vector		:  1,
+				illegal_register_address	:  1,
+				__reserved_2			: 24;
+			u32 __reserved_3[3];
+		} error_bits;
+		struct {
+			u32 errors;
+			u32 __reserved_3[3];
+		} all_errors;
+	} esr;
+
+/*290*/	struct { u32 __reserved[4]; } __reserved_08;
+
+/*2A0*/	struct { u32 __reserved[4]; } __reserved_09;
+
+/*2B0*/	struct { u32 __reserved[4]; } __reserved_10;
+
+/*2C0*/	struct { u32 __reserved[4]; } __reserved_11;
+
+/*2D0*/	struct { u32 __reserved[4]; } __reserved_12;
+
+/*2E0*/	struct { u32 __reserved[4]; } __reserved_13;
+
+/*2F0*/	struct { u32 __reserved[4]; } __reserved_14;
+
+/*300*/	struct { /* Interrupt Command Register 1 */
+		u32   vector			:  8,
+			delivery_mode		:  3,
+			destination_mode	:  1,
+			delivery_status		:  1,
+			__reserved_1		:  1,
+			level			:  1,
+			trigger			:  1,
+			__reserved_2		:  2,
+			shorthand		:  2,
+			__reserved_3		:  12;
+		u32 __reserved_4[3];
+	} icr1;
+
+/*310*/	struct { /* Interrupt Command Register 2 */
+		union {
+			u32   __reserved_1	: 24,
+				phys_dest	:  4,
+				__reserved_2	:  4;
+			u32   __reserved_3	: 24,
+				logical_dest	:  8;
+		} dest;
+		u32 __reserved_4[3];
+	} icr2;
+
+/*320*/	struct { /* LVT - Timer */
+		u32   vector		:  8,
+			__reserved_1	:  4,
+			delivery_status	:  1,
+			__reserved_2	:  3,
+			mask		:  1,
+			timer_mode	:  1,
+			__reserved_3	: 14;
+		u32 __reserved_4[3];
+	} lvt_timer;
+
+/*330*/	struct { /* LVT - Thermal Sensor */
+		u32  vector		:  8,
+			delivery_mode	:  3,
+			__reserved_1	:  1,
+			delivery_status	:  1,
+			__reserved_2	:  3,
+			mask		:  1,
+			__reserved_3	: 15;
+		u32 __reserved_4[3];
+	} lvt_thermal;
+
+/*340*/	struct { /* LVT - Performance Counter */
+		u32   vector		:  8,
+			delivery_mode	:  3,
+			__reserved_1	:  1,
+			delivery_status	:  1,
+			__reserved_2	:  3,
+			mask		:  1,
+			__reserved_3	: 15;
+		u32 __reserved_4[3];
+	} lvt_pc;
+
+/*350*/	struct { /* LVT - LINT0 */
+		u32   vector		:  8,
+			delivery_mode	:  3,
+			__reserved_1	:  1,
+			delivery_status	:  1,
+			polarity	:  1,
+			remote_irr	:  1,
+			trigger		:  1,
+			mask		:  1,
+			__reserved_2	: 15;
+		u32 __reserved_3[3];
+	} lvt_lint0;
+
+/*360*/	struct { /* LVT - LINT1 */
+		u32   vector		:  8,
+			delivery_mode	:  3,
+			__reserved_1	:  1,
+			delivery_status	:  1,
+			polarity	:  1,
+			remote_irr	:  1,
+			trigger		:  1,
+			mask		:  1,
+			__reserved_2	: 15;
+		u32 __reserved_3[3];
+	} lvt_lint1;
+
+/*370*/	struct { /* LVT - Error */
+		u32   vector		:  8,
+			__reserved_1	:  4,
+			delivery_status	:  1,
+			__reserved_2	:  3,
+			mask		:  1,
+			__reserved_3	: 15;
+		u32 __reserved_4[3];
+	} lvt_error;
+
+/*380*/	struct { /* Timer Initial Count Register */
+		u32   initial_count;
+		u32 __reserved_2[3];
+	} timer_icr;
+
+/*390*/	const
+	struct { /* Timer Current Count Register */
+		u32   curr_count;
+		u32 __reserved_2[3];
+	} timer_ccr;
+
+/*3A0*/	struct { u32 __reserved[4]; } __reserved_16;
+
+/*3B0*/	struct { u32 __reserved[4]; } __reserved_17;
+
+/*3C0*/	struct { u32 __reserved[4]; } __reserved_18;
+
+/*3D0*/	struct { u32 __reserved[4]; } __reserved_19;
+
+/*3E0*/	struct { /* Timer Divide Configuration Register */
+		u32   divisor		:  4,
+			__reserved_1	: 28;
+		u32 __reserved_2[3];
+	} timer_dcr;
+
+/*3F0*/	struct { u32 __reserved[4]; } __reserved_20;
+
+};
+#endif /* !__ASSEMBLY__ */
+
+#undef u32
+
+#endif
-- 
Anthony PERARD


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 2/2] Add vlapic timer checks
  2017-03-20 14:38 [PATCH 0/2] Testing vlapic timer Anthony PERARD
  2017-03-20 14:38 ` [PATCH 1/2] Import apicdef.h from xen.git Anthony PERARD
@ 2017-03-20 14:38 ` Anthony PERARD
  2017-03-29 13:18   ` Andrew Cooper
  1 sibling, 1 reply; 6+ messages in thread
From: Anthony PERARD @ 2017-03-20 14:38 UTC (permalink / raw)
  To: xen-devel; +Cc: Anthony PERARD, Andrew Cooper

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
---
 tests/vlapic-timer/Makefile |   9 +++
 tests/vlapic-timer/main.c   | 131 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 140 insertions(+)
 create mode 100644 tests/vlapic-timer/Makefile
 create mode 100644 tests/vlapic-timer/main.c

diff --git a/tests/vlapic-timer/Makefile b/tests/vlapic-timer/Makefile
new file mode 100644
index 0000000..01fa4ea
--- /dev/null
+++ b/tests/vlapic-timer/Makefile
@@ -0,0 +1,9 @@
+include $(ROOT)/build/common.mk
+
+NAME      := vlapic-timer
+CATEGORY  := functional
+TEST-ENVS := $(HVM_ENVIRONMENTS)
+
+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..b081661
--- /dev/null
+++ b/tests/vlapic-timer/main.c
@@ -0,0 +1,131 @@
+/**
+ * @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.
+ *
+ * This tests should work on baremetal.
+ *
+ * It is testing switch between different mode, one-shot and periodic.
+ *
+ * @see tests/vlapic-timer/main.c
+ */
+#include <stdbool.h>
+#include <xtf.h>
+#include <arch/apicdef.h>
+
+const char test_title[] = "Test vlapic-timer";
+
+static inline void apic_write(unsigned long reg, uint32_t v)
+{
+    *((volatile uint32_t *)(APIC_BASE + reg)) = v;
+}
+
+static inline uint32_t apic_read(unsigned long reg)
+{
+    return *((volatile uint32_t *)(APIC_BASE + reg));
+}
+
+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_until_tmcct_is_zero(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);
+    }
+}
+
+void test_main(void)
+{
+    uint32_t tmict = 0x999999;
+
+    apic_write(APIC_TMICT, tmict);
+    /*
+     * Assuming that the initial mode is one-shot, change it to periodic. TMICT
+     * should not be reset.
+     */
+    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);
+    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, false);
+    if ( apic_read(APIC_TMCCT) )
+        xtf_failure("Fail: TMCCT should have reached 0\n");
+
+    /*
+     * Write TMICT before changing mode from one-shot to periodic TMCCT should
+     * be reset to TMICT periodicly
+     */
+    apic_write(APIC_TMICT, tmict);
+    wait_until_tmcct_is_zero(tmict, true);
+    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");
+    /*
+     * After the change of mode, the counter should not be reset and continue
+     * counting down from where it was
+     */
+    if ( apic_read(APIC_TMCCT) > (tmict / 2) )
+        xtf_failure("Fail: TMCCT should not be reset to TMICT value\n");
+    wait_until_tmcct_is_zero(tmict, false);
+    if ( apic_read(APIC_TMCCT) < (tmict / 2) )
+        xtf_failure("Fail: TMCCT should be reset to the initial-count\n");
+
+    wait_until_tmcct_is_zero(tmict, true);
+    /*
+     * Keep the same TMICT and change timer mode to one-shot
+     * TMCCT should be > 0 and count-down to 0
+     */
+    printk("Testing one-shot after periodic (no tmict reset)\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, false);
+    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");
+
+    xtf_success(NULL);
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
-- 
Anthony PERARD


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH 1/2] Import apicdef.h from xen.git
  2017-03-20 14:38 ` [PATCH 1/2] Import apicdef.h from xen.git Anthony PERARD
@ 2017-03-20 14:51   ` Roger Pau Monné
  2017-03-29 12:43   ` Andrew Cooper
  1 sibling, 0 replies; 6+ messages in thread
From: Roger Pau Monné @ 2017-03-20 14:51 UTC (permalink / raw)
  To: Anthony PERARD; +Cc: xen-devel, Andrew Cooper

On Mon, Mar 20, 2017 at 02:38:45PM +0000, Anthony PERARD wrote:
> Have only changed the value of APIC_BASE.
> 
> Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
> ---
>  arch/x86/include/arch/apicdef.h | 392 ++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 392 insertions(+)
>  create mode 100644 arch/x86/include/arch/apicdef.h
> 
> diff --git a/arch/x86/include/arch/apicdef.h b/arch/x86/include/arch/apicdef.h
> new file mode 100644
> index 0000000..242c45e
> --- /dev/null
> +++ b/arch/x86/include/arch/apicdef.h
> @@ -0,0 +1,392 @@
> +#ifndef __ASM_APICDEF_H
> +#define __ASM_APICDEF_H
> +
> +/*
> + * Constants for various Intel APICs. (local APIC, IOAPIC, etc.)
> + *
> + * Alan Cox <Alan.Cox@linux.org>, 1995.
> + * Ingo Molnar <mingo@redhat.com>, 1999, 2000
> + */

Careful, this AFAICT is under GPLv2. I would argue that headers with defines
and structs cannot really be under any license, but anyway... I suggest you
pick the FreeBSD equivalent which is BSD-licensed [0].

Roger.

[0] https://svnweb.freebsd.org/base/head/sys/x86/include/apicreg.h?view=markup

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 1/2] Import apicdef.h from xen.git
  2017-03-20 14:38 ` [PATCH 1/2] Import apicdef.h from xen.git Anthony PERARD
  2017-03-20 14:51   ` Roger Pau Monné
@ 2017-03-29 12:43   ` Andrew Cooper
  1 sibling, 0 replies; 6+ messages in thread
From: Andrew Cooper @ 2017-03-29 12:43 UTC (permalink / raw)
  To: Anthony PERARD, xen-devel

On 20/03/17 14:38, Anthony PERARD wrote:
> Have only changed the value of APIC_BASE.
>
> Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
> ---
>  arch/x86/include/arch/apicdef.h | 392 ++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 392 insertions(+)
>  create mode 100644 arch/x86/include/arch/apicdef.h
>
> diff --git a/arch/x86/include/arch/apicdef.h b/arch/x86/include/arch/apicdef.h
> new file mode 100644
> index 0000000..242c45e
> --- /dev/null
> +++ b/arch/x86/include/arch/apicdef.h

Other than what Roger said concerning licensing issue, I'd just
introduce the constants that you currently need.  Most of this content
will never be needed in XTF.

~Andrew

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 2/2] Add vlapic timer checks
  2017-03-20 14:38 ` [PATCH 2/2] Add vlapic timer checks Anthony PERARD
@ 2017-03-29 13:18   ` Andrew Cooper
  0 siblings, 0 replies; 6+ messages in thread
From: Andrew Cooper @ 2017-03-29 13:18 UTC (permalink / raw)
  To: Anthony PERARD, xen-devel


[-- Attachment #1.1: Type: text/plain, Size: 6139 bytes --]

On 20/03/17 14:38, Anthony PERARD wrote:
> Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
> ---
>  tests/vlapic-timer/Makefile |   9 +++
>  tests/vlapic-timer/main.c   | 131 ++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 140 insertions(+)
>  create mode 100644 tests/vlapic-timer/Makefile
>  create mode 100644 tests/vlapic-timer/main.c
>
> diff --git a/tests/vlapic-timer/Makefile b/tests/vlapic-timer/Makefile
> new file mode 100644
> index 0000000..01fa4ea
> --- /dev/null
> +++ b/tests/vlapic-timer/Makefile
> @@ -0,0 +1,9 @@
> +include $(ROOT)/build/common.mk
> +
> +NAME      := vlapic-timer
> +CATEGORY  := functional
> +TEST-ENVS := $(HVM_ENVIRONMENTS)

Do you really need all HVM environments?  APIC emulation doesn't have
any interaction with paging or operating modes.

Speaking of this test, I should really see about upstreaming some of my
ad-hoc lapic tests, which have existed almost as long as XTF has.  I am
also going to have to see about getting the test revision logic working,
because I'd prefer to have one "apic functionaltiy test" than a large
number of individual tests each testing a different part of behaviour.

> +
> +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..b081661
> --- /dev/null
> +++ b/tests/vlapic-timer/main.c
> @@ -0,0 +1,131 @@
> +/**
> + * @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.
> + *
> + * This tests should work on baremetal.
> + *
> + * It is testing switch between different mode, one-shot and periodic.
> + *
> + * @see tests/vlapic-timer/main.c
> + */
> +#include <stdbool.h>

No need for this include.  It will come in via xtf.h

> +#include <xtf.h>
> +#include <arch/apicdef.h>
> +
> +const char test_title[] = "Test vlapic-timer";
> +
> +static inline void apic_write(unsigned long reg, uint32_t v)
> +{
> +    *((volatile uint32_t *)(APIC_BASE + reg)) = v;
> +}
> +
> +static inline uint32_t apic_read(unsigned long reg)
> +{
> +    return *((volatile uint32_t *)(APIC_BASE + reg));
> +}

These should be in an piece of common apic library, along with an
initialisation function to probe and enable the lapic.  (after all,
restricted PVH environments one have one at all).

> +
> +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_until_tmcct_is_zero(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);
> +    }
> +}
> +
> +void test_main(void)
> +{
> +    uint32_t tmict = 0x999999;
> +
> +    apic_write(APIC_TMICT, tmict);
> +    /*
> +     * Assuming that the initial mode is one-shot, change it to periodic. TMICT
> +     * should not be reset.

It is not generally a good idea make assumptions like this.  The only
way it would be safe, is to state that one-shot is the reset value of
the APIC state.

> +     */
> +    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);
> +    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, false);
> +    if ( apic_read(APIC_TMCCT) )
> +        xtf_failure("Fail: TMCCT should have reached 0\n");

Please spread this logic out with newlines, to make it easier to read.

~Andrew

> +
> +    /*
> +     * Write TMICT before changing mode from one-shot to periodic TMCCT should
> +     * be reset to TMICT periodicly
> +     */
> +    apic_write(APIC_TMICT, tmict);
> +    wait_until_tmcct_is_zero(tmict, true);
> +    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");
> +    /*
> +     * After the change of mode, the counter should not be reset and continue
> +     * counting down from where it was
> +     */
> +    if ( apic_read(APIC_TMCCT) > (tmict / 2) )
> +        xtf_failure("Fail: TMCCT should not be reset to TMICT value\n");
> +    wait_until_tmcct_is_zero(tmict, false);
> +    if ( apic_read(APIC_TMCCT) < (tmict / 2) )
> +        xtf_failure("Fail: TMCCT should be reset to the initial-count\n");
> +
> +    wait_until_tmcct_is_zero(tmict, true);
> +    /*
> +     * Keep the same TMICT and change timer mode to one-shot
> +     * TMCCT should be > 0 and count-down to 0
> +     */
> +    printk("Testing one-shot after periodic (no tmict reset)\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, false);
> +    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");
> +
> +    xtf_success(NULL);
> +}
> +
> +/*
> + * Local variables:
> + * mode: C
> + * c-file-style: "BSD"
> + * c-basic-offset: 4
> + * tab-width: 4
> + * indent-tabs-mode: nil
> + * End:
> + */


[-- Attachment #1.2: Type: text/html, Size: 7252 bytes --]

[-- Attachment #2: Type: text/plain, Size: 127 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2017-03-29 13:18 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-03-20 14:38 [PATCH 0/2] Testing vlapic timer Anthony PERARD
2017-03-20 14:38 ` [PATCH 1/2] Import apicdef.h from xen.git Anthony PERARD
2017-03-20 14:51   ` Roger Pau Monné
2017-03-29 12:43   ` Andrew Cooper
2017-03-20 14:38 ` [PATCH 2/2] Add vlapic timer checks Anthony PERARD
2017-03-29 13:18   ` Andrew Cooper

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.