Merge remote-tracking branch 'remotes/mwalle/tags/lm32-semihosting/20140524' into staging

* remotes/mwalle/tags/lm32-semihosting/20140524:
  lm32: remove lm32_sys
  test: lm32: use semihosting for testing
  target-lm32: add semihosting support
  test: lm32: make test cases independent

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2014-05-27 22:11:25 +01:00
commit 2f21ff25c0
22 changed files with 366 additions and 216 deletions

View File

@ -29,7 +29,6 @@ obj-$(CONFIG_NSERIES) += cbus.o
obj-$(CONFIG_ECCMEMCTL) += eccmemctl.o obj-$(CONFIG_ECCMEMCTL) += eccmemctl.o
obj-$(CONFIG_EXYNOS4) += exynos4210_pmu.o obj-$(CONFIG_EXYNOS4) += exynos4210_pmu.o
obj-$(CONFIG_IMX) += imx_ccm.o obj-$(CONFIG_IMX) += imx_ccm.o
obj-$(CONFIG_LM32) += lm32_sys.o
obj-$(CONFIG_MILKYMIST) += milkymist-hpdmc.o obj-$(CONFIG_MILKYMIST) += milkymist-hpdmc.o
obj-$(CONFIG_MILKYMIST) += milkymist-pfpu.o obj-$(CONFIG_MILKYMIST) += milkymist-pfpu.o
obj-$(CONFIG_MAINSTONE) += mst_fpga.o obj-$(CONFIG_MAINSTONE) += mst_fpga.o

View File

@ -1,179 +0,0 @@
/*
* QEMU model of the LatticeMico32 system control block.
*
* Copyright (c) 2010 Michael Walle <michael@walle.cc>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
/*
* This model is mainly intended for testing purposes and doesn't fit to any
* real hardware. On the one hand it provides a control register (R_CTRL) on
* the other hand it supports the lm32 tests.
*
* A write to the control register causes a system shutdown.
* Tests first write the pointer to a test name to the test name register
* (R_TESTNAME) and then write a zero to the pass/fail register (R_PASSFAIL) if
* the test is passed or any non-zero value to it if the test is failed.
*/
#include "hw/hw.h"
#include "hw/sysbus.h"
#include "trace.h"
#include "qemu/log.h"
#include "qemu/error-report.h"
#include "sysemu/sysemu.h"
enum {
R_CTRL = 0,
R_PASSFAIL,
R_TESTNAME,
R_MAX
};
#define MAX_TESTNAME_LEN 32
#define TYPE_LM32_SYS "lm32-sys"
#define LM32_SYS(obj) OBJECT_CHECK(LM32SysState, (obj), TYPE_LM32_SYS)
struct LM32SysState {
SysBusDevice parent_obj;
MemoryRegion iomem;
uint32_t base;
uint32_t regs[R_MAX];
uint8_t testname[MAX_TESTNAME_LEN];
};
typedef struct LM32SysState LM32SysState;
static void copy_testname(LM32SysState *s)
{
cpu_physical_memory_read(s->regs[R_TESTNAME], s->testname,
MAX_TESTNAME_LEN);
s->testname[MAX_TESTNAME_LEN - 1] = '\0';
}
static void sys_write(void *opaque, hwaddr addr,
uint64_t value, unsigned size)
{
LM32SysState *s = opaque;
char *testname;
trace_lm32_sys_memory_write(addr, value);
addr >>= 2;
switch (addr) {
case R_CTRL:
qemu_system_shutdown_request();
break;
case R_PASSFAIL:
s->regs[addr] = value;
testname = (char *)s->testname;
fprintf(stderr, "TC %-*s %s\n", MAX_TESTNAME_LEN,
testname, (value) ? "FAILED" : "OK");
if (value) {
cpu_dump_state(qemu_get_cpu(0), stderr, fprintf, 0);
}
break;
case R_TESTNAME:
s->regs[addr] = value;
copy_testname(s);
break;
default:
error_report("lm32_sys: write access to unknown register 0x"
TARGET_FMT_plx, addr << 2);
break;
}
}
static bool sys_ops_accepts(void *opaque, hwaddr addr,
unsigned size, bool is_write)
{
return is_write && size == 4;
}
static const MemoryRegionOps sys_ops = {
.write = sys_write,
.valid.accepts = sys_ops_accepts,
.endianness = DEVICE_NATIVE_ENDIAN,
};
static void sys_reset(DeviceState *d)
{
LM32SysState *s = LM32_SYS(d);
int i;
for (i = 0; i < R_MAX; i++) {
s->regs[i] = 0;
}
memset(s->testname, 0, MAX_TESTNAME_LEN);
}
static int lm32_sys_init(SysBusDevice *dev)
{
LM32SysState *s = LM32_SYS(dev);
memory_region_init_io(&s->iomem, OBJECT(dev), &sys_ops , s,
"sys", R_MAX * 4);
sysbus_init_mmio(dev, &s->iomem);
/* Note: This device is not created in the board initialization,
* instead it has to be added with the -device parameter. Therefore,
* the device maps itself. */
sysbus_mmio_map(dev, 0, s->base);
return 0;
}
static const VMStateDescription vmstate_lm32_sys = {
.name = "lm32-sys",
.version_id = 1,
.minimum_version_id = 1,
.fields = (VMStateField[]) {
VMSTATE_UINT32_ARRAY(regs, LM32SysState, R_MAX),
VMSTATE_BUFFER(testname, LM32SysState),
VMSTATE_END_OF_LIST()
}
};
static Property lm32_sys_properties[] = {
DEFINE_PROP_UINT32("base", LM32SysState, base, 0xffff0000),
DEFINE_PROP_END_OF_LIST(),
};
static void lm32_sys_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
k->init = lm32_sys_init;
dc->reset = sys_reset;
dc->vmsd = &vmstate_lm32_sys;
dc->props = lm32_sys_properties;
}
static const TypeInfo lm32_sys_info = {
.name = TYPE_LM32_SYS,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(LM32SysState),
.class_init = lm32_sys_class_init,
};
static void lm32_sys_register_types(void)
{
type_register_static(&lm32_sys_info);
}
type_init(lm32_sys_register_types)

View File

@ -3071,7 +3071,8 @@ STEXI
Set OpenBIOS nvram @var{variable} to given @var{value} (PPC, SPARC only). Set OpenBIOS nvram @var{variable} to given @var{value} (PPC, SPARC only).
ETEXI ETEXI
DEF("semihosting", 0, QEMU_OPTION_semihosting, DEF("semihosting", 0, QEMU_OPTION_semihosting,
"-semihosting semihosting mode\n", QEMU_ARCH_ARM | QEMU_ARCH_M68K | QEMU_ARCH_XTENSA) "-semihosting semihosting mode\n",
QEMU_ARCH_ARM | QEMU_ARCH_M68K | QEMU_ARCH_XTENSA | QEMU_ARCH_LM32)
STEXI STEXI
@item -semihosting @item -semihosting
@findex -semihosting @findex -semihosting

View File

@ -1,3 +1,4 @@
obj-y += translate.o op_helper.o helper.o cpu.o obj-y += translate.o op_helper.o helper.o cpu.o
obj-y += gdbstub.o obj-y += gdbstub.o
obj-y += lm32-semi.o
obj-$(CONFIG_SOFTMMU) += machine.o obj-$(CONFIG_SOFTMMU) += machine.o

View File

@ -16,14 +16,13 @@ This will make serial0 (the lm32_uart) and serial1 (the JTAG UART)
available as virtual consoles. available as virtual consoles.
Programmatically terminate the emulator Semihosting
---------------------------------------- -----------
Originally neither the LatticeMico32 nor its peripherals support a Semihosting on this target is supported. Some system calls like read, write
mechanism to shut down the machine. Emulation aware programs can write to a and exit are executed on the host if semihosting is enabled. See
to a special register within the system control block to shut down the target/lm32-semi.c for all supported system calls. Emulation aware programs
virtual machine. For more details see hw/lm32_sys.c. The lm32-evr is the can use this mechanism to shut down the virtual machine and print to the
first BSP which instantiate this model. A (32 bit) write to 0xfff0000 host console. See the tcg tests for an example.
causes a vm shutdown.
Special instructions Special instructions

View File

@ -217,6 +217,7 @@ void lm32_breakpoint_remove(CPULM32State *env, int index);
void lm32_watchpoint_insert(CPULM32State *env, int index, target_ulong address, void lm32_watchpoint_insert(CPULM32State *env, int index, target_ulong address,
lm32_wp_t wp_type); lm32_wp_t wp_type);
void lm32_watchpoint_remove(CPULM32State *env, int index); void lm32_watchpoint_remove(CPULM32State *env, int index);
bool lm32_cpu_do_semihosting(CPUState *cs);
static inline CPULM32State *cpu_init(const char *cpu_model) static inline CPULM32State *cpu_init(const char *cpu_model)
{ {

View File

@ -1,7 +1,7 @@
/* /*
* LatticeMico32 helper routines. * LatticeMico32 helper routines.
* *
* Copyright (c) 2010 Michael Walle <michael@walle.cc> * Copyright (c) 2010-2014 Michael Walle <michael@walle.cc>
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -19,6 +19,7 @@
#include "cpu.h" #include "cpu.h"
#include "qemu/host-utils.h" #include "qemu/host-utils.h"
#include "sysemu/sysemu.h"
int lm32_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw, int lm32_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
int mmu_idx) int mmu_idx)
@ -159,11 +160,20 @@ void lm32_cpu_do_interrupt(CPUState *cs)
"exception at pc=%x type=%x\n", env->pc, cs->exception_index); "exception at pc=%x type=%x\n", env->pc, cs->exception_index);
switch (cs->exception_index) { switch (cs->exception_index) {
case EXCP_SYSTEMCALL:
if (unlikely(semihosting_enabled)) {
/* do_semicall() returns true if call was handled. Otherwise
* do the normal exception handling. */
if (lm32_cpu_do_semihosting(cs)) {
env->pc += 4;
break;
}
}
/* fall through */
case EXCP_INSN_BUS_ERROR: case EXCP_INSN_BUS_ERROR:
case EXCP_DATA_BUS_ERROR: case EXCP_DATA_BUS_ERROR:
case EXCP_DIVIDE_BY_ZERO: case EXCP_DIVIDE_BY_ZERO:
case EXCP_IRQ: case EXCP_IRQ:
case EXCP_SYSTEMCALL:
/* non-debug exceptions */ /* non-debug exceptions */
env->regs[R_EA] = env->pc; env->regs[R_EA] = env->pc;
env->ie |= (env->ie & IE_IE) ? IE_EIE : 0; env->ie |= (env->ie & IE_IE) ? IE_EIE : 0;

215
target-lm32/lm32-semi.c Normal file
View File

@ -0,0 +1,215 @@
/*
* Lattice Mico32 semihosting syscall interface
*
* Copyright (c) 2014 Michael Walle <michael@walle.cc>
*
* Based on target-m68k/m68k-semi.c, which is
* Copyright (c) 2005-2007 CodeSourcery.
*
* This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
*/
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <stddef.h>
#include "cpu.h"
#include "helper.h"
#include "qemu/log.h"
#include "exec/softmmu-semi.h"
enum {
TARGET_SYS_exit = 1,
TARGET_SYS_open = 2,
TARGET_SYS_close = 3,
TARGET_SYS_read = 4,
TARGET_SYS_write = 5,
TARGET_SYS_lseek = 6,
TARGET_SYS_fstat = 10,
TARGET_SYS_stat = 15,
};
enum {
NEWLIB_O_RDONLY = 0x0,
NEWLIB_O_WRONLY = 0x1,
NEWLIB_O_RDWR = 0x2,
NEWLIB_O_APPEND = 0x8,
NEWLIB_O_CREAT = 0x200,
NEWLIB_O_TRUNC = 0x400,
NEWLIB_O_EXCL = 0x800,
};
static int translate_openflags(int flags)
{
int hf;
if (flags & NEWLIB_O_WRONLY) {
hf = O_WRONLY;
} else if (flags & NEWLIB_O_RDWR) {
hf = O_RDWR;
} else {
hf = O_RDONLY;
}
if (flags & NEWLIB_O_APPEND) {
hf |= O_APPEND;
}
if (flags & NEWLIB_O_CREAT) {
hf |= O_CREAT;
}
if (flags & NEWLIB_O_TRUNC) {
hf |= O_TRUNC;
}
if (flags & NEWLIB_O_EXCL) {
hf |= O_EXCL;
}
return hf;
}
struct newlib_stat {
int16_t newlib_st_dev; /* device */
uint16_t newlib_st_ino; /* inode */
uint16_t newlib_st_mode; /* protection */
uint16_t newlib_st_nlink; /* number of hard links */
uint16_t newlib_st_uid; /* user ID of owner */
uint16_t newlib_st_gid; /* group ID of owner */
int16_t newlib_st_rdev; /* device type (if inode device) */
int32_t newlib_st_size; /* total size, in bytes */
int32_t newlib_st_atime; /* time of last access */
uint32_t newlib_st_spare1;
int32_t newlib_st_mtime; /* time of last modification */
uint32_t newlib_st_spare2;
int32_t newlib_st_ctime; /* time of last change */
uint32_t newlib_st_spare3;
} QEMU_PACKED;
static int translate_stat(CPULM32State *env, target_ulong addr,
struct stat *s)
{
struct newlib_stat *p;
p = lock_user(VERIFY_WRITE, addr, sizeof(struct newlib_stat), 0);
if (!p) {
return 0;
}
p->newlib_st_dev = cpu_to_be16(s->st_dev);
p->newlib_st_ino = cpu_to_be16(s->st_ino);
p->newlib_st_mode = cpu_to_be16(s->st_mode);
p->newlib_st_nlink = cpu_to_be16(s->st_nlink);
p->newlib_st_uid = cpu_to_be16(s->st_uid);
p->newlib_st_gid = cpu_to_be16(s->st_gid);
p->newlib_st_rdev = cpu_to_be16(s->st_rdev);
p->newlib_st_size = cpu_to_be32(s->st_size);
p->newlib_st_atime = cpu_to_be32(s->st_atime);
p->newlib_st_mtime = cpu_to_be32(s->st_mtime);
p->newlib_st_ctime = cpu_to_be32(s->st_ctime);
unlock_user(p, addr, sizeof(struct newlib_stat));
return 1;
}
bool lm32_cpu_do_semihosting(CPUState *cs)
{
LM32CPU *cpu = LM32_CPU(cs);
CPULM32State *env = &cpu->env;
int ret = -1;
target_ulong nr, arg0, arg1, arg2;
void *p;
struct stat s;
nr = env->regs[R_R8];
arg0 = env->regs[R_R1];
arg1 = env->regs[R_R2];
arg2 = env->regs[R_R3];
switch (nr) {
case TARGET_SYS_exit:
/* void _exit(int rc) */
exit(arg0);
case TARGET_SYS_open:
/* int open(const char *pathname, int flags) */
p = lock_user_string(arg0);
if (!p) {
ret = -1;
} else {
ret = open(p, translate_openflags(arg2));
unlock_user(p, arg0, 0);
}
break;
case TARGET_SYS_read:
/* ssize_t read(int fd, const void *buf, size_t count) */
p = lock_user(VERIFY_WRITE, arg1, arg2, 0);
if (!p) {
ret = -1;
} else {
ret = read(arg0, p, arg2);
unlock_user(p, arg1, arg2);
}
break;
case TARGET_SYS_write:
/* ssize_t write(int fd, const void *buf, size_t count) */
p = lock_user(VERIFY_READ, arg1, arg2, 1);
if (!p) {
ret = -1;
} else {
ret = write(arg0, p, arg2);
unlock_user(p, arg1, 0);
}
break;
case TARGET_SYS_close:
/* int close(int fd) */
/* don't close stdin/stdout/stderr */
if (arg0 > 2) {
ret = close(arg0);
} else {
ret = 0;
}
break;
case TARGET_SYS_lseek:
/* off_t lseek(int fd, off_t offset, int whence */
ret = lseek(arg0, arg1, arg2);
break;
case TARGET_SYS_stat:
/* int stat(const char *path, struct stat *buf) */
p = lock_user_string(arg0);
if (!p) {
ret = -1;
} else {
ret = stat(p, &s);
unlock_user(p, arg0, 0);
if (translate_stat(env, arg1, &s) == 0) {
ret = -1;
}
}
break;
case TARGET_SYS_fstat:
/* int stat(int fd, struct stat *buf) */
ret = fstat(arg0, &s);
if (ret == 0) {
if (translate_stat(env, arg1, &s) == 0) {
ret = -1;
}
}
break;
default:
/* unhandled */
return false;
}
env->regs[R_R1] = ret;
return true;
}

View File

@ -3,7 +3,7 @@
CROSS=lm32-elf- CROSS=lm32-elf-
SIM = qemu-system-lm32 SIM = qemu-system-lm32
SIMFLAGS = -M lm32-evr -nographic -device lm32-sys -net none -kernel SIMFLAGS = -M lm32-evr -nographic -semihosting -net none -kernel
CC = $(CROSS)gcc CC = $(CROSS)gcc
AS = $(CROSS)as AS = $(CROSS)as
@ -18,6 +18,7 @@ LDFLAGS = -T$(TSRC_PATH)/linker.ld
ASFLAGS += -Wa,-I,$(TSRC_PATH)/ ASFLAGS += -Wa,-I,$(TSRC_PATH)/
CRT = crt.o CRT = crt.o
HELPER = helper.o
TESTCASES += test_add.tst TESTCASES += test_add.tst
TESTCASES += test_addi.tst TESTCASES += test_addi.tst
TESTCASES += test_and.tst TESTCASES += test_and.tst
@ -91,15 +92,15 @@ all: build
%.o: $(TSRC_PATH)/%.S %.o: $(TSRC_PATH)/%.S
$(AS) $(ASFLAGS) -c $< -o $@ $(AS) $(ASFLAGS) -c $< -o $@
%.tst: %.o $(TSRC_PATH)/macros.inc $(CRT) %.tst: %.o $(TSRC_PATH)/macros.inc $(CRT) $(HELPER)
$(LD) $(LDFLAGS) $(NOSTDFLAGS) $(CRT) $< -o $@ $(LD) $(LDFLAGS) $(NOSTDFLAGS) $(CRT) $(HELPER) $< -o $@
build: $(CRT) $(TESTCASES) build: $(TESTCASES)
check: $(TESTCASES:test_%.tst=check_%) check: $(TESTCASES:test_%.tst=check_%)
check_%: test_%.tst $(CRT) $(SYS) check_%: test_%.tst
$(SIM) $(SIMFLAGS) $< @$(SIM) $(SIMFLAGS) $<
clean: clean:
$(RM) -fr $(TESTCASES) $(CRT) $(RM) -fr $(TESTCASES) $(CRT) $(HELPER)

View File

@ -8,9 +8,9 @@ _reset_handler:
ori r1, r1, lo(_start) ori r1, r1, lo(_start)
wcsr eba, r1 wcsr eba, r1
wcsr deba, r1 wcsr deba, r1
mvhi sp, hi(_fstack)
ori sp, sp, lo(_fstack)
bi _main bi _main
nop
nop
_breakpoint_handler: _breakpoint_handler:
ori r25, r25, 1 ori r25, r25, 1

65
tests/tcg/lm32/helper.S Normal file
View File

@ -0,0 +1,65 @@
.text
.global _start, _write, _exit
.global _tc_fail, _tc_pass
_write:
addi sp, sp, -4
sw (sp+4), r8
mvi r8, 5
scall
lw r8, (sp+4)
addi sp, sp, 4
ret
_exit:
mvi r8, 1
scall
1:
bi 1b
_tc_pass:
.data
1:
.ascii "OK\n"
2:
.text
addi sp, sp, -16
sw (sp+4), ra
sw (sp+8), r1
sw (sp+12), r2
sw (sp+16), r3
mvi r1, 1
mvhi r2, hi(1b)
ori r2, r2, lo(1b)
mvi r3, (2b - 1b)
calli _write
lw r3, (sp+16)
lw r2, (sp+12)
lw r1, (sp+8)
lw ra, (sp+4)
addi sp, sp, 16
ret
_tc_fail:
.data
1:
.ascii "FAILED\n"
2:
.text
addi sp, sp, -16
sw (sp+4), ra
sw (sp+8), r1
sw (sp+12), r2
sw (sp+16), r3
sw (sp+4), ra
mvi r1, 1
mvhi r2, hi(1b)
ori r2, r2, lo(1b)
mvi r3, (2b - 1b)
calli _write
lw r3, (sp+16)
lw r2, (sp+12)
lw r1, (sp+8)
lw ra, (sp+4)
addi sp, sp, 16
ret

View File

@ -1,12 +1,26 @@
.equ MAX_TESTNAME_LEN, 32
.macro test_name name .macro test_name name
.data .data
tn_\name: tn_\name:
.asciz "\name" .ascii "\name"
.space MAX_TESTNAME_LEN - (. - tn_\name), ' '
.text .text
mvhi r13, hi(tn_\name) .global \name
ori r13, r13, lo(tn_\name) \name:
sw (r12+8), r13 addi sp, sp, -12
sw (sp+4), r1
sw (sp+8), r2
sw (sp+12), r3
mvi r1, 1
mvhi r2, hi(tn_\name)
ori r2, r2, lo(tn_\name)
mvi r3, MAX_TESTNAME_LEN
calli _write
lw r3, (sp+12)
lw r2, (sp+8)
lw r1, (sp+4)
addi sp, sp, 12
.endm .endm
.macro load reg val .macro load reg val
@ -15,13 +29,12 @@ tn_\name:
.endm .endm
.macro tc_pass .macro tc_pass
mvi r13, 0 calli _tc_pass
sw (r12+4), r13
.endm .endm
.macro tc_fail .macro tc_fail
mvi r13, 1 addi r12, r12, 1
sw (r12+4), r13 calli _tc_fail
.endm .endm
.macro check_r3 val .macro check_r3 val
@ -63,14 +76,12 @@ tn_\name:
.global _main .global _main
.text .text
_main: _main:
mvhi r12, hi(0xffff0000) # base address of test block mvi r12, 0
ori r12, r12, lo(0xffff0000)
.endm .endm
.macro end .macro end
sw (r12+0), r0 mv r1, r12
1: calli _exit
bi 1b
.endm .endm
# base + # base +

View File

@ -8,10 +8,12 @@ lb r3, (r1+0)
check_r3 0x7e check_r3 0x7e
test_name LB_2 test_name LB_2
load r1 data
lb r3, (r1+1) lb r3, (r1+1)
check_r3 0x7f check_r3 0x7f
test_name LB_3 test_name LB_3
load r1 data
lb r3, (r1+-1) lb r3, (r1+-1)
check_r3 0x7d check_r3 0x7d
@ -21,10 +23,12 @@ lb r3, (r1+0)
check_r3 0xfffffffe check_r3 0xfffffffe
test_name LB_5 test_name LB_5
load r1 data_msb
lb r3, (r1+1) lb r3, (r1+1)
check_r3 0xffffffff check_r3 0xffffffff
test_name LB_6 test_name LB_6
load r1 data_msb
lb r3, (r1+-1) lb r3, (r1+-1)
check_r3 0xfffffffd check_r3 0xfffffffd

View File

@ -8,10 +8,12 @@ lbu r3, (r1+0)
check_r3 0x7e check_r3 0x7e
test_name LBU_2 test_name LBU_2
load r1 data
lbu r3, (r1+1) lbu r3, (r1+1)
check_r3 0x7f check_r3 0x7f
test_name LBU_3 test_name LBU_3
load r1 data
lbu r3, (r1+-1) lbu r3, (r1+-1)
check_r3 0x7d check_r3 0x7d
@ -21,10 +23,12 @@ lbu r3, (r1+0)
check_r3 0xfe check_r3 0xfe
test_name LBU_5 test_name LBU_5
load r1 data_msb
lbu r3, (r1+1) lbu r3, (r1+1)
check_r3 0xff check_r3 0xff
test_name LBU_6 test_name LBU_6
load r1 data_msb
lbu r3, (r1+-1) lbu r3, (r1+-1)
check_r3 0xfd check_r3 0xfd

View File

@ -8,10 +8,12 @@ lh r3, (r1+0)
check_r3 0x7e7f check_r3 0x7e7f
test_name LH_2 test_name LH_2
load r1 data
lh r3, (r1+2) lh r3, (r1+2)
check_r3 0x7071 check_r3 0x7071
test_name LH_3 test_name LH_3
load r1 data
lh r3, (r1+-2) lh r3, (r1+-2)
check_r3 0x7c7d check_r3 0x7c7d
@ -21,10 +23,12 @@ lh r3, (r1+0)
check_r3 0xfffffeff check_r3 0xfffffeff
test_name LH_5 test_name LH_5
load r1 data_msb
lh r3, (r1+2) lh r3, (r1+2)
check_r3 0xfffff0f1 check_r3 0xfffff0f1
test_name LH_6 test_name LH_6
load r1 data_msb
lh r3, (r1+-2) lh r3, (r1+-2)
check_r3 0xfffffcfd check_r3 0xfffffcfd

View File

@ -8,10 +8,12 @@ lhu r3, (r1+0)
check_r3 0x7e7f check_r3 0x7e7f
test_name LHU_2 test_name LHU_2
load r1 data
lhu r3, (r1+2) lhu r3, (r1+2)
check_r3 0x7071 check_r3 0x7071
test_name LHU_3 test_name LHU_3
load r1 data
lhu r3, (r1+-2) lhu r3, (r1+-2)
check_r3 0x7c7d check_r3 0x7c7d
@ -21,10 +23,12 @@ lhu r3, (r1+0)
check_r3 0xfeff check_r3 0xfeff
test_name LHU_5 test_name LHU_5
load r1 data_msb
lhu r3, (r1+2) lhu r3, (r1+2)
check_r3 0xf0f1 check_r3 0xf0f1
test_name LHU_6 test_name LHU_6
load r1 data_msb
lhu r3, (r1+-2) lhu r3, (r1+-2)
check_r3 0xfcfd check_r3 0xfcfd

View File

@ -8,10 +8,12 @@ lw r3, (r1+0)
check_r3 0x7e7f7071 check_r3 0x7e7f7071
test_name LW_2 test_name LW_2
load r1 data
lw r3, (r1+4) lw r3, (r1+4)
check_r3 0x72737475 check_r3 0x72737475
test_name LW_3 test_name LW_3
load r1 data
lw r3, (r1+-4) lw r3, (r1+-4)
check_r3 0x7a7b7c7d check_r3 0x7a7b7c7d

View File

@ -9,11 +9,13 @@ sb (r1+0), r2
check_mem data 0xaa000000 check_mem data 0xaa000000
test_name SB_2 test_name SB_2
load r1 data
load r2 0xf0f1f2bb load r2 0xf0f1f2bb
sb (r1+1), r2 sb (r1+1), r2
check_mem data 0xaabb0000 check_mem data 0xaabb0000
test_name SB_3 test_name SB_3
load r1 data
load r2 0xf0f1f2cc load r2 0xf0f1f2cc
sb (r1+-1), r2 sb (r1+-1), r2
check_mem data0 0x000000cc check_mem data0 0x000000cc

View File

@ -5,6 +5,10 @@ start
test_name SCALL_1 test_name SCALL_1
mvi r1, 1 mvi r1, 1
wcsr IE, r1 wcsr IE, r1
# we are running in a semi hosted environment
# therefore we have to set r8 to some unused system
# call
mvi r8, 0
insn: insn:
scall scall
check_excp 64 check_excp 64

View File

@ -9,11 +9,13 @@ sh (r1+0), r2
check_mem data 0xaaaa0000 check_mem data 0xaaaa0000
test_name SH_2 test_name SH_2
load r1 data
load r2 0xf0f1bbbb load r2 0xf0f1bbbb
sh (r1+2), r2 sh (r1+2), r2
check_mem data 0xaaaabbbb check_mem data 0xaaaabbbb
test_name SH_3 test_name SH_3
load r1 data
load r2 0xf0f1cccc load r2 0xf0f1cccc
sh (r1+-2), r2 sh (r1+-2), r2
check_mem data0 0x0000cccc check_mem data0 0x0000cccc

View File

@ -9,16 +9,19 @@ sw (r1+0), r2
check_mem data 0xaabbccdd check_mem data 0xaabbccdd
test_name SW_2 test_name SW_2
load r1 data
load r2 0x00112233 load r2 0x00112233
sw (r1+4), r2 sw (r1+4), r2
check_mem data1 0x00112233 check_mem data1 0x00112233
test_name SW_3 test_name SW_3
load r1 data
load r2 0x44556677 load r2 0x44556677
sw (r1+-4), r2 sw (r1+-4), r2
check_mem data0 0x44556677 check_mem data0 0x44556677
test_name SW_4 test_name SW_4
load r1 data
sw (r1+0), r1 sw (r1+0), r1
lw r3, (r1+0) lw r3, (r1+0)
check_r3 data check_r3 data

View File

@ -627,9 +627,6 @@ lm32_uart_memory_write(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
lm32_uart_memory_read(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x" lm32_uart_memory_read(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
lm32_uart_irq_state(int level) "irq state %d" lm32_uart_irq_state(int level) "irq state %d"
# hw/misc/lm32_sys.c
lm32_sys_memory_write(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
# hw/scsi/megasas.c # hw/scsi/megasas.c
megasas_init_firmware(uint64_t pa) "pa %" PRIx64 " " megasas_init_firmware(uint64_t pa) "pa %" PRIx64 " "
megasas_init_queue(uint64_t queue_pa, int queue_len, uint64_t head, uint64_t tail, uint32_t flags) "queue at %" PRIx64 " len %d head %" PRIx64 " tail %" PRIx64 " flags %x" megasas_init_queue(uint64_t queue_pa, int queue_len, uint64_t head, uint64_t tail, uint32_t flags) "queue at %" PRIx64 " len %d head %" PRIx64 " tail %" PRIx64 " flags %x"