qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: "Alex Bennée" <alex.bennee@linaro.org>
To: qemu-devel@nongnu.org
Cc: "Peter Maydell" <peter.maydell@linaro.org>,
	qemu-arm@nongnu.org, "Alex Bennée" <alex.bennee@linaro.org>
Subject: [Qemu-devel] [PATCH v1 07/23] tests/tcg/aarch64: add system boot.S
Date: Thu,  9 May 2019 17:58:55 +0100	[thread overview]
Message-ID: <20190509165912.10512-8-alex.bennee@linaro.org> (raw)
In-Reply-To: <20190509165912.10512-1-alex.bennee@linaro.org>

This provides the bootstrap and low level helper functions for an
aarch64 kernel. We use semihosting to handle test output and exiting
the emulation. semihosting's parameter passing is a little funky so we
end up using the stack and pointing to that as the parameter block.

Signed-off-by: Alex Bennée <alex.bennee@linaro.org>

---
v2
  - fix tabs
  - 2 stage table lookup with ro and nx sections
  - set stack to back
  - moar comments
---
 tests/tcg/aarch64/Makefile.softmmu-target |  32 +++
 tests/tcg/aarch64/system/boot.S           | 239 ++++++++++++++++++++++
 tests/tcg/aarch64/system/kernel.ld        |  24 +++
 3 files changed, 295 insertions(+)
 create mode 100644 tests/tcg/aarch64/Makefile.softmmu-target
 create mode 100644 tests/tcg/aarch64/system/boot.S
 create mode 100644 tests/tcg/aarch64/system/kernel.ld

diff --git a/tests/tcg/aarch64/Makefile.softmmu-target b/tests/tcg/aarch64/Makefile.softmmu-target
new file mode 100644
index 00000000000..cdb836f7e1e
--- /dev/null
+++ b/tests/tcg/aarch64/Makefile.softmmu-target
@@ -0,0 +1,32 @@
+#
+# Aarch64 system tests
+#
+
+AARCH64_SYSTEM_SRC=$(SRC_PATH)/tests/tcg/aarch64/system
+VPATH+=$(AARCH64_SYSTEM_SRC)
+
+# These objects provide the basic boot code and helper functions for all tests
+CRT_OBJS=boot.o
+
+AARCH64_TEST_SRCS=$(wildcard $(AARCH64_SYSTEM_SRC)/*.c)
+AARCH64_TESTS = $(patsubst $(AARCH64_SYSTEM_SRC)/%.c, %, $(AARCH64_TEST_SRCS))
+
+CRT_PATH=$(AARCH64_SYSTEM_SRC)
+LINK_SCRIPT=$(AARCH64_SYSTEM_SRC)/kernel.ld
+LDFLAGS=-Wl,-T$(LINK_SCRIPT)
+TESTS+=$(AARCH64_TESTS) $(MULTIARCH_TESTS)
+CFLAGS+=-nostdlib -ggdb -O0 $(MINILIB_INC)
+LDFLAGS+=-static -nostdlib $(CRT_OBJS) $(MINILIB_OBJS) -lgcc
+
+# building head blobs
+.PRECIOUS: $(CRT_OBJS)
+
+%.o: $(CRT_PATH)/%.S
+	$(CC) $(CFLAGS) -x assembler-with-cpp -c $< -o $@
+
+# Build and link the tests
+%: %.c $(LINK_SCRIPT) $(CRT_OBJS) $(MINILIB_OBJS)
+	$(CC) $(CFLAGS) $< -o $@ $(LDFLAGS)
+
+# Running
+QEMU_OPTS+=-M virt -cpu max -display none -semihosting-config enable=on,target=native,chardev=output -kernel
diff --git a/tests/tcg/aarch64/system/boot.S b/tests/tcg/aarch64/system/boot.S
new file mode 100644
index 00000000000..b14e94f332d
--- /dev/null
+++ b/tests/tcg/aarch64/system/boot.S
@@ -0,0 +1,239 @@
+/*
+ * Minimal AArch64 system boot code.
+ *
+ * Copyright Linaro Ltd 2019
+ *
+ * Loosely based on the newlib/libgloss setup stubs. Using semihosting
+ * for serial output and exit functions.
+ */
+
+/*
+ * Semihosting interface on ARM AArch64
+ * See "Semihosting for AArch32 and AArch64 Relase 2.0" by ARM
+ * w0 - semihosting call number
+ * x1 - semihosting parameter
+ */
+#define semihosting_call hlt 0xf000
+#define SYS_WRITEC	0x03	/* character to debug channel */
+#define SYS_WRITE0	0x04	/* string to debug channel */
+#define SYS_EXIT	0x18
+
+	.align	12
+
+	.macro	ventry	label
+	.align	7
+	b	\label
+	.endm
+
+vector_table:
+	/* Current EL with SP0.	 */
+	ventry	curr_sp0_sync		/* Synchronous	*/
+	ventry	curr_sp0_irq		/* Irq/vIRQ  */
+	ventry	curr_sp0_fiq		/* Fiq/vFIQ  */
+	ventry	curr_sp0_serror		/* SError/VSError  */
+
+	/* Current EL with SPx.	 */
+	ventry	curr_spx_sync		/* Synchronous	*/
+	ventry	curr_spx_irq		/* IRQ/vIRQ  */
+	ventry	curr_spx_fiq		/* FIQ/vFIQ  */
+	ventry	curr_spx_serror		/* SError/VSError  */
+
+	/* Lower EL using AArch64.  */
+	ventry	lower_a64_sync		/* Synchronous	*/
+	ventry	lower_a64_irq		/* IRQ/vIRQ  */
+	ventry	lower_a64_fiq		/* FIQ/vFIQ  */
+	ventry	lower_a64_serror	/* SError/VSError  */
+
+	/* Lower EL using AArch32.  */
+	ventry	lower_a32_sync		/* Synchronous	*/
+	ventry	lower_a32_irq		/* IRQ/vIRQ  */
+	ventry	lower_a32_fiq		/* FIQ/vFIQ  */
+	ventry	lower_a32_serror	/* SError/VSError  */
+
+	.text
+	.align 4
+
+	/* Common vector handling for now */
+curr_sp0_sync:
+curr_sp0_irq:
+curr_sp0_fiq:
+curr_sp0_serror:
+curr_spx_sync:
+curr_spx_irq:
+curr_spx_fiq:
+curr_spx_serror:
+lower_a64_sync:
+lower_a64_irq:
+lower_a64_fiq:
+lower_a64_serror:
+lower_a32_sync:
+lower_a32_irq:
+lower_a32_fiq:
+lower_a32_serror:
+	mov	x0, SYS_WRITE0
+	adr	x1, .error
+	semihosting_call
+	mov	x0, SYS_EXIT
+	mov	x1, 1
+	semihosting_call
+	/* never returns */
+
+	.section .rodata
+.error:
+	.string "Terminated by exception.\n"
+
+	.text
+	.align 4
+	.global __start
+__start:
+	/* Installs a table of exception vectors to catch and handle all
+	   exceptions by terminating the process with a diagnostic.  */
+	adr	x0, vector_table
+	msr	vbar_el1, x0
+
+	/* Page table setup (identity mapping). */
+	adrp	x0, ttb
+	add	x0, x0, :lo12:ttb
+	msr	ttbr0_el1, x0
+
+	/*
+	 * Setup a flat address mapping page-tables. Stage one simply
+	 * maps RAM to the first Gb. The stage2 tables have two 2mb
+	 * translation block entries covering a series of adjacent
+	 * 4k pages.
+	*/
+
+	/* Stage 1 entry: indexed by IA[38:30] */
+	adr	x1, .				/* phys address */
+	bic	x1, x1, #(1 << 30) - 1		/* 1GB alignment*/
+	add	x2, x0, x1, lsr #(30 - 3)	/* offset in l1 page table */
+
+	/* point to stage 2 table [47:12] */
+	adrp	x0, ttb_stage2
+	orr 	x1, x0, #3 			/* ptr to stage 2 */
+	str	x1, [x2]
+
+	/* Stage 2 entries: indexed by IA[29:21] */
+	ldr	x5, =(((1 << 9) - 1) << 21)
+
+	/* First block: .text/RO/execute enabled */
+	adr	x1, .				/* phys address */
+	bic	x1, x1, #(1 << 21) - 1		/* 2mb block alignment	*/
+	and	x4, x1, x5			/* IA[29:21] */
+	add	x2, x0, x4, lsr #(21 - 3)	/* offset in l2 page table */
+	ldr	x3, =0x401			/* attr(AF, block) */
+	orr	x1, x1, x3
+	str	x1, [x2]			/* 1st 2mb (.text & rodata) */
+
+	/* Second block: .data/RW/no execute */
+	adrp	x1, .data
+	add	x1, x1, :lo12:.data
+	bic	x1, x1, #(1 << 21) - 1		/* 2mb block alignment */
+	and	x4, x1, x5			/* IA[29:21] */
+	add	x2, x0, x4, lsr #(21 - 3)	/* offset in l2 page table */
+	ldr	x3, =(3 << 53) | 0x401		/* attr(AF, NX, block) */
+	orr	x1, x1, x3
+	str	x1, [x2]			/* 2nd 2mb (.data & .bss)*/
+
+	/* Setup/enable the MMU.  */
+
+	/*
+	 * TCR_EL1 - Translation Control Registers
+	 *
+	 * IPS[34:32] = 40-bit PA, 1TB
+	 * TG0[14:15] = b00 => 4kb granuale
+	 * ORGN0[11:10] = Outer: Normal, WB Read-Alloc No Write-Alloc Cacheable
+	 * IRGN0[9:8] = Inner: Normal, WB Read-Alloc No Write-Alloc Cacheable
+	 * T0SZ[5:0]  = 2^(64 - 25)
+	 *
+	 * The size of T0SZ controls what the initial lookup level. It
+	 * would be nice to start at level 2 but unfortunatly for a
+	 * flat-mapping on the virt machine we need to handle IA's
+	 * with at least 1gb range to see RAM. So we start with a
+	 * level 1 lookup.
+	 */
+	ldr	x0, = (2 << 32) | 25 | (3 << 10) | (3 << 8)
+	msr	tcr_el1, x0
+
+	mov	x0, #0xee			/* Inner/outer cacheable WB */
+	msr	mair_el1, x0
+	isb
+
+	/*
+	 * SCTLR_EL1 - System Control Register
+	 *
+	 * WXN[19] = 0 = no effect, Write does not imply XN (execute never)
+	 * I[12] = Instruction cachability control
+	 * SA[3] = SP alignment check
+	 * C[2] = Data cachability control
+	 * M[0] = 1, enable stage 1 address translation for EL0/1
+	 */
+	mrs	x0, sctlr_el1
+	ldr	x1, =0x100d			/* bits I(12) SA(3) C(2) M(0) */
+	bic	x0, x0, #(1 << 1)		/* clear bit A(1) */
+	bic	x0, x0, #(1 << 19)		/* clear WXN */
+	orr	x0, x0, x1			/* set bits */
+
+	dsb	sy
+	msr	sctlr_el1, x0
+	isb
+
+	/*
+	 * Enable FP registers. The standard C pre-amble will be
+	 * saving these and A-profile compilers will use AdvSIMD
+	 * registers unless we tell it not to.
+	*/
+	mrs	x0, cpacr_el1
+	orr	x0, x0, #(3 << 20)
+	msr	cpacr_el1, x0
+
+	/* Setup some stack space and enter the test code.
+	 * Assume everthing except the return value is garbage when we
+	 * return, we won't need it.
+	 */
+	adrp	x0, stack_end
+	add	x0, x0, :lo12:stack_end
+	mov	sp, x0
+	bl	main
+
+	/* pass return value to sys exit */
+	mov    x1, x0
+	ldr    x0, =0x20026 /* ADP_Stopped_ApplicationExit */
+	stp    x0, x1, [sp, #-16]!
+	mov    x1, sp
+	mov    x0, SYS_EXIT
+	semihosting_call
+	/* never returns */
+
+	/*
+	 * Helper Functions
+	*/
+
+	/* Output a single character to serial port */
+	.global __sys_outc
+__sys_outc:
+	stp x0, x1, [sp, #-16]!
+	/* pass address of c on stack */
+	mov x1, sp
+	mov x0, SYS_WRITEC
+	semihosting_call
+	ldp x0, x1, [sp], #16
+	ret
+
+	.data
+	.align	12
+
+	/* Translation table
+	 * @4k granuale: 9 bit lookup, 512 entries
+	*/
+ttb:
+	.space	4096, 0
+
+	.align	12
+ttb_stage2:
+	.space	4096, 0
+
+	.align	12
+stack:
+	.space 65536, 0
+stack_end:
diff --git a/tests/tcg/aarch64/system/kernel.ld b/tests/tcg/aarch64/system/kernel.ld
new file mode 100644
index 00000000000..7b3a76dcbf3
--- /dev/null
+++ b/tests/tcg/aarch64/system/kernel.ld
@@ -0,0 +1,24 @@
+ENTRY(__start)
+
+SECTIONS
+{
+    /* virt machine, RAM starts at 1gb */
+    . = (1 << 30);
+    .text : {
+        *(.text)
+    }
+    .rodata : {
+        *(.rodata)
+    }
+    /* align r/w section to next 2mb */
+    . = ALIGN(1 << 21);
+    .data : {
+        *(.data)
+    }
+    .bss : {
+        *(.bss)
+    }
+    /DISCARD/ : {
+        *(.ARM.attributes)
+    }
+}
-- 
2.20.1



  parent reply	other threads:[~2019-05-09 17:11 UTC|newest]

Thread overview: 45+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-05-09 16:58 [Qemu-devel] [PATCH v1 00/23] current testing/next queue (docker/system & io tests) Alex Bennée
2019-05-09 16:58 ` [Qemu-devel] [PATCH v1 01/23] tests/docker: add ubuntu 18.04 Alex Bennée
2019-05-09 17:41   ` Philippe Mathieu-Daudé
2019-05-09 16:58 ` [Qemu-devel] [PATCH v1 02/23] tests/docker: Test more components on the Fedora default image Alex Bennée
2019-05-09 17:40   ` Philippe Mathieu-Daudé
2019-05-09 17:53   ` Richard Henderson
2019-05-09 16:58 ` [Qemu-devel] [PATCH v1 03/23] tests/tcg/multiarch: add support for multiarch system tests Alex Bennée
2019-05-09 16:58 ` [Qemu-devel] [PATCH v1 04/23] tests/tcg/multiarch: add hello world system test Alex Bennée
2019-05-09 16:58 ` [Qemu-devel] [PATCH v1 05/23] semihosting: enable chardev backed output Alex Bennée
2019-05-09 22:48   ` Richard Henderson
2019-05-10  6:55     ` Alex Bennée
2019-05-10 13:52       ` Richard Henderson
2019-05-10 14:05         ` Alex Bennée
2019-05-10 14:21           ` Peter Maydell
2019-05-10 14:22   ` Peter Maydell
2019-05-10 16:59     ` Alex Bennée
2019-05-10 17:02       ` Peter Maydell
2019-05-11 18:04         ` Alex Bennée
2019-05-09 16:58 ` [Qemu-devel] [PATCH v1 06/23] editorconfig: add settings for .s/.S files Alex Bennée
2019-05-09 22:50   ` Richard Henderson
2019-05-09 16:58 ` Alex Bennée [this message]
2019-05-09 16:58 ` [Qemu-devel] [PATCH v1 08/23] tests/tcg/multiarch: move the system memory test Alex Bennée
2019-05-09 16:58 ` [Qemu-devel] [PATCH v1 09/23] tests/tcg/minilib: support %c format char Alex Bennée
2019-05-09 16:58 ` [Qemu-devel] [PATCH v1 10/23] tests/tcg/multiarch: expand system memory test to cover more Alex Bennée
2019-05-09 17:03   ` Richard Henderson
2019-05-09 16:58 ` [Qemu-devel] [PATCH v1 11/23] tests/tcg/alpha: add system boot.S Alex Bennée
2019-05-09 16:59 ` [Qemu-devel] [PATCH v1 12/23] .travis.yml: enable aarch64-softmmu and alpha-softmmu tcg tests Alex Bennée
2019-05-09 23:01   ` Richard Henderson
2019-05-09 16:59 ` [Qemu-devel] [PATCH v1 13/23] Makefile: fix coverage-report reference to BUILD_DIR Alex Bennée
2019-05-09 16:59 ` [Qemu-devel] [PATCH v1 14/23] Makefile: include per-target build directories in coverage report Alex Bennée
2019-05-09 16:59 ` [Qemu-devel] [PATCH v1 15/23] Makefile.target: support per-target coverage reports Alex Bennée
2019-05-09 16:59 ` [Qemu-devel] [PATCH v1 16/23] tests/qemu-iotests/005: Add a sanity check for large sparse file support Alex Bennée
2019-05-09 23:03   ` Richard Henderson
2019-05-09 16:59 ` [Qemu-devel] [PATCH v1 17/23] tests/qemu-iotests/check: Pick a default machine if necessary Alex Bennée
2019-05-09 16:59 ` [Qemu-devel] [PATCH v1 18/23] tests/qemu-iotests: Do not hard-code the path to bash Alex Bennée
2019-05-09 16:59 ` [Qemu-devel] [PATCH v1 19/23] cirrus / travis: Add gnu-sed and bash for macOS and FreeBSD Alex Bennée
2019-05-09 16:59 ` [Qemu-devel] [PATCH v1 20/23] tests/qemu-iotests: Remove the "_supported_os Linux" line from many tests Alex Bennée
2019-05-09 16:59 ` [Qemu-devel] [PATCH v1 21/23] tests/qemu-iotests/group: Re-use the "auto" group for tests that can always run Alex Bennée
2019-05-09 16:59 ` [Qemu-devel] [PATCH v1 22/23] tests/qemu-iotests: re-format output to for make check-block Alex Bennée
2019-05-09 18:12   ` Max Reitz
2019-05-09 20:38     ` Alex Bennée
2019-05-09 20:45       ` Eric Blake
2019-05-10  4:45   ` Thomas Huth
2019-05-09 16:59 ` [Qemu-devel] [PATCH v1 23/23] tests: Run the iotests during "make check" again Alex Bennée
2019-05-10  8:46   ` Thomas Huth

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190509165912.10512-8-alex.bennee@linaro.org \
    --to=alex.bennee@linaro.org \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-arm@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).