mirror of https://github.com/xemu-project/xemu.git
tests/tcg/nios2: Add semihosting multiarch tests
Add runtime supporting the nios2-semi.c interface. Execute the hello and memory multiarch tests. Cc: Alex Bennée <alex.bennee@linaro.org> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Message-Id: <20220421151735.31996-64-richard.henderson@linaro.org>
This commit is contained in:
parent
28a3c1b5f1
commit
ccbaa553a1
|
@ -0,0 +1,66 @@
|
||||||
|
/*
|
||||||
|
* Link script for the Nios2 10m50-ghrd board.
|
||||||
|
*
|
||||||
|
* Copyright Linaro Ltd 2022
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
tpf (rx) : ORIGIN = 0xc0000000, LENGTH = 1K
|
||||||
|
ram (rwx) : ORIGIN = 0xc8000000, LENGTH = 128M
|
||||||
|
}
|
||||||
|
|
||||||
|
PHDRS
|
||||||
|
{
|
||||||
|
RAM PT_LOAD;
|
||||||
|
}
|
||||||
|
|
||||||
|
ENTRY(_start)
|
||||||
|
EXTERN(_start)
|
||||||
|
EXTERN(_interrupt)
|
||||||
|
EXTERN(_fast_tlb_miss)
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
/* Begin at the (hardcoded) _interrupt entry point. */
|
||||||
|
.text 0xc8000120 : {
|
||||||
|
*(.text.intr)
|
||||||
|
*(.text .text.* .gnu.linkonce.t.*)
|
||||||
|
} >ram :RAM
|
||||||
|
|
||||||
|
.rodata : ALIGN(4) {
|
||||||
|
*(.rodata .rodata.* .gnu.linkonce.r.*)
|
||||||
|
} > ram :RAM
|
||||||
|
|
||||||
|
.eh_frame_hdr : ALIGN (4) {
|
||||||
|
KEEP (*(.eh_frame_hdr))
|
||||||
|
*(.eh_frame_entry .eh_frame_entry.*)
|
||||||
|
} >ram :RAM
|
||||||
|
.eh_frame : ALIGN (4) {
|
||||||
|
KEEP (*(.eh_frame)) *(.eh_frame.*)
|
||||||
|
} >ram :RAM
|
||||||
|
|
||||||
|
.data : ALIGN(4) {
|
||||||
|
*(.shdata)
|
||||||
|
*(.data .data.* .gnu.linkonce.d.*)
|
||||||
|
. = ALIGN(4);
|
||||||
|
_gp = ABSOLUTE(. + 0x8000);
|
||||||
|
*(.got.plt) *(.got)
|
||||||
|
*(.lit8)
|
||||||
|
*(.lit4)
|
||||||
|
*(.sdata .sdata.* .gnu.linkonce.s.*)
|
||||||
|
} >ram :RAM
|
||||||
|
|
||||||
|
.bss : ALIGN(4) {
|
||||||
|
__bss_start = ABSOLUTE(.);
|
||||||
|
*(.sbss .sbss.* .gnu.linkonce.sb.*)
|
||||||
|
*(.scommon)
|
||||||
|
*(.bss .bss.* .gnu.linkonce.b.*)
|
||||||
|
*(COMMON)
|
||||||
|
. = ALIGN(4);
|
||||||
|
__bss_end = ABSOLUTE(.);
|
||||||
|
} >ram :RAM
|
||||||
|
|
||||||
|
__stack = ORIGIN(ram) + LENGTH(ram);
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
#
|
||||||
|
# Nios2 system tests
|
||||||
|
#
|
||||||
|
# Copyright Linaro Ltd 2022
|
||||||
|
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
#
|
||||||
|
|
||||||
|
NIOS2_SYSTEM_SRC = $(SRC_PATH)/tests/tcg/nios2
|
||||||
|
VPATH += $(NIOS2_SYSTEM_SRC)
|
||||||
|
|
||||||
|
# These objects provide the basic boot code and helper functions for all tests
|
||||||
|
CRT_OBJS = boot.o intr.o $(MINILIB_OBJS)
|
||||||
|
LINK_SCRIPT = $(NIOS2_SYSTEM_SRC)/10m50-ghrd.ld
|
||||||
|
|
||||||
|
CFLAGS += -nostdlib -g -O0 $(MINILIB_INC)
|
||||||
|
LDFLAGS += -Wl,-T$(LINK_SCRIPT) -static -nostdlib $(CRT_OBJS) -lgcc
|
||||||
|
|
||||||
|
%.o: %.S
|
||||||
|
$(call quiet-command, $(CC) $(CFLAGS) $(EXTRA_CFLAGS) -x assembler-with-cpp -c $< -o $@, AS, $@)
|
||||||
|
|
||||||
|
%.o: %.c
|
||||||
|
$(call quiet-command, $(CC) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@, CC, $@)
|
||||||
|
|
||||||
|
# Build and link the tests
|
||||||
|
%: %.o $(LINK_SCRIPT) $(CRT_OBJS)
|
||||||
|
$(call quiet-command, $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $< -o $@ $(LDFLAGS), LD, $@)
|
||||||
|
|
||||||
|
# FIXME: nios2 semihosting writes to stdout, not a chardev
|
||||||
|
QEMU_OPTS = -M 10m50-ghrd,vic=on -semihosting >$@.out -kernel
|
||||||
|
|
||||||
|
memory: CFLAGS+=-DCHECK_UNALIGNED=0
|
||||||
|
TESTS += $(MULTIARCH_TESTS)
|
|
@ -0,0 +1,218 @@
|
||||||
|
/*
|
||||||
|
* Minimal Nios2 system boot code.
|
||||||
|
*
|
||||||
|
* Copyright Linaro Ltd 2022
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "semicall.h"
|
||||||
|
|
||||||
|
.text
|
||||||
|
.set noat
|
||||||
|
|
||||||
|
_start:
|
||||||
|
/* Linker script defines stack at end of ram. */
|
||||||
|
movia sp, __stack
|
||||||
|
|
||||||
|
/* Install trampoline to _fast_tlb_miss at hardcoded vector. */
|
||||||
|
movia r4, 0xc0000100
|
||||||
|
movia r5, _ftm_tramp
|
||||||
|
movi r6, .L__ftm_end - _ftm_tramp
|
||||||
|
call memcpy
|
||||||
|
|
||||||
|
/* Zero the bss to satisfy C. */
|
||||||
|
movia r4, __bss_start
|
||||||
|
movia r6, __bss_end
|
||||||
|
sub r6, r6, r4
|
||||||
|
movi r5, 0
|
||||||
|
call memset
|
||||||
|
|
||||||
|
/* Test! */
|
||||||
|
call main
|
||||||
|
|
||||||
|
/* Exit with main's return value. */
|
||||||
|
movi r4, HOSTED_EXIT
|
||||||
|
mov r5, r2
|
||||||
|
semihosting_call
|
||||||
|
|
||||||
|
.globl _start
|
||||||
|
.type _start, @function
|
||||||
|
.size _start, . - _start
|
||||||
|
|
||||||
|
_ftm_tramp:
|
||||||
|
movia et, _fast_tlb_miss
|
||||||
|
jmp et
|
||||||
|
.L__ftm_end:
|
||||||
|
|
||||||
|
.type _ftm_tramp, @function
|
||||||
|
.size _ftm_tramp, . - _ftm_tramp
|
||||||
|
|
||||||
|
#define dst r4
|
||||||
|
#define src r5
|
||||||
|
#define len r6
|
||||||
|
|
||||||
|
memcpy:
|
||||||
|
/* Store return value right away, per API */
|
||||||
|
mov r2, dst
|
||||||
|
|
||||||
|
/* Check for both dst and src aligned. */
|
||||||
|
or at, dst, src
|
||||||
|
andi at, at, 3
|
||||||
|
bne at, zero, .L_mc_test1
|
||||||
|
|
||||||
|
/* Copy blocks of 8. */
|
||||||
|
|
||||||
|
movi at, 8
|
||||||
|
bltu len, at, .L_mc_test4
|
||||||
|
|
||||||
|
.L_mc_loop8:
|
||||||
|
ldw r8, 0(src)
|
||||||
|
ldw r9, 4(src)
|
||||||
|
addi src, src, 8
|
||||||
|
addi dst, dst, 8
|
||||||
|
subi len, len, 8
|
||||||
|
stw r8, -8(dst)
|
||||||
|
stw r9, -4(dst)
|
||||||
|
bgeu len, at, .L_mc_loop8
|
||||||
|
|
||||||
|
/* Copy final aligned block of 4. */
|
||||||
|
|
||||||
|
.L_mc_test4:
|
||||||
|
movi at, 4
|
||||||
|
bltu len, at, .L_mc_test1
|
||||||
|
|
||||||
|
ldw r8, 0(src)
|
||||||
|
addi src, src, 4
|
||||||
|
addi dst, dst, 4
|
||||||
|
subi len, len, 4
|
||||||
|
stw r8, -4(dst)
|
||||||
|
|
||||||
|
/* Copy single bytes to finish. */
|
||||||
|
|
||||||
|
.L_mc_test1:
|
||||||
|
beq len, zero, .L_mc_done
|
||||||
|
|
||||||
|
.L_mc_loop1:
|
||||||
|
ldb r8, 0(src)
|
||||||
|
addi src, src, 1
|
||||||
|
addi dst, dst, 1
|
||||||
|
subi len, len, 1
|
||||||
|
stb r8, -1(dst)
|
||||||
|
bne len, zero, .L_mc_loop1
|
||||||
|
|
||||||
|
.L_mc_done:
|
||||||
|
ret
|
||||||
|
|
||||||
|
#undef dst
|
||||||
|
#undef src
|
||||||
|
#undef len
|
||||||
|
|
||||||
|
.global memcpy
|
||||||
|
.type memcpy, @function
|
||||||
|
.size memcpy, . - memcpy
|
||||||
|
|
||||||
|
#define dst r4
|
||||||
|
#define val r5
|
||||||
|
#define len r6
|
||||||
|
|
||||||
|
memset:
|
||||||
|
/* Store return value right away, per API */
|
||||||
|
mov r2, dst
|
||||||
|
|
||||||
|
/* Check for small blocks; fall back to bytewise. */
|
||||||
|
movi r3, 8
|
||||||
|
bltu len, r3, .L_ms_test1
|
||||||
|
|
||||||
|
/* Replicate the byte across the word. */
|
||||||
|
andi val, val, 0xff
|
||||||
|
slli at, val, 8
|
||||||
|
or val, val, at
|
||||||
|
slli at, val, 16
|
||||||
|
or val, val, at
|
||||||
|
|
||||||
|
/* Check for destination alignment; realign if needed. */
|
||||||
|
andi at, dst, 3
|
||||||
|
bne at, zero, .L_ms_align
|
||||||
|
|
||||||
|
/* Set blocks of 8. */
|
||||||
|
|
||||||
|
.L_ms_loop8:
|
||||||
|
stw val, 0(dst)
|
||||||
|
stw val, 4(dst)
|
||||||
|
addi dst, dst, 8
|
||||||
|
subi len, len, 8
|
||||||
|
bgeu len, r3, .L_ms_loop8
|
||||||
|
|
||||||
|
/* Set final aligned block of 4. */
|
||||||
|
|
||||||
|
.L_ms_test4:
|
||||||
|
movi at, 4
|
||||||
|
bltu len, at, .L_ms_test1
|
||||||
|
|
||||||
|
stw r8, 0(dst)
|
||||||
|
addi dst, dst, 4
|
||||||
|
subi len, len, 4
|
||||||
|
stw r8, -4(dst)
|
||||||
|
|
||||||
|
/* Set single bytes to finish. */
|
||||||
|
|
||||||
|
.L_ms_test1:
|
||||||
|
beq len, zero, .L_ms_done
|
||||||
|
|
||||||
|
.L_ms_loop1:
|
||||||
|
stb r8, 0(dst)
|
||||||
|
addi dst, dst, 1
|
||||||
|
subi len, len, 1
|
||||||
|
bne len, zero, .L_ms_loop1
|
||||||
|
|
||||||
|
.L_ms_done:
|
||||||
|
ret
|
||||||
|
|
||||||
|
/* Realign for a large block, len >= 8. */
|
||||||
|
.L_ms_align:
|
||||||
|
andi at, dst, 1
|
||||||
|
beq at, zero, 2f
|
||||||
|
|
||||||
|
stb val, 0(dst)
|
||||||
|
addi dst, dst, 1
|
||||||
|
subi len, len, 1
|
||||||
|
|
||||||
|
2: andi at, dst, 2
|
||||||
|
beq at, zero, 4f
|
||||||
|
|
||||||
|
sth val, 0(dst)
|
||||||
|
addi dst, dst, 2
|
||||||
|
subi len, len, 2
|
||||||
|
|
||||||
|
4: bgeu len, r3, .L_ms_loop8
|
||||||
|
br .L_ms_test4
|
||||||
|
|
||||||
|
#undef dst
|
||||||
|
#undef val
|
||||||
|
#undef len
|
||||||
|
|
||||||
|
.global memset
|
||||||
|
.type memset, @function
|
||||||
|
.size memset, . - memset
|
||||||
|
|
||||||
|
/*
|
||||||
|
* void __sys_outc(char c);
|
||||||
|
*/
|
||||||
|
__sys_outc:
|
||||||
|
subi sp, sp, 16
|
||||||
|
stb r4, 0(sp) /* buffer[0] = c */
|
||||||
|
movi at, 1
|
||||||
|
stw at, 4(sp) /* STDOUT_FILENO */
|
||||||
|
stw sp, 8(sp) /* buffer */
|
||||||
|
stw at, 12(sp) /* len */
|
||||||
|
|
||||||
|
movi r4, HOSTED_WRITE
|
||||||
|
addi r5, sp, 4
|
||||||
|
semihosting_call
|
||||||
|
|
||||||
|
addi sp, sp, 16
|
||||||
|
ret
|
||||||
|
|
||||||
|
.global __sys_outc
|
||||||
|
.type __sys_outc, @function
|
||||||
|
.size __sys_outc, . - __sys_outc
|
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
* Minimal Nios2 system boot code -- exit on interrupt.
|
||||||
|
*
|
||||||
|
* Copyright Linaro Ltd 2022
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "semicall.h"
|
||||||
|
|
||||||
|
.section .text.intr, "ax"
|
||||||
|
.global _interrupt
|
||||||
|
.type _interrupt, @function
|
||||||
|
|
||||||
|
_interrupt:
|
||||||
|
rdctl r5, exception /* extract exception.CAUSE */
|
||||||
|
srli r5, r5, 2
|
||||||
|
movi r4, HOSTED_EXIT
|
||||||
|
semihosting_call
|
||||||
|
|
||||||
|
.size _interrupt, . - _interrupt
|
||||||
|
|
||||||
|
.text
|
||||||
|
.global _fast_tlb_miss
|
||||||
|
.type _fast_tlb_miss, @function
|
||||||
|
|
||||||
|
_fast_tlb_miss:
|
||||||
|
movi r5, 32
|
||||||
|
movi r4, HOSTED_EXIT
|
||||||
|
semihosting_call
|
||||||
|
|
||||||
|
.size _fast_tlb_miss, . - _fast_tlb_miss
|
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
* Nios2 semihosting interface.
|
||||||
|
*
|
||||||
|
* Copyright Linaro Ltd 2022
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SEMICALL_H
|
||||||
|
#define SEMICALL_H
|
||||||
|
|
||||||
|
#define HOSTED_EXIT 0
|
||||||
|
#define HOSTED_INIT_SIM 1
|
||||||
|
#define HOSTED_OPEN 2
|
||||||
|
#define HOSTED_CLOSE 3
|
||||||
|
#define HOSTED_READ 4
|
||||||
|
#define HOSTED_WRITE 5
|
||||||
|
#define HOSTED_LSEEK 6
|
||||||
|
#define HOSTED_RENAME 7
|
||||||
|
#define HOSTED_UNLINK 8
|
||||||
|
#define HOSTED_STAT 9
|
||||||
|
#define HOSTED_FSTAT 10
|
||||||
|
#define HOSTED_GETTIMEOFDAY 11
|
||||||
|
#define HOSTED_ISATTY 12
|
||||||
|
#define HOSTED_SYSTEM 13
|
||||||
|
|
||||||
|
#define semihosting_call break 1
|
||||||
|
|
||||||
|
#endif /* SEMICALL_H */
|
Loading…
Reference in New Issue