KVM WS tests, initial drop

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..a8a0dce
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+*.bin
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..fa37c5f
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,24 @@
+
+BINS := do_hvc.bin do_sgi.bin do_sysreg.bin
+
+PERF := perf
+LKVM := lkvm
+LKVM_ARGS :=
+
+%.bin : %.o
+	objcopy -O binary $^ $@
+
+all: $(BINS)
+
+clean:
+	rm -f $(BINS)
+
+.PHONY: tests-gicv2 tests-gicv3
+
+tests-gicv2:
+	@echo GICv2:; for i in $(BINS); do echo -n $$i: ; LANG='C' taskset -c 1 $(PERF) stat -e cycles:hk $(LKVM) run -c1 --kernel $$i --irqchip=gicv2 $(LKVM_ARGS) 2>&1 >/dev/null| grep cycles | awk '{print $$1 / 2^20}'; done
+
+tests-gicv3:
+	@echo GICv3:; for i in $(BINS); do echo -n $$i: ; LANG='C' taskset -c 1 $(PERF) stat -e cycles:hk $(LKVM) run -c1 --kernel $$i --irqchip=gicv3 2>&1 >/dev/null | grep cycles | awk '{print $$1 / 2^20}'; done
+
+tests: $(BINS) tests-gicv2 tests-gicv3
diff --git a/do_hvc.S b/do_hvc.S
new file mode 100644
index 0000000..c7f6f06
--- /dev/null
+++ b/do_hvc.S
@@ -0,0 +1,11 @@
+
+__start:
+	mov	x19, #(1 << 20)
+1:	mov	x0, #0x84000000
+	hvc	#0
+	sub	x19, x19, #1
+	cbnz	x19, 1b
+	mov	x0, #0x84000000
+	add	x0, x0, #9
+	hvc	#0
+	b	.
diff --git a/do_sgi.S b/do_sgi.S
new file mode 100644
index 0000000..0056828
--- /dev/null
+++ b/do_sgi.S
@@ -0,0 +1,83 @@
+
+__start:
+	mov	x19, #(1 << 20)
+
+	mrs	x0, id_aa64pfr0_el1
+	ubfx	x0, x0, #24, #4
+	and	x0, x0, #0xf
+	cbz	x0, do_v2
+
+	mrs	x0, s3_0_c12_c12_5	// ICC_SRE_EL1
+	and	x0, x0, #1		// SRE bit
+	cbnz	x0, do_v3
+
+do_v2:
+	mov	x0, #0x3fff0000		// Dist
+	mov	x1, #0x3ffd0000		// CPU
+	mov	w2, #1
+	str	w2, [x0]		// Enable Group0
+	ldr	w2, =0xa0a0a0a0
+	str	w2, [x0, 0x400]		// A0 priority for SGI0-3
+	mov	w2, #0x0f
+	str	w2, [x0, #0x100]	// Enable SGI0-3
+	mov	w2, #0xf0
+	str	w2, [x1, #4]		// PMR
+	mov	w2, #1
+	str	w2, [x1]		// Enable CPU interface
+
+1:
+	mov	w2, #(2 << 24)		// Interrupt self with SGI0
+	str	w2, [x0, #0xf00]
+
+2:	ldr	w2, [x1, #0x0c]		// GICC_IAR
+	cmp	w2, #0x3ff
+	b.ne	3f
+
+	wfi
+	b	2b
+
+3:	str	w2, [x1, #0x10]		// EOI
+
+	sub	x19, x19, #1
+	cbnz	x19, 1b
+
+die:
+	mov	x0, #0x84000000
+	add	x0, x0, #9
+	hvc	#0
+	b	.
+
+
+do_v3:
+	mov	x0, #0x3fff0000		// Dist
+	mov	x1, #0x3fbf0000		// Redist 0
+	mov	x2, #0x10000
+	add	x1, x1, x2		// SGI page
+	mov	w2, #2
+	str	w2, [x0]		// Enable Group1
+	ldr	w2, =0xa0a0a0a0
+	str	w2, [x1, 0x400]		// A0 priority for SGI0-3
+	mov	w2, #0x0f
+	str	w2, [x1, #0x100]	// Enable SGI0-3
+	mov	w2, #0xf0
+	msr	S3_0_c4_c6_0, x2	// PMR
+	mov	w2, #1
+	msr	S3_0_C12_C12_7, x2	// Enable Group1
+
+1:
+	mov	x2, #1
+	msr	S3_0_c12_c11_5, x2	// Self SGI0
+
+2:	mrs	x2, S3_0_c12_c12_0	// Read IAR1
+	cmp	w2, #0x3ff
+	b.ne	3f
+
+	wfi
+	b	2b
+
+3:	msr	S3_0_c12_c12_1, x2	// EOI
+
+	sub	x19, x19, #1
+	cbnz	x19, 1b
+
+	b	die
diff --git a/do_sysreg.S b/do_sysreg.S
new file mode 100644
index 0000000..e091c90
--- /dev/null
+++ b/do_sysreg.S
@@ -0,0 +1,12 @@
+
+__start:
+	mov	x19, #(1 << 20)
+1:	mrs	x0, PMSELR_EL0
+	sub	x19, x19, #1
+	cbnz	x19, 1b
+
+// Die
+	mov	x0, #0x84000000
+	add	x0, x0, #9
+	hvc	#0
+	b	.